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/ADT/Triple.h"
20 #include "llvm/DebugInfo/CodeView/CodeView.h"
21 #include "llvm/MC/MCAsmBackend.h"
22 #include "llvm/MC/MCCodeEmitter.h"
23 #include "llvm/MC/MCELFStreamer.h"
24 #include "llvm/MC/MCInstrAnalysis.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCObjectWriter.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSubtargetInfo.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/TargetParser.h"
32 #include "llvm/Support/TargetRegistry.h"
36 #define GET_REGINFO_MC_DESC
37 #include "ARMGenRegisterInfo.inc"
39 static bool getMCRDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
41 if (STI
.getFeatureBits()[llvm::ARM::HasV7Ops
] &&
42 (MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 15) &&
43 (MI
.getOperand(1).isImm() && MI
.getOperand(1).getImm() == 0) &&
44 // Checks for the deprecated CP15ISB encoding:
45 // mcr p15, #0, rX, c7, c5, #4
46 (MI
.getOperand(3).isImm() && MI
.getOperand(3).getImm() == 7)) {
47 if ((MI
.getOperand(5).isImm() && MI
.getOperand(5).getImm() == 4)) {
48 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 5) {
49 Info
= "deprecated since v7, use 'isb'";
53 // Checks for the deprecated CP15DSB encoding:
54 // mcr p15, #0, rX, c7, c10, #4
55 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 10) {
56 Info
= "deprecated since v7, use 'dsb'";
60 // Checks for the deprecated CP15DMB encoding:
61 // mcr p15, #0, rX, c7, c10, #5
62 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 10 &&
63 (MI
.getOperand(5).isImm() && MI
.getOperand(5).getImm() == 5)) {
64 Info
= "deprecated since v7, use 'dmb'";
68 if (STI
.getFeatureBits()[llvm::ARM::HasV7Ops
] &&
69 ((MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 10) ||
70 (MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 11))) {
71 Info
= "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
78 static bool getMRCDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
80 if (STI
.getFeatureBits()[llvm::ARM::HasV7Ops
] &&
81 ((MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 10) ||
82 (MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 11))) {
83 Info
= "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
90 static bool getITDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
92 if (STI
.getFeatureBits()[llvm::ARM::HasV8Ops
] && MI
.getOperand(1).isImm() &&
93 MI
.getOperand(1).getImm() != 8) {
94 Info
= "applying IT instruction to more than one subsequent instruction is "
102 static bool getARMStoreDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
104 assert(!STI
.getFeatureBits()[llvm::ARM::ModeThumb
] &&
105 "cannot predicate thumb instructions");
107 assert(MI
.getNumOperands() >= 4 && "expected >= 4 arguments");
108 for (unsigned OI
= 4, OE
= MI
.getNumOperands(); OI
< OE
; ++OI
) {
109 assert(MI
.getOperand(OI
).isReg() && "expected register");
110 if (MI
.getOperand(OI
).getReg() == ARM::PC
) {
111 Info
= "use of PC in the list is deprecated";
118 static bool getARMLoadDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
120 assert(!STI
.getFeatureBits()[llvm::ARM::ModeThumb
] &&
121 "cannot predicate thumb instructions");
123 assert(MI
.getNumOperands() >= 4 && "expected >= 4 arguments");
124 bool ListContainsPC
= false, ListContainsLR
= false;
125 for (unsigned OI
= 4, OE
= MI
.getNumOperands(); OI
< OE
; ++OI
) {
126 assert(MI
.getOperand(OI
).isReg() && "expected register");
127 switch (MI
.getOperand(OI
).getReg()) {
131 ListContainsLR
= true;
134 ListContainsPC
= true;
139 if (ListContainsPC
&& ListContainsLR
) {
140 Info
= "use of LR and PC simultaneously in the list is deprecated";
147 #define GET_INSTRINFO_MC_DESC
148 #include "ARMGenInstrInfo.inc"
150 #define GET_SUBTARGETINFO_MC_DESC
151 #include "ARMGenSubtargetInfo.inc"
153 std::string
ARM_MC::ParseARMTriple(const Triple
&TT
, StringRef CPU
) {
154 std::string ARMArchFeature
;
156 ARM::ArchKind ArchID
= ARM::parseArch(TT
.getArchName());
157 if (ArchID
!= ARM::ArchKind::INVALID
&& (CPU
.empty() || CPU
== "generic"))
158 ARMArchFeature
= (ARMArchFeature
+ "+" + ARM::getArchName(ArchID
)).str();
161 if (!ARMArchFeature
.empty())
162 ARMArchFeature
+= ",";
163 ARMArchFeature
+= "+thumb-mode,+v4t";
167 if (!ARMArchFeature
.empty())
168 ARMArchFeature
+= ",";
169 ARMArchFeature
+= "+nacl-trap";
172 if (TT
.isOSWindows()) {
173 if (!ARMArchFeature
.empty())
174 ARMArchFeature
+= ",";
175 ARMArchFeature
+= "+noarm";
178 return ARMArchFeature
;
181 bool ARM_MC::isPredicated(const MCInst
&MI
, const MCInstrInfo
*MCII
) {
182 const MCInstrDesc
&Desc
= MCII
->get(MI
.getOpcode());
183 int PredOpIdx
= Desc
.findFirstPredOperandIdx();
184 return PredOpIdx
!= -1 && MI
.getOperand(PredOpIdx
).getImm() != ARMCC::AL
;
187 bool ARM_MC::isCPSRDefined(const MCInst
&MI
, const MCInstrInfo
*MCII
) {
188 const MCInstrDesc
&Desc
= MCII
->get(MI
.getOpcode());
189 for (unsigned I
= 0; I
< MI
.getNumOperands(); ++I
) {
190 const MCOperand
&MO
= MI
.getOperand(I
);
191 if (MO
.isReg() && MO
.getReg() == ARM::CPSR
&&
192 Desc
.OpInfo
[I
].isOptionalDef())
198 uint64_t ARM_MC::evaluateBranchTarget(const MCInstrDesc
&InstDesc
,
199 uint64_t Addr
, int64_t Imm
) {
200 // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
203 ((InstDesc
.TSFlags
& ARMII::FormMask
) == ARMII::ThumbFrm
) ? 4 : 8;
205 // A Thumb instruction BLX(i) can be 16-bit aligned while targets Arm code
206 // which is 32-bit aligned. The target address for the case is calculated as
207 // targetAddress = Align(PC,4) + imm32;
209 // Align(x, y) = y * (x DIV y);
210 if (InstDesc
.getOpcode() == ARM::tBLXi
)
213 return Addr
+ Imm
+ Offset
;
216 MCSubtargetInfo
*ARM_MC::createARMMCSubtargetInfo(const Triple
&TT
,
217 StringRef CPU
, StringRef FS
) {
218 std::string ArchFS
= ARM_MC::ParseARMTriple(TT
, CPU
);
221 ArchFS
= (Twine(ArchFS
) + "," + FS
).str();
223 ArchFS
= std::string(FS
);
226 return createARMMCSubtargetInfoImpl(TT
, CPU
, /*TuneCPU*/ CPU
, ArchFS
);
229 static MCInstrInfo
*createARMMCInstrInfo() {
230 MCInstrInfo
*X
= new MCInstrInfo();
231 InitARMMCInstrInfo(X
);
235 void ARM_MC::initLLVMToCVRegMapping(MCRegisterInfo
*MRI
) {
236 // Mapping from CodeView to MC register id.
237 static const struct {
238 codeview::RegisterId CVReg
;
241 {codeview::RegisterId::ARM_R0
, ARM::R0
},
242 {codeview::RegisterId::ARM_R1
, ARM::R1
},
243 {codeview::RegisterId::ARM_R2
, ARM::R2
},
244 {codeview::RegisterId::ARM_R3
, ARM::R3
},
245 {codeview::RegisterId::ARM_R4
, ARM::R4
},
246 {codeview::RegisterId::ARM_R5
, ARM::R5
},
247 {codeview::RegisterId::ARM_R6
, ARM::R6
},
248 {codeview::RegisterId::ARM_R7
, ARM::R7
},
249 {codeview::RegisterId::ARM_R8
, ARM::R8
},
250 {codeview::RegisterId::ARM_R9
, ARM::R9
},
251 {codeview::RegisterId::ARM_R10
, ARM::R10
},
252 {codeview::RegisterId::ARM_R11
, ARM::R11
},
253 {codeview::RegisterId::ARM_R12
, ARM::R12
},
254 {codeview::RegisterId::ARM_SP
, ARM::SP
},
255 {codeview::RegisterId::ARM_LR
, ARM::LR
},
256 {codeview::RegisterId::ARM_PC
, ARM::PC
},
257 {codeview::RegisterId::ARM_CPSR
, ARM::CPSR
},
258 {codeview::RegisterId::ARM_FPSCR
, ARM::FPSCR
},
259 {codeview::RegisterId::ARM_FPEXC
, ARM::FPEXC
},
260 {codeview::RegisterId::ARM_FS0
, ARM::S0
},
261 {codeview::RegisterId::ARM_FS1
, ARM::S1
},
262 {codeview::RegisterId::ARM_FS2
, ARM::S2
},
263 {codeview::RegisterId::ARM_FS3
, ARM::S3
},
264 {codeview::RegisterId::ARM_FS4
, ARM::S4
},
265 {codeview::RegisterId::ARM_FS5
, ARM::S5
},
266 {codeview::RegisterId::ARM_FS6
, ARM::S6
},
267 {codeview::RegisterId::ARM_FS7
, ARM::S7
},
268 {codeview::RegisterId::ARM_FS8
, ARM::S8
},
269 {codeview::RegisterId::ARM_FS9
, ARM::S9
},
270 {codeview::RegisterId::ARM_FS10
, ARM::S10
},
271 {codeview::RegisterId::ARM_FS11
, ARM::S11
},
272 {codeview::RegisterId::ARM_FS12
, ARM::S12
},
273 {codeview::RegisterId::ARM_FS13
, ARM::S13
},
274 {codeview::RegisterId::ARM_FS14
, ARM::S14
},
275 {codeview::RegisterId::ARM_FS15
, ARM::S15
},
276 {codeview::RegisterId::ARM_FS16
, ARM::S16
},
277 {codeview::RegisterId::ARM_FS17
, ARM::S17
},
278 {codeview::RegisterId::ARM_FS18
, ARM::S18
},
279 {codeview::RegisterId::ARM_FS19
, ARM::S19
},
280 {codeview::RegisterId::ARM_FS20
, ARM::S20
},
281 {codeview::RegisterId::ARM_FS21
, ARM::S21
},
282 {codeview::RegisterId::ARM_FS22
, ARM::S22
},
283 {codeview::RegisterId::ARM_FS23
, ARM::S23
},
284 {codeview::RegisterId::ARM_FS24
, ARM::S24
},
285 {codeview::RegisterId::ARM_FS25
, ARM::S25
},
286 {codeview::RegisterId::ARM_FS26
, ARM::S26
},
287 {codeview::RegisterId::ARM_FS27
, ARM::S27
},
288 {codeview::RegisterId::ARM_FS28
, ARM::S28
},
289 {codeview::RegisterId::ARM_FS29
, ARM::S29
},
290 {codeview::RegisterId::ARM_FS30
, ARM::S30
},
291 {codeview::RegisterId::ARM_FS31
, ARM::S31
},
292 {codeview::RegisterId::ARM_ND0
, ARM::D0
},
293 {codeview::RegisterId::ARM_ND1
, ARM::D1
},
294 {codeview::RegisterId::ARM_ND2
, ARM::D2
},
295 {codeview::RegisterId::ARM_ND3
, ARM::D3
},
296 {codeview::RegisterId::ARM_ND4
, ARM::D4
},
297 {codeview::RegisterId::ARM_ND5
, ARM::D5
},
298 {codeview::RegisterId::ARM_ND6
, ARM::D6
},
299 {codeview::RegisterId::ARM_ND7
, ARM::D7
},
300 {codeview::RegisterId::ARM_ND8
, ARM::D8
},
301 {codeview::RegisterId::ARM_ND9
, ARM::D9
},
302 {codeview::RegisterId::ARM_ND10
, ARM::D10
},
303 {codeview::RegisterId::ARM_ND11
, ARM::D11
},
304 {codeview::RegisterId::ARM_ND12
, ARM::D12
},
305 {codeview::RegisterId::ARM_ND13
, ARM::D13
},
306 {codeview::RegisterId::ARM_ND14
, ARM::D14
},
307 {codeview::RegisterId::ARM_ND15
, ARM::D15
},
308 {codeview::RegisterId::ARM_ND16
, ARM::D16
},
309 {codeview::RegisterId::ARM_ND17
, ARM::D17
},
310 {codeview::RegisterId::ARM_ND18
, ARM::D18
},
311 {codeview::RegisterId::ARM_ND19
, ARM::D19
},
312 {codeview::RegisterId::ARM_ND20
, ARM::D20
},
313 {codeview::RegisterId::ARM_ND21
, ARM::D21
},
314 {codeview::RegisterId::ARM_ND22
, ARM::D22
},
315 {codeview::RegisterId::ARM_ND23
, ARM::D23
},
316 {codeview::RegisterId::ARM_ND24
, ARM::D24
},
317 {codeview::RegisterId::ARM_ND25
, ARM::D25
},
318 {codeview::RegisterId::ARM_ND26
, ARM::D26
},
319 {codeview::RegisterId::ARM_ND27
, ARM::D27
},
320 {codeview::RegisterId::ARM_ND28
, ARM::D28
},
321 {codeview::RegisterId::ARM_ND29
, ARM::D29
},
322 {codeview::RegisterId::ARM_ND30
, ARM::D30
},
323 {codeview::RegisterId::ARM_ND31
, ARM::D31
},
324 {codeview::RegisterId::ARM_NQ0
, ARM::Q0
},
325 {codeview::RegisterId::ARM_NQ1
, ARM::Q1
},
326 {codeview::RegisterId::ARM_NQ2
, ARM::Q2
},
327 {codeview::RegisterId::ARM_NQ3
, ARM::Q3
},
328 {codeview::RegisterId::ARM_NQ4
, ARM::Q4
},
329 {codeview::RegisterId::ARM_NQ5
, ARM::Q5
},
330 {codeview::RegisterId::ARM_NQ6
, ARM::Q6
},
331 {codeview::RegisterId::ARM_NQ7
, ARM::Q7
},
332 {codeview::RegisterId::ARM_NQ8
, ARM::Q8
},
333 {codeview::RegisterId::ARM_NQ9
, ARM::Q9
},
334 {codeview::RegisterId::ARM_NQ10
, ARM::Q10
},
335 {codeview::RegisterId::ARM_NQ11
, ARM::Q11
},
336 {codeview::RegisterId::ARM_NQ12
, ARM::Q12
},
337 {codeview::RegisterId::ARM_NQ13
, ARM::Q13
},
338 {codeview::RegisterId::ARM_NQ14
, ARM::Q14
},
339 {codeview::RegisterId::ARM_NQ15
, ARM::Q15
},
341 for (unsigned I
= 0; I
< array_lengthof(RegMap
); ++I
)
342 MRI
->mapLLVMRegToCVReg(RegMap
[I
].Reg
, static_cast<int>(RegMap
[I
].CVReg
));
345 static MCRegisterInfo
*createARMMCRegisterInfo(const Triple
&Triple
) {
346 MCRegisterInfo
*X
= new MCRegisterInfo();
347 InitARMMCRegisterInfo(X
, ARM::LR
, 0, 0, ARM::PC
);
348 ARM_MC::initLLVMToCVRegMapping(X
);
352 static MCAsmInfo
*createARMMCAsmInfo(const MCRegisterInfo
&MRI
,
353 const Triple
&TheTriple
,
354 const MCTargetOptions
&Options
) {
356 if (TheTriple
.isOSDarwin() || TheTriple
.isOSBinFormatMachO())
357 MAI
= new ARMMCAsmInfoDarwin(TheTriple
);
358 else if (TheTriple
.isWindowsMSVCEnvironment())
359 MAI
= new ARMCOFFMCAsmInfoMicrosoft();
360 else if (TheTriple
.isOSWindows())
361 MAI
= new ARMCOFFMCAsmInfoGNU();
363 MAI
= new ARMELFMCAsmInfo(TheTriple
);
365 unsigned Reg
= MRI
.getDwarfRegNum(ARM::SP
, true);
366 MAI
->addInitialFrameState(MCCFIInstruction::cfiDefCfa(nullptr, Reg
, 0));
371 static MCStreamer
*createELFStreamer(const Triple
&T
, MCContext
&Ctx
,
372 std::unique_ptr
<MCAsmBackend
> &&MAB
,
373 std::unique_ptr
<MCObjectWriter
> &&OW
,
374 std::unique_ptr
<MCCodeEmitter
> &&Emitter
,
376 return createARMELFStreamer(
377 Ctx
, std::move(MAB
), std::move(OW
), std::move(Emitter
), false,
378 (T
.getArch() == Triple::thumb
|| T
.getArch() == Triple::thumbeb
),
383 createARMMachOStreamer(MCContext
&Ctx
, std::unique_ptr
<MCAsmBackend
> &&MAB
,
384 std::unique_ptr
<MCObjectWriter
> &&OW
,
385 std::unique_ptr
<MCCodeEmitter
> &&Emitter
, bool RelaxAll
,
386 bool DWARFMustBeAtTheEnd
) {
387 return createMachOStreamer(Ctx
, std::move(MAB
), std::move(OW
),
388 std::move(Emitter
), false, DWARFMustBeAtTheEnd
);
391 static MCInstPrinter
*createARMMCInstPrinter(const Triple
&T
,
392 unsigned SyntaxVariant
,
393 const MCAsmInfo
&MAI
,
394 const MCInstrInfo
&MII
,
395 const MCRegisterInfo
&MRI
) {
396 if (SyntaxVariant
== 0)
397 return new ARMInstPrinter(MAI
, MII
, MRI
);
401 static MCRelocationInfo
*createARMMCRelocationInfo(const Triple
&TT
,
403 if (TT
.isOSBinFormatMachO())
404 return createARMMachORelocationInfo(Ctx
);
405 // Default to the stock relocation info.
406 return llvm::createMCRelocationInfo(TT
, Ctx
);
411 class ARMMCInstrAnalysis
: public MCInstrAnalysis
{
413 ARMMCInstrAnalysis(const MCInstrInfo
*Info
) : MCInstrAnalysis(Info
) {}
415 bool isUnconditionalBranch(const MCInst
&Inst
) const override
{
416 // BCCs with the "always" predicate are unconditional branches.
417 if (Inst
.getOpcode() == ARM::Bcc
&& Inst
.getOperand(1).getImm()==ARMCC::AL
)
419 return MCInstrAnalysis::isUnconditionalBranch(Inst
);
422 bool isConditionalBranch(const MCInst
&Inst
) const override
{
423 // BCCs with the "always" predicate are unconditional branches.
424 if (Inst
.getOpcode() == ARM::Bcc
&& Inst
.getOperand(1).getImm()==ARMCC::AL
)
426 return MCInstrAnalysis::isConditionalBranch(Inst
);
429 bool evaluateBranch(const MCInst
&Inst
, uint64_t Addr
, uint64_t Size
,
430 uint64_t &Target
) const override
{
431 const MCInstrDesc
&Desc
= Info
->get(Inst
.getOpcode());
433 // Find the PC-relative immediate operand in the instruction.
434 for (unsigned OpNum
= 0; OpNum
< Desc
.getNumOperands(); ++OpNum
) {
435 if (Inst
.getOperand(OpNum
).isImm() &&
436 Desc
.OpInfo
[OpNum
].OperandType
== MCOI::OPERAND_PCREL
) {
437 int64_t Imm
= Inst
.getOperand(OpNum
).getImm();
438 Target
= ARM_MC::evaluateBranchTarget(Desc
, Addr
, Imm
);
445 Optional
<uint64_t> evaluateMemoryOperandAddress(const MCInst
&Inst
,
446 const MCSubtargetInfo
*STI
,
448 uint64_t Size
) const override
;
453 static Optional
<uint64_t>
454 // NOLINTNEXTLINE(readability-identifier-naming)
455 evaluateMemOpAddrForAddrMode_i12(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
456 unsigned MemOpIndex
, uint64_t Addr
) {
457 if (MemOpIndex
+ 1 >= Desc
.getNumOperands())
460 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
461 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
462 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| !MO2
.isImm())
465 int32_t OffImm
= (int32_t)MO2
.getImm();
466 // Special value for #-0. All others are normal.
467 if (OffImm
== INT32_MIN
)
469 return Addr
+ OffImm
;
472 static Optional
<uint64_t> evaluateMemOpAddrForAddrMode3(const MCInst
&Inst
,
473 const MCInstrDesc
&Desc
,
476 if (MemOpIndex
+ 2 >= Desc
.getNumOperands())
479 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
480 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
481 const MCOperand
&MO3
= Inst
.getOperand(MemOpIndex
+ 2);
482 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| MO2
.getReg() || !MO3
.isImm())
485 unsigned ImmOffs
= ARM_AM::getAM3Offset(MO3
.getImm());
486 ARM_AM::AddrOpc Op
= ARM_AM::getAM3Op(MO3
.getImm());
488 if (Op
== ARM_AM::sub
)
489 return Addr
- ImmOffs
;
490 return Addr
+ ImmOffs
;
493 static Optional
<uint64_t> evaluateMemOpAddrForAddrMode5(const MCInst
&Inst
,
494 const MCInstrDesc
&Desc
,
497 if (MemOpIndex
+ 1 >= Desc
.getNumOperands())
500 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
501 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
502 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| !MO2
.isImm())
505 unsigned ImmOffs
= ARM_AM::getAM5Offset(MO2
.getImm());
506 ARM_AM::AddrOpc Op
= ARM_AM::getAM5Op(MO2
.getImm());
508 if (Op
== ARM_AM::sub
)
509 return Addr
- ImmOffs
* 4;
510 return Addr
+ ImmOffs
* 4;
513 static Optional
<uint64_t>
514 evaluateMemOpAddrForAddrMode5FP16(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
515 unsigned MemOpIndex
, uint64_t Addr
) {
516 if (MemOpIndex
+ 1 >= Desc
.getNumOperands())
519 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
520 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
521 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| !MO2
.isImm())
524 unsigned ImmOffs
= ARM_AM::getAM5FP16Offset(MO2
.getImm());
525 ARM_AM::AddrOpc Op
= ARM_AM::getAM5FP16Op(MO2
.getImm());
527 if (Op
== ARM_AM::sub
)
528 return Addr
- ImmOffs
* 2;
529 return Addr
+ ImmOffs
* 2;
532 static Optional
<uint64_t>
533 // NOLINTNEXTLINE(readability-identifier-naming)
534 evaluateMemOpAddrForAddrModeT2_i8s4(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
535 unsigned MemOpIndex
, uint64_t Addr
) {
536 if (MemOpIndex
+ 1 >= Desc
.getNumOperands())
539 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
540 const MCOperand
&MO2
= Inst
.getOperand(MemOpIndex
+ 1);
541 if (!MO1
.isReg() || MO1
.getReg() != ARM::PC
|| !MO2
.isImm())
544 int32_t OffImm
= (int32_t)MO2
.getImm();
545 assert(((OffImm
& 0x3) == 0) && "Not a valid immediate!");
547 // Special value for #-0. All others are normal.
548 if (OffImm
== INT32_MIN
)
550 return Addr
+ OffImm
;
553 static Optional
<uint64_t>
554 // NOLINTNEXTLINE(readability-identifier-naming)
555 evaluateMemOpAddrForAddrModeT2_pc(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
556 unsigned MemOpIndex
, uint64_t Addr
) {
557 const MCOperand
&MO1
= Inst
.getOperand(MemOpIndex
);
561 int32_t OffImm
= (int32_t)MO1
.getImm();
563 // Special value for #-0. All others are normal.
564 if (OffImm
== INT32_MIN
)
566 return Addr
+ OffImm
;
569 static Optional
<uint64_t>
570 // NOLINTNEXTLINE(readability-identifier-naming)
571 evaluateMemOpAddrForAddrModeT1_s(const MCInst
&Inst
, const MCInstrDesc
&Desc
,
572 unsigned MemOpIndex
, uint64_t Addr
) {
573 return evaluateMemOpAddrForAddrModeT2_pc(Inst
, Desc
, MemOpIndex
, Addr
);
576 Optional
<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
577 const MCInst
&Inst
, const MCSubtargetInfo
*STI
, uint64_t Addr
,
578 uint64_t Size
) const {
579 const MCInstrDesc
&Desc
= Info
->get(Inst
.getOpcode());
581 // Only load instructions can have PC-relative memory addressing.
585 // PC-relative addressing does not update the base register.
586 uint64_t TSFlags
= Desc
.TSFlags
;
588 (TSFlags
& ARMII::IndexModeMask
) >> ARMII::IndexModeShift
;
589 if (IndexMode
!= ARMII::IndexModeNone
)
592 // Find the memory addressing operand in the instruction.
593 unsigned OpIndex
= Desc
.NumDefs
;
594 while (OpIndex
< Desc
.getNumOperands() &&
595 Desc
.OpInfo
[OpIndex
].OperandType
!= MCOI::OPERAND_MEMORY
)
597 if (OpIndex
== Desc
.getNumOperands())
600 // Base address for PC-relative addressing is always 32-bit aligned.
603 // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
605 switch (Desc
.TSFlags
& ARMII::FormMask
) {
609 case ARMII::ThumbFrm
:
612 // VLDR* instructions share the same opcode (and thus the same form) for Arm
613 // and Thumb. Use a bit longer route through STI in that case.
614 case ARMII::VFPLdStFrm
:
615 Addr
+= STI
->getFeatureBits()[ARM::ModeThumb
] ? 4 : 8;
619 // Eveluate the address depending on the addressing mode
620 unsigned AddrMode
= (TSFlags
& ARMII::AddrModeMask
);
624 case ARMII::AddrMode_i12
:
625 return evaluateMemOpAddrForAddrMode_i12(Inst
, Desc
, OpIndex
, Addr
);
626 case ARMII::AddrMode3
:
627 return evaluateMemOpAddrForAddrMode3(Inst
, Desc
, OpIndex
, Addr
);
628 case ARMII::AddrMode5
:
629 return evaluateMemOpAddrForAddrMode5(Inst
, Desc
, OpIndex
, Addr
);
630 case ARMII::AddrMode5FP16
:
631 return evaluateMemOpAddrForAddrMode5FP16(Inst
, Desc
, OpIndex
, Addr
);
632 case ARMII::AddrModeT2_i8s4
:
633 return evaluateMemOpAddrForAddrModeT2_i8s4(Inst
, Desc
, OpIndex
, Addr
);
634 case ARMII::AddrModeT2_pc
:
635 return evaluateMemOpAddrForAddrModeT2_pc(Inst
, Desc
, OpIndex
, Addr
);
636 case ARMII::AddrModeT1_s
:
637 return evaluateMemOpAddrForAddrModeT1_s(Inst
, Desc
, OpIndex
, Addr
);
641 static MCInstrAnalysis
*createARMMCInstrAnalysis(const MCInstrInfo
*Info
) {
642 return new ARMMCInstrAnalysis(Info
);
645 bool ARM::isCDECoproc(size_t Coproc
, const MCSubtargetInfo
&STI
) {
646 // Unfortunately we don't have ARMTargetInfo in the disassembler, so we have
647 // to rely on feature bits.
650 return STI
.getFeatureBits()[ARM::FeatureCoprocCDE0
+ Coproc
];
653 // Force static initialization.
654 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeARMTargetMC() {
655 for (Target
*T
: {&getTheARMLETarget(), &getTheARMBETarget(),
656 &getTheThumbLETarget(), &getTheThumbBETarget()}) {
657 // Register the MC asm info.
658 RegisterMCAsmInfoFn
X(*T
, createARMMCAsmInfo
);
660 // Register the MC instruction info.
661 TargetRegistry::RegisterMCInstrInfo(*T
, createARMMCInstrInfo
);
663 // Register the MC register info.
664 TargetRegistry::RegisterMCRegInfo(*T
, createARMMCRegisterInfo
);
666 // Register the MC subtarget info.
667 TargetRegistry::RegisterMCSubtargetInfo(*T
,
668 ARM_MC::createARMMCSubtargetInfo
);
670 TargetRegistry::RegisterELFStreamer(*T
, createELFStreamer
);
671 TargetRegistry::RegisterCOFFStreamer(*T
, createARMWinCOFFStreamer
);
672 TargetRegistry::RegisterMachOStreamer(*T
, createARMMachOStreamer
);
674 // Register the obj target streamer.
675 TargetRegistry::RegisterObjectTargetStreamer(*T
,
676 createARMObjectTargetStreamer
);
678 // Register the asm streamer.
679 TargetRegistry::RegisterAsmTargetStreamer(*T
, createARMTargetAsmStreamer
);
681 // Register the null TargetStreamer.
682 TargetRegistry::RegisterNullTargetStreamer(*T
, createARMNullTargetStreamer
);
684 // Register the MCInstPrinter.
685 TargetRegistry::RegisterMCInstPrinter(*T
, createARMMCInstPrinter
);
687 // Register the MC relocation info.
688 TargetRegistry::RegisterMCRelocationInfo(*T
, createARMMCRelocationInfo
);
691 // Register the MC instruction analyzer.
692 for (Target
*T
: {&getTheARMLETarget(), &getTheARMBETarget(),
693 &getTheThumbLETarget(), &getTheThumbBETarget()})
694 TargetRegistry::RegisterMCInstrAnalysis(*T
, createARMMCInstrAnalysis
);
696 for (Target
*T
: {&getTheARMLETarget(), &getTheThumbLETarget()}) {
697 TargetRegistry::RegisterMCCodeEmitter(*T
, createARMLEMCCodeEmitter
);
698 TargetRegistry::RegisterMCAsmBackend(*T
, createARMLEAsmBackend
);
700 for (Target
*T
: {&getTheARMBETarget(), &getTheThumbBETarget()}) {
701 TargetRegistry::RegisterMCCodeEmitter(*T
, createARMBEMCCodeEmitter
);
702 TargetRegistry::RegisterMCAsmBackend(*T
, createARMBEAsmBackend
);