1 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides ARM specific target descriptions.
12 //===----------------------------------------------------------------------===//
14 #include "ARMBaseInfo.h"
15 #include "ARMMCAsmInfo.h"
16 #include "ARMMCTargetDesc.h"
17 #include "InstPrinter/ARMInstPrinter.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/MC/MCCodeGenInfo.h"
20 #include "llvm/MC/MCELFStreamer.h"
21 #include "llvm/MC/MCInstrAnalysis.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCRegisterInfo.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/TargetRegistry.h"
30 #define GET_REGINFO_MC_DESC
31 #include "ARMGenRegisterInfo.inc"
33 static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
35 if (STI.getFeatureBits() & llvm::ARM::HasV7Ops &&
36 (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
37 (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
38 // Checks for the deprecated CP15ISB encoding:
39 // mcr p15, #0, rX, c7, c5, #4
40 (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
41 if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
42 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
43 Info = "deprecated since v7, use 'isb'";
47 // Checks for the deprecated CP15DSB encoding:
48 // mcr p15, #0, rX, c7, c10, #4
49 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
50 Info = "deprecated since v7, use 'dsb'";
54 // Checks for the deprecated CP15DMB encoding:
55 // mcr p15, #0, rX, c7, c10, #5
56 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
57 (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
58 Info = "deprecated since v7, use 'dmb'";
65 static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
67 if (STI.getFeatureBits() & llvm::ARM::HasV8Ops &&
68 MI.getOperand(1).isImm() && MI.getOperand(1).getImm() != 8) {
69 Info = "applying IT instruction to more than one subsequent instruction is deprecated";
76 #define GET_INSTRINFO_MC_DESC
77 #include "ARMGenInstrInfo.inc"
79 #define GET_SUBTARGETINFO_MC_DESC
80 #include "ARMGenSubtargetInfo.inc"
83 std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) {
86 // Set the boolean corresponding to the current target triple, or the default
87 // if one cannot be determined, to true.
88 unsigned Len = TT.size();
91 // FIXME: Enhance Triple helper class to extract ARM version.
92 bool isThumb = triple.getArch() == Triple::thumb ||
93 triple.getArch() == Triple::thumbeb;
94 if (Len >= 5 && TT.substr(0, 4) == "armv")
96 else if (Len >= 7 && TT.substr(0, 6) == "armebv")
98 else if (Len >= 7 && TT.substr(0, 6) == "thumbv")
100 else if (Len >= 9 && TT.substr(0, 8) == "thumbebv")
103 bool NoCPU = CPU == "generic" || CPU.empty();
104 std::string ARMArchFeature;
106 unsigned SubVer = TT[Idx];
109 // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2, FeatureMP,
110 // FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, FeatureT2XtPk, FeatureCrypto, FeatureCRC
111 ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm,+trustzone,+t2xtpk,+crypto,+crc";
113 // Use CPU to figure out the exact features
114 ARMArchFeature = "+v8";
115 } else if (SubVer == '7') {
116 if (Len >= Idx+2 && TT[Idx+1] == 'm') {
119 // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass
120 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass";
122 // Use CPU to figure out the exact features.
123 ARMArchFeature = "+v7";
124 } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') {
126 // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2,
127 // FeatureT2XtPk, FeatureMClass
128 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass";
130 // Use CPU to figure out the exact features.
131 ARMArchFeature = "+v7";
132 } else if (Len >= Idx+2 && TT[Idx+1] == 's') {
134 // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS
136 ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+ras";
138 // Use CPU to figure out the exact features.
139 ARMArchFeature = "+v7";
141 // v7 CPUs have lots of different feature sets. If no CPU is specified,
142 // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return
143 // the "minimum" feature set and use CPU string to figure out the exact
146 // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk
147 ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk";
149 // Use CPU to figure out the exact features.
150 ARMArchFeature = "+v7";
152 } else if (SubVer == '6') {
153 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
154 ARMArchFeature = "+v6t2";
155 else if (Len >= Idx+2 && TT[Idx+1] == 'm') {
158 // v6m: FeatureNoARM, FeatureMClass
159 ARMArchFeature = "+v6m,+noarm,+mclass";
161 ARMArchFeature = "+v6";
163 ARMArchFeature = "+v6";
164 } else if (SubVer == '5') {
165 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
166 ARMArchFeature = "+v5te";
168 ARMArchFeature = "+v5t";
169 } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't')
170 ARMArchFeature = "+v4t";
174 if (ARMArchFeature.empty())
175 ARMArchFeature = "+thumb-mode";
177 ARMArchFeature += ",+thumb-mode";
180 if (triple.isOSNaCl()) {
181 if (ARMArchFeature.empty())
182 ARMArchFeature = "+nacl-trap";
184 ARMArchFeature += ",+nacl-trap";
187 return ARMArchFeature;
190 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU,
192 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
195 ArchFS = ArchFS + "," + FS.str();
200 MCSubtargetInfo *X = new MCSubtargetInfo();
201 InitARMMCSubtargetInfo(X, TT, CPU, ArchFS);
205 static MCInstrInfo *createARMMCInstrInfo() {
206 MCInstrInfo *X = new MCInstrInfo();
207 InitARMMCInstrInfo(X);
211 static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
212 MCRegisterInfo *X = new MCRegisterInfo();
213 InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
217 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
218 Triple TheTriple(TT);
221 if (TheTriple.isOSBinFormatMachO())
222 MAI = new ARMMCAsmInfoDarwin(TT);
224 MAI = new ARMELFMCAsmInfo(TT);
226 unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
227 MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(0, Reg, 0));
232 static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM,
234 CodeGenOpt::Level OL) {
235 MCCodeGenInfo *X = new MCCodeGenInfo();
236 if (RM == Reloc::Default) {
237 Triple TheTriple(TT);
238 // Default relocation model on Darwin is PIC, not DynamicNoPIC.
239 RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC;
241 X->InitMCCodeGenInfo(RM, CM, OL);
245 // This is duplicated code. Refactor this.
246 static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
247 MCContext &Ctx, MCAsmBackend &MAB,
249 MCCodeEmitter *Emitter,
250 const MCSubtargetInfo &STI,
253 Triple TheTriple(TT);
255 if (TheTriple.isOSBinFormatMachO()) {
256 MCStreamer *S = createMachOStreamer(Ctx, MAB, OS, Emitter, false);
257 new ARMTargetStreamer(*S);
261 if (TheTriple.isOSWindows()) {
262 llvm_unreachable("ARM does not support Windows COFF format");
265 return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack,
266 TheTriple.getArch() == Triple::thumb);
269 static MCInstPrinter *createARMMCInstPrinter(const Target &T,
270 unsigned SyntaxVariant,
271 const MCAsmInfo &MAI,
272 const MCInstrInfo &MII,
273 const MCRegisterInfo &MRI,
274 const MCSubtargetInfo &STI) {
275 if (SyntaxVariant == 0)
276 return new ARMInstPrinter(MAI, MII, MRI, STI);
280 static MCRelocationInfo *createARMMCRelocationInfo(StringRef TT,
282 Triple TheTriple(TT);
283 if (TheTriple.isOSBinFormatMachO())
284 return createARMMachORelocationInfo(Ctx);
285 // Default to the stock relocation info.
286 return llvm::createMCRelocationInfo(TT, Ctx);
291 class ARMMCInstrAnalysis : public MCInstrAnalysis {
293 ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
295 bool isUnconditionalBranch(const MCInst &Inst) const override {
296 // BCCs with the "always" predicate are unconditional branches.
297 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
299 return MCInstrAnalysis::isUnconditionalBranch(Inst);
302 bool isConditionalBranch(const MCInst &Inst) const override {
303 // BCCs with the "always" predicate are unconditional branches.
304 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
306 return MCInstrAnalysis::isConditionalBranch(Inst);
309 bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
310 uint64_t Size, uint64_t &Target) const override {
311 // We only handle PCRel branches for now.
312 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
315 int64_t Imm = Inst.getOperand(0).getImm();
316 // FIXME: This is not right for thumb.
317 Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes.
324 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
325 return new ARMMCInstrAnalysis(Info);
328 // Force static initialization.
329 extern "C" void LLVMInitializeARMTargetMC() {
330 // Register the MC asm info.
331 RegisterMCAsmInfoFn X(TheARMleTarget, createARMMCAsmInfo);
332 RegisterMCAsmInfoFn Y(TheARMbeTarget, createARMMCAsmInfo);
333 RegisterMCAsmInfoFn A(TheThumbleTarget, createARMMCAsmInfo);
334 RegisterMCAsmInfoFn B(TheThumbbeTarget, createARMMCAsmInfo);
336 // Register the MC codegen info.
337 TargetRegistry::RegisterMCCodeGenInfo(TheARMleTarget, createARMMCCodeGenInfo);
338 TargetRegistry::RegisterMCCodeGenInfo(TheARMbeTarget, createARMMCCodeGenInfo);
339 TargetRegistry::RegisterMCCodeGenInfo(TheThumbleTarget, createARMMCCodeGenInfo);
340 TargetRegistry::RegisterMCCodeGenInfo(TheThumbbeTarget, createARMMCCodeGenInfo);
342 // Register the MC instruction info.
343 TargetRegistry::RegisterMCInstrInfo(TheARMleTarget, createARMMCInstrInfo);
344 TargetRegistry::RegisterMCInstrInfo(TheARMbeTarget, createARMMCInstrInfo);
345 TargetRegistry::RegisterMCInstrInfo(TheThumbleTarget, createARMMCInstrInfo);
346 TargetRegistry::RegisterMCInstrInfo(TheThumbbeTarget, createARMMCInstrInfo);
348 // Register the MC register info.
349 TargetRegistry::RegisterMCRegInfo(TheARMleTarget, createARMMCRegisterInfo);
350 TargetRegistry::RegisterMCRegInfo(TheARMbeTarget, createARMMCRegisterInfo);
351 TargetRegistry::RegisterMCRegInfo(TheThumbleTarget, createARMMCRegisterInfo);
352 TargetRegistry::RegisterMCRegInfo(TheThumbbeTarget, createARMMCRegisterInfo);
354 // Register the MC subtarget info.
355 TargetRegistry::RegisterMCSubtargetInfo(TheARMleTarget,
356 ARM_MC::createARMMCSubtargetInfo);
357 TargetRegistry::RegisterMCSubtargetInfo(TheARMbeTarget,
358 ARM_MC::createARMMCSubtargetInfo);
359 TargetRegistry::RegisterMCSubtargetInfo(TheThumbleTarget,
360 ARM_MC::createARMMCSubtargetInfo);
361 TargetRegistry::RegisterMCSubtargetInfo(TheThumbbeTarget,
362 ARM_MC::createARMMCSubtargetInfo);
364 // Register the MC instruction analyzer.
365 TargetRegistry::RegisterMCInstrAnalysis(TheARMleTarget,
366 createARMMCInstrAnalysis);
367 TargetRegistry::RegisterMCInstrAnalysis(TheARMbeTarget,
368 createARMMCInstrAnalysis);
369 TargetRegistry::RegisterMCInstrAnalysis(TheThumbleTarget,
370 createARMMCInstrAnalysis);
371 TargetRegistry::RegisterMCInstrAnalysis(TheThumbbeTarget,
372 createARMMCInstrAnalysis);
374 // Register the MC Code Emitter
375 TargetRegistry::RegisterMCCodeEmitter(TheARMleTarget,
376 createARMleMCCodeEmitter);
377 TargetRegistry::RegisterMCCodeEmitter(TheARMbeTarget,
378 createARMbeMCCodeEmitter);
379 TargetRegistry::RegisterMCCodeEmitter(TheThumbleTarget,
380 createARMleMCCodeEmitter);
381 TargetRegistry::RegisterMCCodeEmitter(TheThumbbeTarget,
382 createARMbeMCCodeEmitter);
384 // Register the asm backend.
385 TargetRegistry::RegisterMCAsmBackend(TheARMleTarget, createARMleAsmBackend);
386 TargetRegistry::RegisterMCAsmBackend(TheARMbeTarget, createARMbeAsmBackend);
387 TargetRegistry::RegisterMCAsmBackend(TheThumbleTarget,
388 createThumbleAsmBackend);
389 TargetRegistry::RegisterMCAsmBackend(TheThumbbeTarget,
390 createThumbbeAsmBackend);
392 // Register the object streamer.
393 TargetRegistry::RegisterMCObjectStreamer(TheARMleTarget, createMCStreamer);
394 TargetRegistry::RegisterMCObjectStreamer(TheARMbeTarget, createMCStreamer);
395 TargetRegistry::RegisterMCObjectStreamer(TheThumbleTarget, createMCStreamer);
396 TargetRegistry::RegisterMCObjectStreamer(TheThumbbeTarget, createMCStreamer);
398 // Register the asm streamer.
399 TargetRegistry::RegisterAsmStreamer(TheARMleTarget, createMCAsmStreamer);
400 TargetRegistry::RegisterAsmStreamer(TheARMbeTarget, createMCAsmStreamer);
401 TargetRegistry::RegisterAsmStreamer(TheThumbleTarget, createMCAsmStreamer);
402 TargetRegistry::RegisterAsmStreamer(TheThumbbeTarget, createMCAsmStreamer);
404 // Register the MCInstPrinter.
405 TargetRegistry::RegisterMCInstPrinter(TheARMleTarget, createARMMCInstPrinter);
406 TargetRegistry::RegisterMCInstPrinter(TheARMbeTarget, createARMMCInstPrinter);
407 TargetRegistry::RegisterMCInstPrinter(TheThumbleTarget,
408 createARMMCInstPrinter);
409 TargetRegistry::RegisterMCInstPrinter(TheThumbbeTarget,
410 createARMMCInstPrinter);
412 // Register the MC relocation info.
413 TargetRegistry::RegisterMCRelocationInfo(TheARMleTarget,
414 createARMMCRelocationInfo);
415 TargetRegistry::RegisterMCRelocationInfo(TheARMbeTarget,
416 createARMMCRelocationInfo);
417 TargetRegistry::RegisterMCRelocationInfo(TheThumbleTarget,
418 createARMMCRelocationInfo);
419 TargetRegistry::RegisterMCRelocationInfo(TheThumbbeTarget,
420 createARMMCRelocationInfo);