1 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file provides ARM specific target descriptions.
11 //===----------------------------------------------------------------------===//
13 #include "ARMMCTargetDesc.h"
14 #include "ARMAddressingModes.h"
15 #include "ARMBaseInfo.h"
16 #include "ARMInstPrinter.h"
17 #include "ARMMCAsmInfo.h"
18 #include "TargetInfo/ARMTargetInfo.h"
19 #include "llvm/DebugInfo/CodeView/CodeView.h"
20 #include "llvm/MC/MCAsmBackend.h"
21 #include "llvm/MC/MCCodeEmitter.h"
22 #include "llvm/MC/MCELFStreamer.h"
23 #include "llvm/MC/MCInstrAnalysis.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCObjectWriter.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSubtargetInfo.h"
29 #include "llvm/MC/TargetRegistry.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/TargetParser/Triple.h"
35 #define GET_REGINFO_MC_DESC
36 #include "ARMGenRegisterInfo.inc"
38 static bool getMCRDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
40 if (STI
.hasFeature(llvm::ARM::HasV7Ops
) &&
41 (MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 15) &&
42 (MI
.getOperand(1).isImm() && MI
.getOperand(1).getImm() == 0) &&
43 // Checks for the deprecated CP15ISB encoding:
44 // mcr p15, #0, rX, c7, c5, #4
45 (MI
.getOperand(3).isImm() && MI
.getOperand(3).getImm() == 7)) {
46 if ((MI
.getOperand(5).isImm() && MI
.getOperand(5).getImm() == 4)) {
47 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 5) {
48 Info
= "deprecated since v7, use 'isb'";
52 // Checks for the deprecated CP15DSB encoding:
53 // mcr p15, #0, rX, c7, c10, #4
54 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 10) {
55 Info
= "deprecated since v7, use 'dsb'";
59 // Checks for the deprecated CP15DMB encoding:
60 // mcr p15, #0, rX, c7, c10, #5
61 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 10 &&
62 (MI
.getOperand(5).isImm() && MI
.getOperand(5).getImm() == 5)) {
63 Info
= "deprecated since v7, use 'dmb'";
67 if (STI
.hasFeature(llvm::ARM::HasV7Ops
) &&
68 ((MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 10) ||
69 (MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 11))) {
70 Info
= "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
77 static bool getMRCDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
79 if (STI
.hasFeature(llvm::ARM::HasV7Ops
) &&
80 ((MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 10) ||
81 (MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 11))) {
82 Info
= "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
89 static bool getARMStoreDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
91 assert(!STI
.hasFeature(llvm::ARM::ModeThumb
) &&
92 "cannot predicate thumb instructions");
94 assert(MI
.getNumOperands() >= 4 && "expected >= 4 arguments");
95 for (unsigned OI
= 4, OE
= MI
.getNumOperands(); OI
< OE
; ++OI
) {
96 assert(MI
.getOperand(OI
).isReg() && "expected register");
97 if (MI
.getOperand(OI
).getReg() == ARM::PC
) {
98 Info
= "use of PC in the list is deprecated";
105 static bool getARMLoadDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
107 assert(!STI
.hasFeature(llvm::ARM::ModeThumb
) &&
108 "cannot predicate thumb instructions");
110 assert(MI
.getNumOperands() >= 4 && "expected >= 4 arguments");
111 bool ListContainsPC
= false, ListContainsLR
= false;
112 for (unsigned OI
= 4, OE
= MI
.getNumOperands(); OI
< OE
; ++OI
) {
113 assert(MI
.getOperand(OI
).isReg() && "expected register");
114 switch (MI
.getOperand(OI
).getReg().id()) {
118 ListContainsLR
= true;
121 ListContainsPC
= true;
126 if (ListContainsPC
&& ListContainsLR
) {
127 Info
= "use of LR and PC simultaneously in the list is deprecated";
134 #define GET_INSTRINFO_MC_DESC
135 #define ENABLE_INSTR_PREDICATE_VERIFIER
136 #include "ARMGenInstrInfo.inc"
138 #define GET_SUBTARGETINFO_MC_DESC
139 #include "ARMGenSubtargetInfo.inc"
141 std::string
ARM_MC::ParseARMTriple(const Triple
&TT
, StringRef CPU
) {
142 std::string ARMArchFeature
;
144 ARM::ArchKind ArchID
= ARM::parseArch(TT
.getArchName());
145 if (ArchID
!= ARM::ArchKind::INVALID
&& (CPU
.empty() || CPU
== "generic"))
146 ARMArchFeature
= (ARMArchFeature
+ "+" + ARM::getArchName(ArchID
)).str();
149 if (!ARMArchFeature
.empty())
150 ARMArchFeature
+= ",";
151 ARMArchFeature
+= "+thumb-mode,+v4t";
155 if (!ARMArchFeature
.empty())
156 ARMArchFeature
+= ",";
157 ARMArchFeature
+= "+nacl-trap";
160 if (TT
.isOSWindows()) {
161 if (!ARMArchFeature
.empty())
162 ARMArchFeature
+= ",";
163 ARMArchFeature
+= "+noarm";
166 return ARMArchFeature
;
169 bool ARM_MC::isPredicated(const MCInst
&MI
, const MCInstrInfo
*MCII
) {
170 const MCInstrDesc
&Desc
= MCII
->get(MI
.getOpcode());
171 int PredOpIdx
= Desc
.findFirstPredOperandIdx();
172 return PredOpIdx
!= -1 && MI
.getOperand(PredOpIdx
).getImm() != ARMCC::AL
;
175 bool ARM_MC::isCPSRDefined(const MCInst
&MI
, const MCInstrInfo
*MCII
) {
176 const MCInstrDesc
&Desc
= MCII
->get(MI
.getOpcode());
177 for (unsigned I
= 0; I
< MI
.getNumOperands(); ++I
) {
178 const MCOperand
&MO
= MI
.getOperand(I
);
179 if (MO
.isReg() && MO
.getReg() == ARM::CPSR
&&
180 Desc
.operands()[I
].isOptionalDef())
186 uint64_t ARM_MC::evaluateBranchTarget(const MCInstrDesc
&InstDesc
,
187 uint64_t Addr
, int64_t Imm
) {
188 // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
191 ((InstDesc
.TSFlags
& ARMII::FormMask
) == ARMII::ThumbFrm
) ? 4 : 8;
193 // A Thumb instruction BLX(i) can be 16-bit aligned while targets Arm code
194 // which is 32-bit aligned. The target address for the case is calculated as
195 // targetAddress = Align(PC,4) + imm32;
197 // Align(x, y) = y * (x DIV y);
198 if (InstDesc
.getOpcode() == ARM::tBLXi
)
201 return Addr
+ Imm
+ Offset
;
204 MCSubtargetInfo
*ARM_MC::createARMMCSubtargetInfo(const Triple
&TT
,
205 StringRef CPU
, StringRef FS
) {
206 std::string ArchFS
= ARM_MC::ParseARMTriple(TT
, CPU
);
209 ArchFS
= (Twine(ArchFS
) + "," + FS
).str();
211 ArchFS
= std::string(FS
);
214 return createARMMCSubtargetInfoImpl(TT
, CPU
, /*TuneCPU*/ CPU
, ArchFS
);
217 static MCInstrInfo
*createARMMCInstrInfo() {
218 MCInstrInfo
*X
= new MCInstrInfo();
219 InitARMMCInstrInfo(X
);
223 void ARM_MC::initLLVMToCVRegMapping(MCRegisterInfo
*MRI
) {
224 // Mapping from CodeView to MC register id.
225 static const struct {
226 codeview::RegisterId CVReg
;
229 {codeview::RegisterId::ARM_R0
, ARM::R0
},
230 {codeview::RegisterId::ARM_R1
, ARM::R1
},
231 {codeview::RegisterId::ARM_R2
, ARM::R2
},
232 {codeview::RegisterId::ARM_R3
, ARM::R3
},
233 {codeview::RegisterId::ARM_R4
, ARM::R4
},
234 {codeview::RegisterId::ARM_R5
, ARM::R5
},
235 {codeview::RegisterId::ARM_R6
, ARM::R6
},
236 {codeview::RegisterId::ARM_R7
, ARM::R7
},
237 {codeview::RegisterId::ARM_R8
, ARM::R8
},
238 {codeview::RegisterId::ARM_R9
, ARM::R9
},
239 {codeview::RegisterId::ARM_R10
, ARM::R10
},
240 {codeview::RegisterId::ARM_R11
, ARM::R11
},
241 {codeview::RegisterId::ARM_R12
, ARM::R12
},
242 {codeview::RegisterId::ARM_SP
, ARM::SP
},
243 {codeview::RegisterId::ARM_LR
, ARM::LR
},
244 {codeview::RegisterId::ARM_PC
, ARM::PC
},
245 {codeview::RegisterId::ARM_CPSR
, ARM::CPSR
},
246 {codeview::RegisterId::ARM_FPSCR
, ARM::FPSCR
},
247 {codeview::RegisterId::ARM_FPEXC
, ARM::FPEXC
},
248 {codeview::RegisterId::ARM_FS0
, ARM::S0
},
249 {codeview::RegisterId::ARM_FS1
, ARM::S1
},
250 {codeview::RegisterId::ARM_FS2
, ARM::S2
},
251 {codeview::RegisterId::ARM_FS3
, ARM::S3
},
252 {codeview::RegisterId::ARM_FS4
, ARM::S4
},
253 {codeview::RegisterId::ARM_FS5
, ARM::S5
},
254 {codeview::RegisterId::ARM_FS6
, ARM::S6
},
255 {codeview::RegisterId::ARM_FS7
, ARM::S7
},
256 {codeview::RegisterId::ARM_FS8
, ARM::S8
},
257 {codeview::RegisterId::ARM_FS9
, ARM::S9
},
258 {codeview::RegisterId::ARM_FS10
, ARM::S10
},
259 {codeview::RegisterId::ARM_FS11
, ARM::S11
},
260 {codeview::RegisterId::ARM_FS12
, ARM::S12
},
261 {codeview::RegisterId::ARM_FS13
, ARM::S13
},
262 {codeview::RegisterId::ARM_FS14
, ARM::S14
},
263 {codeview::RegisterId::ARM_FS15
, ARM::S15
},
264 {codeview::RegisterId::ARM_FS16
, ARM::S16
},
265 {codeview::RegisterId::ARM_FS17
, ARM::S17
},
266 {codeview::RegisterId::ARM_FS18
, ARM::S18
},
267 {codeview::RegisterId::ARM_FS19
, ARM::S19
},
268 {codeview::RegisterId::ARM_FS20
, ARM::S20
},
269 {codeview::RegisterId::ARM_FS21
, ARM::S21
},
270 {codeview::RegisterId::ARM_FS22
, ARM::S22
},
271 {codeview::RegisterId::ARM_FS23
, ARM::S23
},
272 {codeview::RegisterId::ARM_FS24
, ARM::S24
},
273 {codeview::RegisterId::ARM_FS25
, ARM::S25
},
274 {codeview::RegisterId::ARM_FS26
, ARM::S26
},
275 {codeview::RegisterId::ARM_FS27
, ARM::S27
},
276 {codeview::RegisterId::ARM_FS28
, ARM::S28
},
277 {codeview::RegisterId::ARM_FS29
, ARM::S29
},
278 {codeview::RegisterId::ARM_FS30
, ARM::S30
},
279 {codeview::RegisterId::ARM_FS31
, ARM::S31
},
280 {codeview::RegisterId::ARM_ND0
, ARM::D0
},
281 {codeview::RegisterId::ARM_ND1
, ARM::D1
},
282 {codeview::RegisterId::ARM_ND2
, ARM::D2
},
283 {codeview::RegisterId::ARM_ND3
, ARM::D3
},
284 {codeview::RegisterId::ARM_ND4
, ARM::D4
},
285 {codeview::RegisterId::ARM_ND5
, ARM::D5
},
286 {codeview::RegisterId::ARM_ND6
, ARM::D6
},
287 {codeview::RegisterId::ARM_ND7
, ARM::D7
},
288 {codeview::RegisterId::ARM_ND8
, ARM::D8
},
289 {codeview::RegisterId::ARM_ND9
, ARM::D9
},
290 {codeview::RegisterId::ARM_ND10
, ARM::D10
},
291 {codeview::RegisterId::ARM_ND11
, ARM::D11
},
292 {codeview::RegisterId::ARM_ND12
, ARM::D12
},
293 {codeview::RegisterId::ARM_ND13
, ARM::D13
},
294 {codeview::RegisterId::ARM_ND14
, ARM::D14
},
295 {codeview::RegisterId::ARM_ND15
, ARM::D15
},
296 {codeview::RegisterId::ARM_ND16
, ARM::D16
},
297 {codeview::RegisterId::ARM_ND17
, ARM::D17
},
298 {codeview::RegisterId::ARM_ND18
, ARM::D18
},
299 {codeview::RegisterId::ARM_ND19
, ARM::D19
},
300 {codeview::RegisterId::ARM_ND20
, ARM::D20
},
301 {codeview::RegisterId::ARM_ND21
, ARM::D21
},
302 {codeview::RegisterId::ARM_ND22
, ARM::D22
},
303 {codeview::RegisterId::ARM_ND23
, ARM::D23
},
304 {codeview::RegisterId::ARM_ND24
, ARM::D24
},
305 {codeview::RegisterId::ARM_ND25
, ARM::D25
},
306 {codeview::RegisterId::ARM_ND26
, ARM::D26
},
307 {codeview::RegisterId::ARM_ND27
, ARM::D27
},
308 {codeview::RegisterId::ARM_ND28
, ARM::D28
},
309 {codeview::RegisterId::ARM_ND29
, ARM::D29
},
310 {codeview::RegisterId::ARM_ND30
, ARM::D30
},
311 {codeview::RegisterId::ARM_ND31
, ARM::D31
},
312 {codeview::RegisterId::ARM_NQ0
, ARM::Q0
},
313 {codeview::RegisterId::ARM_NQ1
, ARM::Q1
},
314 {codeview::RegisterId::ARM_NQ2
, ARM::Q2
},
315 {codeview::RegisterId::ARM_NQ3
, ARM::Q3
},
316 {codeview::RegisterId::ARM_NQ4
, ARM::Q4
},
317 {codeview::RegisterId::ARM_NQ5
, ARM::Q5
},
318 {codeview::RegisterId::ARM_NQ6
, ARM::Q6
},
319 {codeview::RegisterId::ARM_NQ7
, ARM::Q7
},
320 {codeview::RegisterId::ARM_NQ8
, ARM::Q8
},
321 {codeview::RegisterId::ARM_NQ9
, ARM::Q9
},
322 {codeview::RegisterId::ARM_NQ10
, ARM::Q10
},
323 {codeview::RegisterId::ARM_NQ11
, ARM::Q11
},
324 {codeview::RegisterId::ARM_NQ12
, ARM::Q12
},
325 {codeview::RegisterId::ARM_NQ13
, ARM::Q13
},
326 {codeview::RegisterId::ARM_NQ14
, ARM::Q14
},
327 {codeview::RegisterId::ARM_NQ15
, ARM::Q15
},
329 for (const auto &I
: RegMap
)
330 MRI
->mapLLVMRegToCVReg(I
.Reg
, static_cast<int>(I
.CVReg
));
333 static MCRegisterInfo
*createARMMCRegisterInfo(const Triple
&Triple
) {
334 MCRegisterInfo
*X
= new MCRegisterInfo();
335 InitARMMCRegisterInfo(X
, ARM::LR
, 0, 0, ARM::PC
);
336 ARM_MC::initLLVMToCVRegMapping(X
);
340 static MCAsmInfo
*createARMMCAsmInfo(const MCRegisterInfo
&MRI
,
341 const Triple
&TheTriple
,
342 const MCTargetOptions
&Options
) {
344 if (TheTriple
.isOSDarwin() || TheTriple
.isOSBinFormatMachO())
345 MAI
= new ARMMCAsmInfoDarwin(TheTriple
);
346 else if (TheTriple
.isWindowsMSVCEnvironment())
347 MAI
= new ARMCOFFMCAsmInfoMicrosoft();
348 else if (TheTriple
.isOSWindows())
349 MAI
= new ARMCOFFMCAsmInfoGNU();
351 MAI
= new ARMELFMCAsmInfo(TheTriple
);
353 unsigned Reg
= MRI
.getDwarfRegNum(ARM::SP
, true);
354 MAI
->addInitialFrameState(MCCFIInstruction::cfiDefCfa(nullptr, Reg
, 0));
359 static MCStreamer
*createELFStreamer(const Triple
&T
, MCContext
&Ctx
,
360 std::unique_ptr
<MCAsmBackend
> &&MAB
,
361 std::unique_ptr
<MCObjectWriter
> &&OW
,
362 std::unique_ptr
<MCCodeEmitter
> &&Emitter
) {
363 return createARMELFStreamer(
364 Ctx
, std::move(MAB
), std::move(OW
), std::move(Emitter
),
365 (T
.getArch() == Triple::thumb
|| T
.getArch() == Triple::thumbeb
),
370 createARMMachOStreamer(MCContext
&Ctx
, std::unique_ptr
<MCAsmBackend
> &&MAB
,
371 std::unique_ptr
<MCObjectWriter
> &&OW
,
372 std::unique_ptr
<MCCodeEmitter
> &&Emitter
) {
373 return createMachOStreamer(Ctx
, std::move(MAB
), std::move(OW
),
374 std::move(Emitter
), false);
377 static MCInstPrinter
*createARMMCInstPrinter(const Triple
&T
,
378 unsigned SyntaxVariant
,
379 const MCAsmInfo
&MAI
,
380 const MCInstrInfo
&MII
,
381 const MCRegisterInfo
&MRI
) {
382 if (SyntaxVariant
== 0)
383 return new ARMInstPrinter(MAI
, MII
, MRI
);
387 static MCRelocationInfo
*createARMMCRelocationInfo(const Triple
&TT
,
389 if (TT
.isOSBinFormatMachO())
390 return createARMMachORelocationInfo(Ctx
);
391 // Default to the stock relocation info.
392 return llvm::createMCRelocationInfo(TT
, Ctx
);
397 class ARMMCInstrAnalysis
: public MCInstrAnalysis
{
399 ARMMCInstrAnalysis(const MCInstrInfo
*Info
) : MCInstrAnalysis(Info
) {}
401 bool isUnconditionalBranch(const MCInst
&Inst
) const override
{
402 // BCCs with the "always" predicate are unconditional branches.
403 if (Inst
.getOpcode() == ARM::Bcc
&& Inst
.getOperand(1).getImm()==ARMCC::AL
)
405 return MCInstrAnalysis::isUnconditionalBranch(Inst
);
408 bool isConditionalBranch(const MCInst
&Inst
) const override
{
409 // BCCs with the "always" predicate are unconditional branches.
410 if (Inst
.getOpcode() == ARM::Bcc
&& Inst
.getOperand(1).getImm()==ARMCC::AL
)
412 return MCInstrAnalysis::isConditionalBranch(Inst
);
415 bool evaluateBranch(const MCInst
&Inst
, uint64_t Addr
, uint64_t Size
,
416 uint64_t &Target
) const override
{
417 const MCInstrDesc
&Desc
= Info
->get(Inst
.getOpcode());
419 // Find the PC-relative immediate operand in the instruction.
420 for (unsigned OpNum
= 0; OpNum
< Desc
.getNumOperands(); ++OpNum
) {
421 if (Inst
.getOperand(OpNum
).isImm() &&
422 Desc
.operands()[OpNum
].OperandType
== MCOI::OPERAND_PCREL
) {
423 int64_t Imm
= Inst
.getOperand(OpNum
).getImm();
424 Target
= ARM_MC::evaluateBranchTarget(Desc
, Addr
, Imm
);
431 std::optional
<uint64_t>
432 evaluateMemoryOperandAddress(const MCInst
&Inst
, const MCSubtargetInfo
*STI
,
433 uint64_t Addr
, uint64_t Size
) const override
;
438 static std::optional
<uint64_t>
439 // NOLINTNEXTLINE(readability-identifier-naming)
440 evaluateMemOpAddrForAddrMode_i12(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
441 unsigned MemOpIndex
, uint64_t Addr
) {
442 if (MemOpIndex
+ 1 >= Desc
.getNumOperands())
445 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
446 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
447 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| !MO2
.isImm())
450 int32_t OffImm
= (int32_t)MO2
.getImm();
451 // Special value for #-0. All others are normal.
452 if (OffImm
== INT32_MIN
)
454 return Addr
+ OffImm
;
457 static std::optional
<uint64_t>
458 evaluateMemOpAddrForAddrMode3(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
459 unsigned MemOpIndex
, uint64_t Addr
) {
460 if (MemOpIndex
+ 2 >= Desc
.getNumOperands())
463 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
464 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
465 const MCOperand
&MO3
= Inst
.getOperand(MemOpIndex
+ 2);
466 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| MO2
.getReg() || !MO3
.isImm())
469 unsigned ImmOffs
= ARM_AM::getAM3Offset(MO3
.getImm());
470 ARM_AM::AddrOpc Op
= ARM_AM::getAM3Op(MO3
.getImm());
472 if (Op
== ARM_AM::sub
)
473 return Addr
- ImmOffs
;
474 return Addr
+ ImmOffs
;
477 static std::optional
<uint64_t>
478 evaluateMemOpAddrForAddrMode5(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
479 unsigned MemOpIndex
, uint64_t Addr
) {
480 if (MemOpIndex
+ 1 >= Desc
.getNumOperands())
483 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
484 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
485 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| !MO2
.isImm())
488 unsigned ImmOffs
= ARM_AM::getAM5Offset(MO2
.getImm());
489 ARM_AM::AddrOpc Op
= ARM_AM::getAM5Op(MO2
.getImm());
491 if (Op
== ARM_AM::sub
)
492 return Addr
- ImmOffs
* 4;
493 return Addr
+ ImmOffs
* 4;
496 static std::optional
<uint64_t>
497 evaluateMemOpAddrForAddrMode5FP16(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
498 unsigned MemOpIndex
, uint64_t Addr
) {
499 if (MemOpIndex
+ 1 >= Desc
.getNumOperands())
502 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
503 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
504 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| !MO2
.isImm())
507 unsigned ImmOffs
= ARM_AM::getAM5FP16Offset(MO2
.getImm());
508 ARM_AM::AddrOpc Op
= ARM_AM::getAM5FP16Op(MO2
.getImm());
510 if (Op
== ARM_AM::sub
)
511 return Addr
- ImmOffs
* 2;
512 return Addr
+ ImmOffs
* 2;
515 static std::optional
<uint64_t>
516 // NOLINTNEXTLINE(readability-identifier-naming)
517 evaluateMemOpAddrForAddrModeT2_i8s4(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
518 unsigned MemOpIndex
, uint64_t Addr
) {
519 if (MemOpIndex
+ 1 >= Desc
.getNumOperands())
522 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
523 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
524 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| !MO2
.isImm())
527 int32_t OffImm
= (int32_t)MO2
.getImm();
528 assert(((OffImm
& 0x3) == 0) && "Not a valid immediate!");
530 // Special value for #-0. All others are normal.
531 if (OffImm
== INT32_MIN
)
533 return Addr
+ OffImm
;
536 static std::optional
<uint64_t>
537 // NOLINTNEXTLINE(readability-identifier-naming)
538 evaluateMemOpAddrForAddrModeT2_pc(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
539 unsigned MemOpIndex
, uint64_t Addr
) {
540 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
544 int32_t OffImm
= (int32_t)MO1
.getImm();
546 // Special value for #-0. All others are normal.
547 if (OffImm
== INT32_MIN
)
549 return Addr
+ OffImm
;
552 static std::optional
<uint64_t>
553 // NOLINTNEXTLINE(readability-identifier-naming)
554 evaluateMemOpAddrForAddrModeT1_s(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
555 unsigned MemOpIndex
, uint64_t Addr
) {
556 return evaluateMemOpAddrForAddrModeT2_pc(Inst
, Desc
, MemOpIndex
, Addr
);
559 std::optional
<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
560 const MCInst
&Inst
, const MCSubtargetInfo
*STI
, uint64_t Addr
,
561 uint64_t Size
) const {
562 const MCInstrDesc
&Desc
= Info
->get(Inst
.getOpcode());
564 // Only load instructions can have PC-relative memory addressing.
568 // PC-relative addressing does not update the base register.
569 uint64_t TSFlags
= Desc
.TSFlags
;
571 (TSFlags
& ARMII::IndexModeMask
) >> ARMII::IndexModeShift
;
572 if (IndexMode
!= ARMII::IndexModeNone
)
575 // Find the memory addressing operand in the instruction.
576 unsigned OpIndex
= Desc
.NumDefs
;
577 while (OpIndex
< Desc
.getNumOperands() &&
578 Desc
.operands()[OpIndex
].OperandType
!= MCOI::OPERAND_MEMORY
)
580 if (OpIndex
== Desc
.getNumOperands())
583 // Base address for PC-relative addressing is always 32-bit aligned.
586 // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
588 switch (Desc
.TSFlags
& ARMII::FormMask
) {
592 case ARMII::ThumbFrm
:
595 // VLDR* instructions share the same opcode (and thus the same form) for Arm
596 // and Thumb. Use a bit longer route through STI in that case.
597 case ARMII::VFPLdStFrm
:
598 Addr
+= STI
->hasFeature(ARM::ModeThumb
) ? 4 : 8;
602 // Eveluate the address depending on the addressing mode
603 unsigned AddrMode
= (TSFlags
& ARMII::AddrModeMask
);
607 case ARMII::AddrMode_i12
:
608 return evaluateMemOpAddrForAddrMode_i12(Inst
, Desc
, OpIndex
, Addr
);
609 case ARMII::AddrMode3
:
610 return evaluateMemOpAddrForAddrMode3(Inst
, Desc
, OpIndex
, Addr
);
611 case ARMII::AddrMode5
:
612 return evaluateMemOpAddrForAddrMode5(Inst
, Desc
, OpIndex
, Addr
);
613 case ARMII::AddrMode5FP16
:
614 return evaluateMemOpAddrForAddrMode5FP16(Inst
, Desc
, OpIndex
, Addr
);
615 case ARMII::AddrModeT2_i8s4
:
616 return evaluateMemOpAddrForAddrModeT2_i8s4(Inst
, Desc
, OpIndex
, Addr
);
617 case ARMII::AddrModeT2_pc
:
618 return evaluateMemOpAddrForAddrModeT2_pc(Inst
, Desc
, OpIndex
, Addr
);
619 case ARMII::AddrModeT1_s
:
620 return evaluateMemOpAddrForAddrModeT1_s(Inst
, Desc
, OpIndex
, Addr
);
624 static MCInstrAnalysis
*createARMMCInstrAnalysis(const MCInstrInfo
*Info
) {
625 return new ARMMCInstrAnalysis(Info
);
628 bool ARM::isCDECoproc(size_t Coproc
, const MCSubtargetInfo
&STI
) {
629 // Unfortunately we don't have ARMTargetInfo in the disassembler, so we have
630 // to rely on feature bits.
633 return STI
.getFeatureBits()[ARM::FeatureCoprocCDE0
+ Coproc
];
636 // Force static initialization.
637 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeARMTargetMC() {
638 for (Target
*T
: {&getTheARMLETarget(), &getTheARMBETarget(),
639 &getTheThumbLETarget(), &getTheThumbBETarget()}) {
640 // Register the MC asm info.
641 RegisterMCAsmInfoFn
X(*T
, createARMMCAsmInfo
);
643 // Register the MC instruction info.
644 TargetRegistry::RegisterMCInstrInfo(*T
, createARMMCInstrInfo
);
646 // Register the MC register info.
647 TargetRegistry::RegisterMCRegInfo(*T
, createARMMCRegisterInfo
);
649 // Register the MC subtarget info.
650 TargetRegistry::RegisterMCSubtargetInfo(*T
,
651 ARM_MC::createARMMCSubtargetInfo
);
653 TargetRegistry::RegisterELFStreamer(*T
, createELFStreamer
);
654 TargetRegistry::RegisterCOFFStreamer(*T
, createARMWinCOFFStreamer
);
655 TargetRegistry::RegisterMachOStreamer(*T
, createARMMachOStreamer
);
657 // Register the obj target streamer.
658 TargetRegistry::RegisterObjectTargetStreamer(*T
,
659 createARMObjectTargetStreamer
);
661 // Register the asm streamer.
662 TargetRegistry::RegisterAsmTargetStreamer(*T
, createARMTargetAsmStreamer
);
664 // Register the null TargetStreamer.
665 TargetRegistry::RegisterNullTargetStreamer(*T
, createARMNullTargetStreamer
);
667 // Register the MCInstPrinter.
668 TargetRegistry::RegisterMCInstPrinter(*T
, createARMMCInstPrinter
);
670 // Register the MC relocation info.
671 TargetRegistry::RegisterMCRelocationInfo(*T
, createARMMCRelocationInfo
);
674 // Register the MC instruction analyzer.
675 for (Target
*T
: {&getTheARMLETarget(), &getTheARMBETarget(),
676 &getTheThumbLETarget(), &getTheThumbBETarget()})
677 TargetRegistry::RegisterMCInstrAnalysis(*T
, createARMMCInstrAnalysis
);
679 for (Target
*T
: {&getTheARMLETarget(), &getTheThumbLETarget()}) {
680 TargetRegistry::RegisterMCCodeEmitter(*T
, createARMLEMCCodeEmitter
);
681 TargetRegistry::RegisterMCAsmBackend(*T
, createARMLEAsmBackend
);
683 for (Target
*T
: {&getTheARMBETarget(), &getTheThumbBETarget()}) {
684 TargetRegistry::RegisterMCCodeEmitter(*T
, createARMBEMCCodeEmitter
);
685 TargetRegistry::RegisterMCAsmBackend(*T
, createARMBEAsmBackend
);