LLVM API Documentation
00001 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides ARM specific target descriptions. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "ARMBaseInfo.h" 00015 #include "ARMMCAsmInfo.h" 00016 #include "ARMMCTargetDesc.h" 00017 #include "InstPrinter/ARMInstPrinter.h" 00018 #include "llvm/ADT/Triple.h" 00019 #include "llvm/MC/MCCodeGenInfo.h" 00020 #include "llvm/MC/MCELFStreamer.h" 00021 #include "llvm/MC/MCInstrAnalysis.h" 00022 #include "llvm/MC/MCInstrInfo.h" 00023 #include "llvm/MC/MCRegisterInfo.h" 00024 #include "llvm/MC/MCStreamer.h" 00025 #include "llvm/MC/MCSubtargetInfo.h" 00026 #include "llvm/Support/ErrorHandling.h" 00027 #include "llvm/Support/TargetRegistry.h" 00028 00029 using namespace llvm; 00030 00031 #define GET_REGINFO_MC_DESC 00032 #include "ARMGenRegisterInfo.inc" 00033 00034 static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, 00035 std::string &Info) { 00036 if (STI.getFeatureBits() & llvm::ARM::HasV7Ops && 00037 (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) && 00038 (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) && 00039 // Checks for the deprecated CP15ISB encoding: 00040 // mcr p15, #0, rX, c7, c5, #4 00041 (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) { 00042 if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) { 00043 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) { 00044 Info = "deprecated since v7, use 'isb'"; 00045 return true; 00046 } 00047 00048 // Checks for the deprecated CP15DSB encoding: 00049 // mcr p15, #0, rX, c7, c10, #4 00050 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) { 00051 Info = "deprecated since v7, use 'dsb'"; 00052 return true; 00053 } 00054 } 00055 // Checks for the deprecated CP15DMB encoding: 00056 // mcr p15, #0, rX, c7, c10, #5 00057 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 && 00058 (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) { 00059 Info = "deprecated since v7, use 'dmb'"; 00060 return true; 00061 } 00062 } 00063 return false; 00064 } 00065 00066 static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, 00067 std::string &Info) { 00068 if (STI.getFeatureBits() & llvm::ARM::HasV8Ops && 00069 MI.getOperand(1).isImm() && MI.getOperand(1).getImm() != 8) { 00070 Info = "applying IT instruction to more than one subsequent instruction is deprecated"; 00071 return true; 00072 } 00073 00074 return false; 00075 } 00076 00077 #define GET_INSTRINFO_MC_DESC 00078 #include "ARMGenInstrInfo.inc" 00079 00080 #define GET_SUBTARGETINFO_MC_DESC 00081 #include "ARMGenSubtargetInfo.inc" 00082 00083 00084 std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { 00085 Triple triple(TT); 00086 00087 bool isThumb = triple.getArch() == Triple::thumb || 00088 triple.getArch() == Triple::thumbeb; 00089 00090 bool NoCPU = CPU == "generic" || CPU.empty(); 00091 std::string ARMArchFeature; 00092 switch (triple.getSubArch()) { 00093 default: 00094 llvm_unreachable("invalid sub-architecture for ARM"); 00095 case Triple::ARMSubArch_v8: 00096 if (NoCPU) 00097 // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2, 00098 // FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, 00099 // FeatureT2XtPk, FeatureCrypto, FeatureCRC 00100 ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm," 00101 "+trustzone,+t2xtpk,+crypto,+crc"; 00102 else 00103 // Use CPU to figure out the exact features 00104 ARMArchFeature = "+v8"; 00105 break; 00106 case Triple::ARMSubArch_v7m: 00107 isThumb = true; 00108 if (NoCPU) 00109 // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass 00110 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass"; 00111 else 00112 // Use CPU to figure out the exact features. 00113 ARMArchFeature = "+v7"; 00114 break; 00115 case Triple::ARMSubArch_v7em: 00116 if (NoCPU) 00117 // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, 00118 // FeatureT2XtPk, FeatureMClass 00119 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass"; 00120 else 00121 // Use CPU to figure out the exact features. 00122 ARMArchFeature = "+v7"; 00123 break; 00124 case Triple::ARMSubArch_v7s: 00125 if (NoCPU) 00126 // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS 00127 // Swift 00128 ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+ras"; 00129 else 00130 // Use CPU to figure out the exact features. 00131 ARMArchFeature = "+v7"; 00132 break; 00133 case Triple::ARMSubArch_v7: 00134 // v7 CPUs have lots of different feature sets. If no CPU is specified, 00135 // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return 00136 // the "minimum" feature set and use CPU string to figure out the exact 00137 // features. 00138 if (NoCPU) 00139 // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk 00140 ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; 00141 else 00142 // Use CPU to figure out the exact features. 00143 ARMArchFeature = "+v7"; 00144 break; 00145 case Triple::ARMSubArch_v6t2: 00146 ARMArchFeature = "+v6t2"; 00147 break; 00148 case Triple::ARMSubArch_v6m: 00149 isThumb = true; 00150 if (NoCPU) 00151 // v6m: FeatureNoARM, FeatureMClass 00152 ARMArchFeature = "+v6m,+noarm,+mclass"; 00153 else 00154 ARMArchFeature = "+v6"; 00155 break; 00156 case Triple::ARMSubArch_v6: 00157 ARMArchFeature = "+v6"; 00158 break; 00159 case Triple::ARMSubArch_v5te: 00160 ARMArchFeature = "+v5te"; 00161 break; 00162 case Triple::ARMSubArch_v5: 00163 ARMArchFeature = "+v5t"; 00164 break; 00165 case Triple::ARMSubArch_v4t: 00166 ARMArchFeature = "+v4t"; 00167 break; 00168 case Triple::NoSubArch: 00169 break; 00170 } 00171 00172 if (isThumb) { 00173 if (ARMArchFeature.empty()) 00174 ARMArchFeature = "+thumb-mode"; 00175 else 00176 ARMArchFeature += ",+thumb-mode"; 00177 } 00178 00179 if (triple.isOSNaCl()) { 00180 if (ARMArchFeature.empty()) 00181 ARMArchFeature = "+nacl-trap"; 00182 else 00183 ARMArchFeature += ",+nacl-trap"; 00184 } 00185 00186 return ARMArchFeature; 00187 } 00188 00189 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, 00190 StringRef FS) { 00191 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 00192 if (!FS.empty()) { 00193 if (!ArchFS.empty()) 00194 ArchFS = ArchFS + "," + FS.str(); 00195 else 00196 ArchFS = FS; 00197 } 00198 00199 MCSubtargetInfo *X = new MCSubtargetInfo(); 00200 InitARMMCSubtargetInfo(X, TT, CPU, ArchFS); 00201 return X; 00202 } 00203 00204 static MCInstrInfo *createARMMCInstrInfo() { 00205 MCInstrInfo *X = new MCInstrInfo(); 00206 InitARMMCInstrInfo(X); 00207 return X; 00208 } 00209 00210 static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { 00211 MCRegisterInfo *X = new MCRegisterInfo(); 00212 InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); 00213 return X; 00214 } 00215 00216 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { 00217 Triple TheTriple(TT); 00218 00219 MCAsmInfo *MAI; 00220 switch (TheTriple.getOS()) { 00221 case llvm::Triple::Darwin: 00222 case llvm::Triple::IOS: 00223 case llvm::Triple::MacOSX: 00224 MAI = new ARMMCAsmInfoDarwin(TT); 00225 break; 00226 case llvm::Triple::Win32: 00227 switch (TheTriple.getEnvironment()) { 00228 case llvm::Triple::Itanium: 00229 MAI = new ARMCOFFMCAsmInfoGNU(); 00230 break; 00231 case llvm::Triple::MSVC: 00232 MAI = new ARMCOFFMCAsmInfoMicrosoft(); 00233 break; 00234 default: 00235 llvm_unreachable("invalid environment"); 00236 } 00237 break; 00238 default: 00239 if (TheTriple.isOSBinFormatMachO()) 00240 MAI = new ARMMCAsmInfoDarwin(TT); 00241 else 00242 MAI = new ARMELFMCAsmInfo(TT); 00243 break; 00244 } 00245 00246 unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); 00247 MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0)); 00248 00249 return MAI; 00250 } 00251 00252 static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, 00253 CodeModel::Model CM, 00254 CodeGenOpt::Level OL) { 00255 MCCodeGenInfo *X = new MCCodeGenInfo(); 00256 if (RM == Reloc::Default) { 00257 Triple TheTriple(TT); 00258 // Default relocation model on Darwin is PIC, not DynamicNoPIC. 00259 RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; 00260 } 00261 X->InitMCCodeGenInfo(RM, CM, OL); 00262 return X; 00263 } 00264 00265 // This is duplicated code. Refactor this. 00266 static MCStreamer *createMCStreamer(const Target &T, StringRef TT, 00267 MCContext &Ctx, MCAsmBackend &MAB, 00268 raw_ostream &OS, 00269 MCCodeEmitter *Emitter, 00270 const MCSubtargetInfo &STI, 00271 bool RelaxAll, 00272 bool NoExecStack) { 00273 Triple TheTriple(TT); 00274 00275 switch (TheTriple.getObjectFormat()) { 00276 default: llvm_unreachable("unsupported object format"); 00277 case Triple::MachO: { 00278 MCStreamer *S = createMachOStreamer(Ctx, MAB, OS, Emitter, false); 00279 new ARMTargetStreamer(*S); 00280 return S; 00281 } 00282 case Triple::COFF: 00283 assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported"); 00284 return createARMWinCOFFStreamer(Ctx, MAB, *Emitter, OS); 00285 case Triple::ELF: 00286 return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack, 00287 TheTriple.getArch() == Triple::thumb); 00288 } 00289 } 00290 00291 static MCInstPrinter *createARMMCInstPrinter(const Target &T, 00292 unsigned SyntaxVariant, 00293 const MCAsmInfo &MAI, 00294 const MCInstrInfo &MII, 00295 const MCRegisterInfo &MRI, 00296 const MCSubtargetInfo &STI) { 00297 if (SyntaxVariant == 0) 00298 return new ARMInstPrinter(MAI, MII, MRI, STI); 00299 return nullptr; 00300 } 00301 00302 static MCRelocationInfo *createARMMCRelocationInfo(StringRef TT, 00303 MCContext &Ctx) { 00304 Triple TheTriple(TT); 00305 if (TheTriple.isOSBinFormatMachO()) 00306 return createARMMachORelocationInfo(Ctx); 00307 // Default to the stock relocation info. 00308 return llvm::createMCRelocationInfo(TT, Ctx); 00309 } 00310 00311 namespace { 00312 00313 class ARMMCInstrAnalysis : public MCInstrAnalysis { 00314 public: 00315 ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 00316 00317 bool isUnconditionalBranch(const MCInst &Inst) const override { 00318 // BCCs with the "always" predicate are unconditional branches. 00319 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 00320 return true; 00321 return MCInstrAnalysis::isUnconditionalBranch(Inst); 00322 } 00323 00324 bool isConditionalBranch(const MCInst &Inst) const override { 00325 // BCCs with the "always" predicate are unconditional branches. 00326 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 00327 return false; 00328 return MCInstrAnalysis::isConditionalBranch(Inst); 00329 } 00330 00331 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 00332 uint64_t Size, uint64_t &Target) const override { 00333 // We only handle PCRel branches for now. 00334 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) 00335 return false; 00336 00337 int64_t Imm = Inst.getOperand(0).getImm(); 00338 // FIXME: This is not right for thumb. 00339 Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 00340 return true; 00341 } 00342 }; 00343 00344 } 00345 00346 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 00347 return new ARMMCInstrAnalysis(Info); 00348 } 00349 00350 // Force static initialization. 00351 extern "C" void LLVMInitializeARMTargetMC() { 00352 // Register the MC asm info. 00353 RegisterMCAsmInfoFn X(TheARMLETarget, createARMMCAsmInfo); 00354 RegisterMCAsmInfoFn Y(TheARMBETarget, createARMMCAsmInfo); 00355 RegisterMCAsmInfoFn A(TheThumbLETarget, createARMMCAsmInfo); 00356 RegisterMCAsmInfoFn B(TheThumbBETarget, createARMMCAsmInfo); 00357 00358 // Register the MC codegen info. 00359 TargetRegistry::RegisterMCCodeGenInfo(TheARMLETarget, createARMMCCodeGenInfo); 00360 TargetRegistry::RegisterMCCodeGenInfo(TheARMBETarget, createARMMCCodeGenInfo); 00361 TargetRegistry::RegisterMCCodeGenInfo(TheThumbLETarget, 00362 createARMMCCodeGenInfo); 00363 TargetRegistry::RegisterMCCodeGenInfo(TheThumbBETarget, 00364 createARMMCCodeGenInfo); 00365 00366 // Register the MC instruction info. 00367 TargetRegistry::RegisterMCInstrInfo(TheARMLETarget, createARMMCInstrInfo); 00368 TargetRegistry::RegisterMCInstrInfo(TheARMBETarget, createARMMCInstrInfo); 00369 TargetRegistry::RegisterMCInstrInfo(TheThumbLETarget, createARMMCInstrInfo); 00370 TargetRegistry::RegisterMCInstrInfo(TheThumbBETarget, createARMMCInstrInfo); 00371 00372 // Register the MC register info. 00373 TargetRegistry::RegisterMCRegInfo(TheARMLETarget, createARMMCRegisterInfo); 00374 TargetRegistry::RegisterMCRegInfo(TheARMBETarget, createARMMCRegisterInfo); 00375 TargetRegistry::RegisterMCRegInfo(TheThumbLETarget, createARMMCRegisterInfo); 00376 TargetRegistry::RegisterMCRegInfo(TheThumbBETarget, createARMMCRegisterInfo); 00377 00378 // Register the MC subtarget info. 00379 TargetRegistry::RegisterMCSubtargetInfo(TheARMLETarget, 00380 ARM_MC::createARMMCSubtargetInfo); 00381 TargetRegistry::RegisterMCSubtargetInfo(TheARMBETarget, 00382 ARM_MC::createARMMCSubtargetInfo); 00383 TargetRegistry::RegisterMCSubtargetInfo(TheThumbLETarget, 00384 ARM_MC::createARMMCSubtargetInfo); 00385 TargetRegistry::RegisterMCSubtargetInfo(TheThumbBETarget, 00386 ARM_MC::createARMMCSubtargetInfo); 00387 00388 // Register the MC instruction analyzer. 00389 TargetRegistry::RegisterMCInstrAnalysis(TheARMLETarget, 00390 createARMMCInstrAnalysis); 00391 TargetRegistry::RegisterMCInstrAnalysis(TheARMBETarget, 00392 createARMMCInstrAnalysis); 00393 TargetRegistry::RegisterMCInstrAnalysis(TheThumbLETarget, 00394 createARMMCInstrAnalysis); 00395 TargetRegistry::RegisterMCInstrAnalysis(TheThumbBETarget, 00396 createARMMCInstrAnalysis); 00397 00398 // Register the MC Code Emitter 00399 TargetRegistry::RegisterMCCodeEmitter(TheARMLETarget, 00400 createARMLEMCCodeEmitter); 00401 TargetRegistry::RegisterMCCodeEmitter(TheARMBETarget, 00402 createARMBEMCCodeEmitter); 00403 TargetRegistry::RegisterMCCodeEmitter(TheThumbLETarget, 00404 createARMLEMCCodeEmitter); 00405 TargetRegistry::RegisterMCCodeEmitter(TheThumbBETarget, 00406 createARMBEMCCodeEmitter); 00407 00408 // Register the asm backend. 00409 TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend); 00410 TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend); 00411 TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget, 00412 createThumbLEAsmBackend); 00413 TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget, 00414 createThumbBEAsmBackend); 00415 00416 // Register the object streamer. 00417 TargetRegistry::RegisterMCObjectStreamer(TheARMLETarget, createMCStreamer); 00418 TargetRegistry::RegisterMCObjectStreamer(TheARMBETarget, createMCStreamer); 00419 TargetRegistry::RegisterMCObjectStreamer(TheThumbLETarget, createMCStreamer); 00420 TargetRegistry::RegisterMCObjectStreamer(TheThumbBETarget, createMCStreamer); 00421 00422 // Register the asm streamer. 00423 TargetRegistry::RegisterAsmStreamer(TheARMLETarget, createMCAsmStreamer); 00424 TargetRegistry::RegisterAsmStreamer(TheARMBETarget, createMCAsmStreamer); 00425 TargetRegistry::RegisterAsmStreamer(TheThumbLETarget, createMCAsmStreamer); 00426 TargetRegistry::RegisterAsmStreamer(TheThumbBETarget, createMCAsmStreamer); 00427 00428 // Register the null streamer. 00429 TargetRegistry::RegisterNullStreamer(TheARMLETarget, createARMNullStreamer); 00430 TargetRegistry::RegisterNullStreamer(TheARMBETarget, createARMNullStreamer); 00431 TargetRegistry::RegisterNullStreamer(TheThumbLETarget, createARMNullStreamer); 00432 TargetRegistry::RegisterNullStreamer(TheThumbBETarget, createARMNullStreamer); 00433 00434 // Register the MCInstPrinter. 00435 TargetRegistry::RegisterMCInstPrinter(TheARMLETarget, createARMMCInstPrinter); 00436 TargetRegistry::RegisterMCInstPrinter(TheARMBETarget, createARMMCInstPrinter); 00437 TargetRegistry::RegisterMCInstPrinter(TheThumbLETarget, 00438 createARMMCInstPrinter); 00439 TargetRegistry::RegisterMCInstPrinter(TheThumbBETarget, 00440 createARMMCInstPrinter); 00441 00442 // Register the MC relocation info. 00443 TargetRegistry::RegisterMCRelocationInfo(TheARMLETarget, 00444 createARMMCRelocationInfo); 00445 TargetRegistry::RegisterMCRelocationInfo(TheARMBETarget, 00446 createARMMCRelocationInfo); 00447 TargetRegistry::RegisterMCRelocationInfo(TheThumbLETarget, 00448 createARMMCRelocationInfo); 00449 TargetRegistry::RegisterMCRelocationInfo(TheThumbBETarget, 00450 createARMMCRelocationInfo); 00451 }