1 //===-- AArch64MCTargetDesc.cpp - AArch64 Target Descriptions ---*- C++ -*-===//
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 AArch64 specific target descriptions.
11 //===----------------------------------------------------------------------===//
13 #include "AArch64MCTargetDesc.h"
14 #include "AArch64ELFStreamer.h"
15 #include "AArch64MCAsmInfo.h"
16 #include "AArch64WinCOFFStreamer.h"
17 #include "MCTargetDesc/AArch64AddressingModes.h"
18 #include "MCTargetDesc/AArch64InstPrinter.h"
19 #include "TargetInfo/AArch64TargetInfo.h"
20 #include "llvm/DebugInfo/CodeView/CodeView.h"
21 #include "llvm/MC/MCAsmBackend.h"
22 #include "llvm/MC/MCCodeEmitter.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/Support/Endian.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/TargetRegistry.h"
35 #define GET_INSTRINFO_MC_DESC
36 #define GET_INSTRINFO_MC_HELPERS
37 #include "AArch64GenInstrInfo.inc"
39 #define GET_SUBTARGETINFO_MC_DESC
40 #include "AArch64GenSubtargetInfo.inc"
42 #define GET_REGINFO_MC_DESC
43 #include "AArch64GenRegisterInfo.inc"
45 static MCInstrInfo
*createAArch64MCInstrInfo() {
46 MCInstrInfo
*X
= new MCInstrInfo();
47 InitAArch64MCInstrInfo(X
);
51 static MCSubtargetInfo
*
52 createAArch64MCSubtargetInfo(const Triple
&TT
, StringRef CPU
, StringRef FS
) {
56 return createAArch64MCSubtargetInfoImpl(TT
, CPU
, FS
);
59 void AArch64_MC::initLLVMToCVRegMapping(MCRegisterInfo
*MRI
) {
60 // Mapping from CodeView to MC register id.
62 codeview::RegisterId CVReg
;
65 {codeview::RegisterId::ARM64_W0
, AArch64::W0
},
66 {codeview::RegisterId::ARM64_W1
, AArch64::W1
},
67 {codeview::RegisterId::ARM64_W2
, AArch64::W2
},
68 {codeview::RegisterId::ARM64_W3
, AArch64::W3
},
69 {codeview::RegisterId::ARM64_W4
, AArch64::W4
},
70 {codeview::RegisterId::ARM64_W5
, AArch64::W5
},
71 {codeview::RegisterId::ARM64_W6
, AArch64::W6
},
72 {codeview::RegisterId::ARM64_W7
, AArch64::W7
},
73 {codeview::RegisterId::ARM64_W8
, AArch64::W8
},
74 {codeview::RegisterId::ARM64_W9
, AArch64::W9
},
75 {codeview::RegisterId::ARM64_W10
, AArch64::W10
},
76 {codeview::RegisterId::ARM64_W11
, AArch64::W11
},
77 {codeview::RegisterId::ARM64_W12
, AArch64::W12
},
78 {codeview::RegisterId::ARM64_W13
, AArch64::W13
},
79 {codeview::RegisterId::ARM64_W14
, AArch64::W14
},
80 {codeview::RegisterId::ARM64_W15
, AArch64::W15
},
81 {codeview::RegisterId::ARM64_W16
, AArch64::W16
},
82 {codeview::RegisterId::ARM64_W17
, AArch64::W17
},
83 {codeview::RegisterId::ARM64_W18
, AArch64::W18
},
84 {codeview::RegisterId::ARM64_W19
, AArch64::W19
},
85 {codeview::RegisterId::ARM64_W20
, AArch64::W20
},
86 {codeview::RegisterId::ARM64_W21
, AArch64::W21
},
87 {codeview::RegisterId::ARM64_W22
, AArch64::W22
},
88 {codeview::RegisterId::ARM64_W23
, AArch64::W23
},
89 {codeview::RegisterId::ARM64_W24
, AArch64::W24
},
90 {codeview::RegisterId::ARM64_W25
, AArch64::W25
},
91 {codeview::RegisterId::ARM64_W26
, AArch64::W26
},
92 {codeview::RegisterId::ARM64_W27
, AArch64::W27
},
93 {codeview::RegisterId::ARM64_W28
, AArch64::W28
},
94 {codeview::RegisterId::ARM64_W29
, AArch64::W29
},
95 {codeview::RegisterId::ARM64_W30
, AArch64::W30
},
96 {codeview::RegisterId::ARM64_WZR
, AArch64::WZR
},
97 {codeview::RegisterId::ARM64_X0
, AArch64::X0
},
98 {codeview::RegisterId::ARM64_X1
, AArch64::X1
},
99 {codeview::RegisterId::ARM64_X2
, AArch64::X2
},
100 {codeview::RegisterId::ARM64_X3
, AArch64::X3
},
101 {codeview::RegisterId::ARM64_X4
, AArch64::X4
},
102 {codeview::RegisterId::ARM64_X5
, AArch64::X5
},
103 {codeview::RegisterId::ARM64_X6
, AArch64::X6
},
104 {codeview::RegisterId::ARM64_X7
, AArch64::X7
},
105 {codeview::RegisterId::ARM64_X8
, AArch64::X8
},
106 {codeview::RegisterId::ARM64_X9
, AArch64::X9
},
107 {codeview::RegisterId::ARM64_X10
, AArch64::X10
},
108 {codeview::RegisterId::ARM64_X11
, AArch64::X11
},
109 {codeview::RegisterId::ARM64_X12
, AArch64::X12
},
110 {codeview::RegisterId::ARM64_X13
, AArch64::X13
},
111 {codeview::RegisterId::ARM64_X14
, AArch64::X14
},
112 {codeview::RegisterId::ARM64_X15
, AArch64::X15
},
113 {codeview::RegisterId::ARM64_X16
, AArch64::X16
},
114 {codeview::RegisterId::ARM64_X17
, AArch64::X17
},
115 {codeview::RegisterId::ARM64_X18
, AArch64::X18
},
116 {codeview::RegisterId::ARM64_X19
, AArch64::X19
},
117 {codeview::RegisterId::ARM64_X20
, AArch64::X20
},
118 {codeview::RegisterId::ARM64_X21
, AArch64::X21
},
119 {codeview::RegisterId::ARM64_X22
, AArch64::X22
},
120 {codeview::RegisterId::ARM64_X23
, AArch64::X23
},
121 {codeview::RegisterId::ARM64_X24
, AArch64::X24
},
122 {codeview::RegisterId::ARM64_X25
, AArch64::X25
},
123 {codeview::RegisterId::ARM64_X26
, AArch64::X26
},
124 {codeview::RegisterId::ARM64_X27
, AArch64::X27
},
125 {codeview::RegisterId::ARM64_X28
, AArch64::X28
},
126 {codeview::RegisterId::ARM64_FP
, AArch64::FP
},
127 {codeview::RegisterId::ARM64_LR
, AArch64::LR
},
128 {codeview::RegisterId::ARM64_SP
, AArch64::SP
},
129 {codeview::RegisterId::ARM64_ZR
, AArch64::XZR
},
130 {codeview::RegisterId::ARM64_NZCV
, AArch64::NZCV
},
131 {codeview::RegisterId::ARM64_S0
, AArch64::S0
},
132 {codeview::RegisterId::ARM64_S1
, AArch64::S1
},
133 {codeview::RegisterId::ARM64_S2
, AArch64::S2
},
134 {codeview::RegisterId::ARM64_S3
, AArch64::S3
},
135 {codeview::RegisterId::ARM64_S4
, AArch64::S4
},
136 {codeview::RegisterId::ARM64_S5
, AArch64::S5
},
137 {codeview::RegisterId::ARM64_S6
, AArch64::S6
},
138 {codeview::RegisterId::ARM64_S7
, AArch64::S7
},
139 {codeview::RegisterId::ARM64_S8
, AArch64::S8
},
140 {codeview::RegisterId::ARM64_S9
, AArch64::S9
},
141 {codeview::RegisterId::ARM64_S10
, AArch64::S10
},
142 {codeview::RegisterId::ARM64_S11
, AArch64::S11
},
143 {codeview::RegisterId::ARM64_S12
, AArch64::S12
},
144 {codeview::RegisterId::ARM64_S13
, AArch64::S13
},
145 {codeview::RegisterId::ARM64_S14
, AArch64::S14
},
146 {codeview::RegisterId::ARM64_S15
, AArch64::S15
},
147 {codeview::RegisterId::ARM64_S16
, AArch64::S16
},
148 {codeview::RegisterId::ARM64_S17
, AArch64::S17
},
149 {codeview::RegisterId::ARM64_S18
, AArch64::S18
},
150 {codeview::RegisterId::ARM64_S19
, AArch64::S19
},
151 {codeview::RegisterId::ARM64_S20
, AArch64::S20
},
152 {codeview::RegisterId::ARM64_S21
, AArch64::S21
},
153 {codeview::RegisterId::ARM64_S22
, AArch64::S22
},
154 {codeview::RegisterId::ARM64_S23
, AArch64::S23
},
155 {codeview::RegisterId::ARM64_S24
, AArch64::S24
},
156 {codeview::RegisterId::ARM64_S25
, AArch64::S25
},
157 {codeview::RegisterId::ARM64_S26
, AArch64::S26
},
158 {codeview::RegisterId::ARM64_S27
, AArch64::S27
},
159 {codeview::RegisterId::ARM64_S28
, AArch64::S28
},
160 {codeview::RegisterId::ARM64_S29
, AArch64::S29
},
161 {codeview::RegisterId::ARM64_S30
, AArch64::S30
},
162 {codeview::RegisterId::ARM64_S31
, AArch64::S31
},
163 {codeview::RegisterId::ARM64_D0
, AArch64::D0
},
164 {codeview::RegisterId::ARM64_D1
, AArch64::D1
},
165 {codeview::RegisterId::ARM64_D2
, AArch64::D2
},
166 {codeview::RegisterId::ARM64_D3
, AArch64::D3
},
167 {codeview::RegisterId::ARM64_D4
, AArch64::D4
},
168 {codeview::RegisterId::ARM64_D5
, AArch64::D5
},
169 {codeview::RegisterId::ARM64_D6
, AArch64::D6
},
170 {codeview::RegisterId::ARM64_D7
, AArch64::D7
},
171 {codeview::RegisterId::ARM64_D8
, AArch64::D8
},
172 {codeview::RegisterId::ARM64_D9
, AArch64::D9
},
173 {codeview::RegisterId::ARM64_D10
, AArch64::D10
},
174 {codeview::RegisterId::ARM64_D11
, AArch64::D11
},
175 {codeview::RegisterId::ARM64_D12
, AArch64::D12
},
176 {codeview::RegisterId::ARM64_D13
, AArch64::D13
},
177 {codeview::RegisterId::ARM64_D14
, AArch64::D14
},
178 {codeview::RegisterId::ARM64_D15
, AArch64::D15
},
179 {codeview::RegisterId::ARM64_D16
, AArch64::D16
},
180 {codeview::RegisterId::ARM64_D17
, AArch64::D17
},
181 {codeview::RegisterId::ARM64_D18
, AArch64::D18
},
182 {codeview::RegisterId::ARM64_D19
, AArch64::D19
},
183 {codeview::RegisterId::ARM64_D20
, AArch64::D20
},
184 {codeview::RegisterId::ARM64_D21
, AArch64::D21
},
185 {codeview::RegisterId::ARM64_D22
, AArch64::D22
},
186 {codeview::RegisterId::ARM64_D23
, AArch64::D23
},
187 {codeview::RegisterId::ARM64_D24
, AArch64::D24
},
188 {codeview::RegisterId::ARM64_D25
, AArch64::D25
},
189 {codeview::RegisterId::ARM64_D26
, AArch64::D26
},
190 {codeview::RegisterId::ARM64_D27
, AArch64::D27
},
191 {codeview::RegisterId::ARM64_D28
, AArch64::D28
},
192 {codeview::RegisterId::ARM64_D29
, AArch64::D29
},
193 {codeview::RegisterId::ARM64_D30
, AArch64::D30
},
194 {codeview::RegisterId::ARM64_D31
, AArch64::D31
},
195 {codeview::RegisterId::ARM64_Q0
, AArch64::Q0
},
196 {codeview::RegisterId::ARM64_Q1
, AArch64::Q1
},
197 {codeview::RegisterId::ARM64_Q2
, AArch64::Q2
},
198 {codeview::RegisterId::ARM64_Q3
, AArch64::Q3
},
199 {codeview::RegisterId::ARM64_Q4
, AArch64::Q4
},
200 {codeview::RegisterId::ARM64_Q5
, AArch64::Q5
},
201 {codeview::RegisterId::ARM64_Q6
, AArch64::Q6
},
202 {codeview::RegisterId::ARM64_Q7
, AArch64::Q7
},
203 {codeview::RegisterId::ARM64_Q8
, AArch64::Q8
},
204 {codeview::RegisterId::ARM64_Q9
, AArch64::Q9
},
205 {codeview::RegisterId::ARM64_Q10
, AArch64::Q10
},
206 {codeview::RegisterId::ARM64_Q11
, AArch64::Q11
},
207 {codeview::RegisterId::ARM64_Q12
, AArch64::Q12
},
208 {codeview::RegisterId::ARM64_Q13
, AArch64::Q13
},
209 {codeview::RegisterId::ARM64_Q14
, AArch64::Q14
},
210 {codeview::RegisterId::ARM64_Q15
, AArch64::Q15
},
211 {codeview::RegisterId::ARM64_Q16
, AArch64::Q16
},
212 {codeview::RegisterId::ARM64_Q17
, AArch64::Q17
},
213 {codeview::RegisterId::ARM64_Q18
, AArch64::Q18
},
214 {codeview::RegisterId::ARM64_Q19
, AArch64::Q19
},
215 {codeview::RegisterId::ARM64_Q20
, AArch64::Q20
},
216 {codeview::RegisterId::ARM64_Q21
, AArch64::Q21
},
217 {codeview::RegisterId::ARM64_Q22
, AArch64::Q22
},
218 {codeview::RegisterId::ARM64_Q23
, AArch64::Q23
},
219 {codeview::RegisterId::ARM64_Q24
, AArch64::Q24
},
220 {codeview::RegisterId::ARM64_Q25
, AArch64::Q25
},
221 {codeview::RegisterId::ARM64_Q26
, AArch64::Q26
},
222 {codeview::RegisterId::ARM64_Q27
, AArch64::Q27
},
223 {codeview::RegisterId::ARM64_Q28
, AArch64::Q28
},
224 {codeview::RegisterId::ARM64_Q29
, AArch64::Q29
},
225 {codeview::RegisterId::ARM64_Q30
, AArch64::Q30
},
226 {codeview::RegisterId::ARM64_Q31
, AArch64::Q31
},
229 for (unsigned I
= 0; I
< array_lengthof(RegMap
); ++I
)
230 MRI
->mapLLVMRegToCVReg(RegMap
[I
].Reg
, static_cast<int>(RegMap
[I
].CVReg
));
233 static MCRegisterInfo
*createAArch64MCRegisterInfo(const Triple
&Triple
) {
234 MCRegisterInfo
*X
= new MCRegisterInfo();
235 InitAArch64MCRegisterInfo(X
, AArch64::LR
);
236 AArch64_MC::initLLVMToCVRegMapping(X
);
240 static MCAsmInfo
*createAArch64MCAsmInfo(const MCRegisterInfo
&MRI
,
241 const Triple
&TheTriple
) {
243 if (TheTriple
.isOSBinFormatMachO())
244 MAI
= new AArch64MCAsmInfoDarwin(TheTriple
.getArch() == Triple::aarch64_32
);
245 else if (TheTriple
.isWindowsMSVCEnvironment())
246 MAI
= new AArch64MCAsmInfoMicrosoftCOFF();
247 else if (TheTriple
.isOSBinFormatCOFF())
248 MAI
= new AArch64MCAsmInfoGNUCOFF();
250 assert(TheTriple
.isOSBinFormatELF() && "Invalid target");
251 MAI
= new AArch64MCAsmInfoELF(TheTriple
);
254 // Initial state of the frame pointer is SP.
255 unsigned Reg
= MRI
.getDwarfRegNum(AArch64::SP
, true);
256 MCCFIInstruction Inst
= MCCFIInstruction::createDefCfa(nullptr, Reg
, 0);
257 MAI
->addInitialFrameState(Inst
);
262 static MCInstPrinter
*createAArch64MCInstPrinter(const Triple
&T
,
263 unsigned SyntaxVariant
,
264 const MCAsmInfo
&MAI
,
265 const MCInstrInfo
&MII
,
266 const MCRegisterInfo
&MRI
) {
267 if (SyntaxVariant
== 0)
268 return new AArch64InstPrinter(MAI
, MII
, MRI
);
269 if (SyntaxVariant
== 1)
270 return new AArch64AppleInstPrinter(MAI
, MII
, MRI
);
275 static MCStreamer
*createELFStreamer(const Triple
&T
, MCContext
&Ctx
,
276 std::unique_ptr
<MCAsmBackend
> &&TAB
,
277 std::unique_ptr
<MCObjectWriter
> &&OW
,
278 std::unique_ptr
<MCCodeEmitter
> &&Emitter
,
280 return createAArch64ELFStreamer(Ctx
, std::move(TAB
), std::move(OW
),
281 std::move(Emitter
), RelaxAll
);
284 static MCStreamer
*createMachOStreamer(MCContext
&Ctx
,
285 std::unique_ptr
<MCAsmBackend
> &&TAB
,
286 std::unique_ptr
<MCObjectWriter
> &&OW
,
287 std::unique_ptr
<MCCodeEmitter
> &&Emitter
,
289 bool DWARFMustBeAtTheEnd
) {
290 return createMachOStreamer(Ctx
, std::move(TAB
), std::move(OW
),
291 std::move(Emitter
), RelaxAll
, DWARFMustBeAtTheEnd
,
292 /*LabelSections*/ true);
296 createWinCOFFStreamer(MCContext
&Ctx
, std::unique_ptr
<MCAsmBackend
> &&TAB
,
297 std::unique_ptr
<MCObjectWriter
> &&OW
,
298 std::unique_ptr
<MCCodeEmitter
> &&Emitter
, bool RelaxAll
,
299 bool IncrementalLinkerCompatible
) {
300 return createAArch64WinCOFFStreamer(Ctx
, std::move(TAB
), std::move(OW
),
301 std::move(Emitter
), RelaxAll
,
302 IncrementalLinkerCompatible
);
307 class AArch64MCInstrAnalysis
: public MCInstrAnalysis
{
309 AArch64MCInstrAnalysis(const MCInstrInfo
*Info
) : MCInstrAnalysis(Info
) {}
311 bool evaluateBranch(const MCInst
&Inst
, uint64_t Addr
, uint64_t Size
,
312 uint64_t &Target
) const override
{
313 // Search for a PC-relative argument.
314 // This will handle instructions like bcc (where the first argument is the
315 // condition code) and cbz (where it is a register).
316 const auto &Desc
= Info
->get(Inst
.getOpcode());
317 for (unsigned i
= 0, e
= Inst
.getNumOperands(); i
!= e
; i
++) {
318 if (Desc
.OpInfo
[i
].OperandType
== MCOI::OPERAND_PCREL
) {
319 int64_t Imm
= Inst
.getOperand(i
).getImm() * 4;
327 std::vector
<std::pair
<uint64_t, uint64_t>>
328 findPltEntries(uint64_t PltSectionVA
, ArrayRef
<uint8_t> PltContents
,
329 uint64_t GotPltSectionVA
,
330 const Triple
&TargetTriple
) const override
{
331 // Do a lightweight parsing of PLT entries.
332 std::vector
<std::pair
<uint64_t, uint64_t>> Result
;
333 for (uint64_t Byte
= 0, End
= PltContents
.size(); Byte
+ 7 < End
;
335 uint32_t Insn
= support::endian::read32le(PltContents
.data() + Byte
);
337 // Check for optional bti c that prefixes adrp in BTI enabled entries
338 if (Insn
== 0xd503245f) {
340 Insn
= support::endian::read32le(PltContents
.data() + Byte
+ Off
);
343 if ((Insn
& 0x9f000000) != 0x90000000)
346 uint64_t Imm
= (((PltSectionVA
+ Byte
) >> 12) << 12) +
347 (((Insn
>> 29) & 3) << 12) + (((Insn
>> 5) & 0x3ffff) << 14);
349 support::endian::read32le(PltContents
.data() + Byte
+ Off
);
350 // Check for: ldr Xt, [Xn, #pimm].
351 if (Insn2
>> 22 == 0x3e5) {
352 Imm
+= ((Insn2
>> 10) & 0xfff) << 3;
353 Result
.push_back(std::make_pair(PltSectionVA
+ Byte
, Imm
));
361 } // end anonymous namespace
363 static MCInstrAnalysis
*createAArch64InstrAnalysis(const MCInstrInfo
*Info
) {
364 return new AArch64MCInstrAnalysis(Info
);
367 // Force static initialization.
368 extern "C" void LLVMInitializeAArch64TargetMC() {
369 for (Target
*T
: {&getTheAArch64leTarget(), &getTheAArch64beTarget(),
370 &getTheAArch64_32Target(), &getTheARM64Target(),
371 &getTheARM64_32Target()}) {
372 // Register the MC asm info.
373 RegisterMCAsmInfoFn
X(*T
, createAArch64MCAsmInfo
);
375 // Register the MC instruction info.
376 TargetRegistry::RegisterMCInstrInfo(*T
, createAArch64MCInstrInfo
);
378 // Register the MC register info.
379 TargetRegistry::RegisterMCRegInfo(*T
, createAArch64MCRegisterInfo
);
381 // Register the MC subtarget info.
382 TargetRegistry::RegisterMCSubtargetInfo(*T
, createAArch64MCSubtargetInfo
);
384 // Register the MC instruction analyzer.
385 TargetRegistry::RegisterMCInstrAnalysis(*T
, createAArch64InstrAnalysis
);
387 // Register the MC Code Emitter
388 TargetRegistry::RegisterMCCodeEmitter(*T
, createAArch64MCCodeEmitter
);
390 // Register the obj streamers.
391 TargetRegistry::RegisterELFStreamer(*T
, createELFStreamer
);
392 TargetRegistry::RegisterMachOStreamer(*T
, createMachOStreamer
);
393 TargetRegistry::RegisterCOFFStreamer(*T
, createWinCOFFStreamer
);
395 // Register the obj target streamer.
396 TargetRegistry::RegisterObjectTargetStreamer(
397 *T
, createAArch64ObjectTargetStreamer
);
399 // Register the asm streamer.
400 TargetRegistry::RegisterAsmTargetStreamer(*T
,
401 createAArch64AsmTargetStreamer
);
402 // Register the MCInstPrinter.
403 TargetRegistry::RegisterMCInstPrinter(*T
, createAArch64MCInstPrinter
);
406 // Register the asm backend.
407 for (Target
*T
: {&getTheAArch64leTarget(), &getTheAArch64_32Target(),
408 &getTheARM64Target(), &getTheARM64_32Target()})
409 TargetRegistry::RegisterMCAsmBackend(*T
, createAArch64leAsmBackend
);
410 TargetRegistry::RegisterMCAsmBackend(getTheAArch64beTarget(),
411 createAArch64beAsmBackend
);