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 "ARMBaseInfo.h"
15 #include "ARMInstPrinter.h"
16 #include "ARMMCAsmInfo.h"
17 #include "TargetInfo/ARMTargetInfo.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/MC/MCAsmBackend.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCELFStreamer.h"
22 #include "llvm/MC/MCInstrAnalysis.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCObjectWriter.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/TargetParser.h"
30 #include "llvm/Support/TargetRegistry.h"
34 #define GET_REGINFO_MC_DESC
35 #include "ARMGenRegisterInfo.inc"
37 static bool getMCRDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
39 if (STI
.getFeatureBits()[llvm::ARM::HasV7Ops
] &&
40 (MI
.getOperand(0).isImm() && MI
.getOperand(0).getImm() == 15) &&
41 (MI
.getOperand(1).isImm() && MI
.getOperand(1).getImm() == 0) &&
42 // Checks for the deprecated CP15ISB encoding:
43 // mcr p15, #0, rX, c7, c5, #4
44 (MI
.getOperand(3).isImm() && MI
.getOperand(3).getImm() == 7)) {
45 if ((MI
.getOperand(5).isImm() && MI
.getOperand(5).getImm() == 4)) {
46 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 5) {
47 Info
= "deprecated since v7, use 'isb'";
51 // Checks for the deprecated CP15DSB encoding:
52 // mcr p15, #0, rX, c7, c10, #4
53 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 10) {
54 Info
= "deprecated since v7, use 'dsb'";
58 // Checks for the deprecated CP15DMB encoding:
59 // mcr p15, #0, rX, c7, c10, #5
60 if (MI
.getOperand(4).isImm() && MI
.getOperand(4).getImm() == 10 &&
61 (MI
.getOperand(5).isImm() && MI
.getOperand(5).getImm() == 5)) {
62 Info
= "deprecated since v7, use 'dmb'";
69 static bool getITDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
71 if (STI
.getFeatureBits()[llvm::ARM::HasV8Ops
] && MI
.getOperand(1).isImm() &&
72 MI
.getOperand(1).getImm() != 8) {
73 Info
= "applying IT instruction to more than one subsequent instruction is "
81 static bool getARMStoreDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
83 assert(!STI
.getFeatureBits()[llvm::ARM::ModeThumb
] &&
84 "cannot predicate thumb instructions");
86 assert(MI
.getNumOperands() >= 4 && "expected >= 4 arguments");
87 for (unsigned OI
= 4, OE
= MI
.getNumOperands(); OI
< OE
; ++OI
) {
88 assert(MI
.getOperand(OI
).isReg() && "expected register");
89 if (MI
.getOperand(OI
).getReg() == ARM::SP
||
90 MI
.getOperand(OI
).getReg() == ARM::PC
) {
91 Info
= "use of SP or PC in the list is deprecated";
98 static bool getARMLoadDeprecationInfo(MCInst
&MI
, const MCSubtargetInfo
&STI
,
100 assert(!STI
.getFeatureBits()[llvm::ARM::ModeThumb
] &&
101 "cannot predicate thumb instructions");
103 assert(MI
.getNumOperands() >= 4 && "expected >= 4 arguments");
104 bool ListContainsPC
= false, ListContainsLR
= false;
105 for (unsigned OI
= 4, OE
= MI
.getNumOperands(); OI
< OE
; ++OI
) {
106 assert(MI
.getOperand(OI
).isReg() && "expected register");
107 switch (MI
.getOperand(OI
).getReg()) {
111 ListContainsLR
= true;
114 ListContainsPC
= true;
117 Info
= "use of SP in the list is deprecated";
122 if (ListContainsPC
&& ListContainsLR
) {
123 Info
= "use of LR and PC simultaneously in the list is deprecated";
130 #define GET_INSTRINFO_MC_DESC
131 #include "ARMGenInstrInfo.inc"
133 #define GET_SUBTARGETINFO_MC_DESC
134 #include "ARMGenSubtargetInfo.inc"
136 std::string
ARM_MC::ParseARMTriple(const Triple
&TT
, StringRef CPU
) {
137 std::string ARMArchFeature
;
139 ARM::ArchKind ArchID
= ARM::parseArch(TT
.getArchName());
140 if (ArchID
!= ARM::ArchKind::INVALID
&& (CPU
.empty() || CPU
== "generic"))
141 ARMArchFeature
= (ARMArchFeature
+ "+" + ARM::getArchName(ArchID
)).str();
144 if (!ARMArchFeature
.empty())
145 ARMArchFeature
+= ",";
146 ARMArchFeature
+= "+thumb-mode,+v4t";
150 if (!ARMArchFeature
.empty())
151 ARMArchFeature
+= ",";
152 ARMArchFeature
+= "+nacl-trap";
155 if (TT
.isOSWindows()) {
156 if (!ARMArchFeature
.empty())
157 ARMArchFeature
+= ",";
158 ARMArchFeature
+= "+noarm";
161 return ARMArchFeature
;
164 MCSubtargetInfo
*ARM_MC::createARMMCSubtargetInfo(const Triple
&TT
,
165 StringRef CPU
, StringRef FS
) {
166 std::string ArchFS
= ARM_MC::ParseARMTriple(TT
, CPU
);
169 ArchFS
= (Twine(ArchFS
) + "," + FS
).str();
174 return createARMMCSubtargetInfoImpl(TT
, CPU
, ArchFS
);
177 static MCInstrInfo
*createARMMCInstrInfo() {
178 MCInstrInfo
*X
= new MCInstrInfo();
179 InitARMMCInstrInfo(X
);
183 static MCRegisterInfo
*createARMMCRegisterInfo(const Triple
&Triple
) {
184 MCRegisterInfo
*X
= new MCRegisterInfo();
185 InitARMMCRegisterInfo(X
, ARM::LR
, 0, 0, ARM::PC
);
189 static MCAsmInfo
*createARMMCAsmInfo(const MCRegisterInfo
&MRI
,
190 const Triple
&TheTriple
) {
192 if (TheTriple
.isOSDarwin() || TheTriple
.isOSBinFormatMachO())
193 MAI
= new ARMMCAsmInfoDarwin(TheTriple
);
194 else if (TheTriple
.isWindowsMSVCEnvironment())
195 MAI
= new ARMCOFFMCAsmInfoMicrosoft();
196 else if (TheTriple
.isOSWindows())
197 MAI
= new ARMCOFFMCAsmInfoGNU();
199 MAI
= new ARMELFMCAsmInfo(TheTriple
);
201 unsigned Reg
= MRI
.getDwarfRegNum(ARM::SP
, true);
202 MAI
->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg
, 0));
207 static MCStreamer
*createELFStreamer(const Triple
&T
, MCContext
&Ctx
,
208 std::unique_ptr
<MCAsmBackend
> &&MAB
,
209 std::unique_ptr
<MCObjectWriter
> &&OW
,
210 std::unique_ptr
<MCCodeEmitter
> &&Emitter
,
212 return createARMELFStreamer(
213 Ctx
, std::move(MAB
), std::move(OW
), std::move(Emitter
), false,
214 (T
.getArch() == Triple::thumb
|| T
.getArch() == Triple::thumbeb
));
218 createARMMachOStreamer(MCContext
&Ctx
, std::unique_ptr
<MCAsmBackend
> &&MAB
,
219 std::unique_ptr
<MCObjectWriter
> &&OW
,
220 std::unique_ptr
<MCCodeEmitter
> &&Emitter
, bool RelaxAll
,
221 bool DWARFMustBeAtTheEnd
) {
222 return createMachOStreamer(Ctx
, std::move(MAB
), std::move(OW
),
223 std::move(Emitter
), false, DWARFMustBeAtTheEnd
);
226 static MCInstPrinter
*createARMMCInstPrinter(const Triple
&T
,
227 unsigned SyntaxVariant
,
228 const MCAsmInfo
&MAI
,
229 const MCInstrInfo
&MII
,
230 const MCRegisterInfo
&MRI
) {
231 if (SyntaxVariant
== 0)
232 return new ARMInstPrinter(MAI
, MII
, MRI
);
236 static MCRelocationInfo
*createARMMCRelocationInfo(const Triple
&TT
,
238 if (TT
.isOSBinFormatMachO())
239 return createARMMachORelocationInfo(Ctx
);
240 // Default to the stock relocation info.
241 return llvm::createMCRelocationInfo(TT
, Ctx
);
246 class ARMMCInstrAnalysis
: public MCInstrAnalysis
{
248 ARMMCInstrAnalysis(const MCInstrInfo
*Info
) : MCInstrAnalysis(Info
) {}
250 bool isUnconditionalBranch(const MCInst
&Inst
) const override
{
251 // BCCs with the "always" predicate are unconditional branches.
252 if (Inst
.getOpcode() == ARM::Bcc
&& Inst
.getOperand(1).getImm()==ARMCC::AL
)
254 return MCInstrAnalysis::isUnconditionalBranch(Inst
);
257 bool isConditionalBranch(const MCInst
&Inst
) const override
{
258 // BCCs with the "always" predicate are unconditional branches.
259 if (Inst
.getOpcode() == ARM::Bcc
&& Inst
.getOperand(1).getImm()==ARMCC::AL
)
261 return MCInstrAnalysis::isConditionalBranch(Inst
);
264 bool evaluateBranch(const MCInst
&Inst
, uint64_t Addr
,
265 uint64_t Size
, uint64_t &Target
) const override
{
266 // We only handle PCRel branches for now.
267 if (Info
->get(Inst
.getOpcode()).OpInfo
[0].OperandType
!=MCOI::OPERAND_PCREL
)
270 int64_t Imm
= Inst
.getOperand(0).getImm();
271 Target
= Addr
+Imm
+8; // In ARM mode the PC is always off by 8 bytes.
276 class ThumbMCInstrAnalysis
: public ARMMCInstrAnalysis
{
278 ThumbMCInstrAnalysis(const MCInstrInfo
*Info
) : ARMMCInstrAnalysis(Info
) {}
280 bool evaluateBranch(const MCInst
&Inst
, uint64_t Addr
, uint64_t Size
,
281 uint64_t &Target
) const override
{
283 switch (Inst
.getOpcode()) {
288 case ARM::t2LEUpdate
:
296 // We only handle PCRel branches for now.
297 if (Info
->get(Inst
.getOpcode()).OpInfo
[OpId
].OperandType
!=
301 // In Thumb mode the PC is always off by 4 bytes.
302 Target
= Addr
+ Inst
.getOperand(OpId
).getImm() + 4;
309 static MCInstrAnalysis
*createARMMCInstrAnalysis(const MCInstrInfo
*Info
) {
310 return new ARMMCInstrAnalysis(Info
);
313 static MCInstrAnalysis
*createThumbMCInstrAnalysis(const MCInstrInfo
*Info
) {
314 return new ThumbMCInstrAnalysis(Info
);
317 // Force static initialization.
318 extern "C" void LLVMInitializeARMTargetMC() {
319 for (Target
*T
: {&getTheARMLETarget(), &getTheARMBETarget(),
320 &getTheThumbLETarget(), &getTheThumbBETarget()}) {
321 // Register the MC asm info.
322 RegisterMCAsmInfoFn
X(*T
, createARMMCAsmInfo
);
324 // Register the MC instruction info.
325 TargetRegistry::RegisterMCInstrInfo(*T
, createARMMCInstrInfo
);
327 // Register the MC register info.
328 TargetRegistry::RegisterMCRegInfo(*T
, createARMMCRegisterInfo
);
330 // Register the MC subtarget info.
331 TargetRegistry::RegisterMCSubtargetInfo(*T
,
332 ARM_MC::createARMMCSubtargetInfo
);
334 TargetRegistry::RegisterELFStreamer(*T
, createELFStreamer
);
335 TargetRegistry::RegisterCOFFStreamer(*T
, createARMWinCOFFStreamer
);
336 TargetRegistry::RegisterMachOStreamer(*T
, createARMMachOStreamer
);
338 // Register the obj target streamer.
339 TargetRegistry::RegisterObjectTargetStreamer(*T
,
340 createARMObjectTargetStreamer
);
342 // Register the asm streamer.
343 TargetRegistry::RegisterAsmTargetStreamer(*T
, createARMTargetAsmStreamer
);
345 // Register the null TargetStreamer.
346 TargetRegistry::RegisterNullTargetStreamer(*T
, createARMNullTargetStreamer
);
348 // Register the MCInstPrinter.
349 TargetRegistry::RegisterMCInstPrinter(*T
, createARMMCInstPrinter
);
351 // Register the MC relocation info.
352 TargetRegistry::RegisterMCRelocationInfo(*T
, createARMMCRelocationInfo
);
355 // Register the MC instruction analyzer.
356 for (Target
*T
: {&getTheARMLETarget(), &getTheARMBETarget()})
357 TargetRegistry::RegisterMCInstrAnalysis(*T
, createARMMCInstrAnalysis
);
358 for (Target
*T
: {&getTheThumbLETarget(), &getTheThumbBETarget()})
359 TargetRegistry::RegisterMCInstrAnalysis(*T
, createThumbMCInstrAnalysis
);
361 for (Target
*T
: {&getTheARMLETarget(), &getTheThumbLETarget()}) {
362 TargetRegistry::RegisterMCCodeEmitter(*T
, createARMLEMCCodeEmitter
);
363 TargetRegistry::RegisterMCAsmBackend(*T
, createARMLEAsmBackend
);
365 for (Target
*T
: {&getTheARMBETarget(), &getTheThumbBETarget()}) {
366 TargetRegistry::RegisterMCCodeEmitter(*T
, createARMBEMCCodeEmitter
);
367 TargetRegistry::RegisterMCAsmBackend(*T
, createARMBEAsmBackend
);