1 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file provides ARM specific target descriptions. 11 // 12 //===----------------------------------------------------------------------===// 13 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" 27 28 using namespace llvm; 29 30 #define GET_REGINFO_MC_DESC 31 #include "ARMGenRegisterInfo.inc" 32 33 static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, 34 std::string &Info) { 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'"; 44 return true; 45 } 46 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'"; 51 return true; 52 } 53 } 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'"; 59 return true; 60 } 61 } 62 return false; 63 } 64 65 static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, 66 std::string &Info) { 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"; 70 return true; 71 } 72 73 return false; 74 } 75 76 #define GET_INSTRINFO_MC_DESC 77 #include "ARMGenInstrInfo.inc" 78 79 #define GET_SUBTARGETINFO_MC_DESC 80 #include "ARMGenSubtargetInfo.inc" 81 82 83 std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { 84 Triple triple(TT); 85 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(); 89 unsigned Idx = 0; 90 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") 95 Idx = 4; 96 else if (Len >= 7 && TT.substr(0, 6) == "armebv") 97 Idx = 6; 98 else if (Len >= 7 && TT.substr(0, 6) == "thumbv") 99 Idx = 6; 100 else if (Len >= 9 && TT.substr(0, 8) == "thumbebv") 101 Idx = 8; 102 103 bool NoCPU = CPU == "generic" || CPU.empty(); 104 std::string ARMArchFeature; 105 if (Idx) { 106 unsigned SubVer = TT[Idx]; 107 if (SubVer == '8') { 108 if (NoCPU) 109 // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2, 110 // FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, 111 // FeatureT2XtPk, FeatureCrypto, FeatureCRC 112 ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm," 113 "+trustzone,+t2xtpk,+crypto,+crc"; 114 else 115 // Use CPU to figure out the exact features 116 ARMArchFeature = "+v8"; 117 } else if (SubVer == '7') { 118 if (Len >= Idx+2 && TT[Idx+1] == 'm') { 119 isThumb = true; 120 if (NoCPU) 121 // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass 122 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass"; 123 else 124 // Use CPU to figure out the exact features. 125 ARMArchFeature = "+v7"; 126 } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { 127 if (NoCPU) 128 // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, 129 // FeatureT2XtPk, FeatureMClass 130 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass"; 131 else 132 // Use CPU to figure out the exact features. 133 ARMArchFeature = "+v7"; 134 } else if (Len >= Idx+2 && TT[Idx+1] == 's') { 135 if (NoCPU) 136 // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS 137 // Swift 138 ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+ras"; 139 else 140 // Use CPU to figure out the exact features. 141 ARMArchFeature = "+v7"; 142 } else { 143 // v7 CPUs have lots of different feature sets. If no CPU is specified, 144 // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return 145 // the "minimum" feature set and use CPU string to figure out the exact 146 // features. 147 if (NoCPU) 148 // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk 149 ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; 150 else 151 // Use CPU to figure out the exact features. 152 ARMArchFeature = "+v7"; 153 } 154 } else if (SubVer == '6') { 155 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') 156 ARMArchFeature = "+v6t2"; 157 else if (Len >= Idx+2 && TT[Idx+1] == 'm') { 158 isThumb = true; 159 if (NoCPU) 160 // v6m: FeatureNoARM, FeatureMClass 161 ARMArchFeature = "+v6m,+noarm,+mclass"; 162 else 163 ARMArchFeature = "+v6"; 164 } else 165 ARMArchFeature = "+v6"; 166 } else if (SubVer == '5') { 167 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') 168 ARMArchFeature = "+v5te"; 169 else 170 ARMArchFeature = "+v5t"; 171 } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't') 172 ARMArchFeature = "+v4t"; 173 } 174 175 if (isThumb) { 176 if (ARMArchFeature.empty()) 177 ARMArchFeature = "+thumb-mode"; 178 else 179 ARMArchFeature += ",+thumb-mode"; 180 } 181 182 if (triple.isOSNaCl()) { 183 if (ARMArchFeature.empty()) 184 ARMArchFeature = "+nacl-trap"; 185 else 186 ARMArchFeature += ",+nacl-trap"; 187 } 188 189 return ARMArchFeature; 190 } 191 192 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, 193 StringRef FS) { 194 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 195 if (!FS.empty()) { 196 if (!ArchFS.empty()) 197 ArchFS = ArchFS + "," + FS.str(); 198 else 199 ArchFS = FS; 200 } 201 202 MCSubtargetInfo *X = new MCSubtargetInfo(); 203 InitARMMCSubtargetInfo(X, TT, CPU, ArchFS); 204 return X; 205 } 206 207 static MCInstrInfo *createARMMCInstrInfo() { 208 MCInstrInfo *X = new MCInstrInfo(); 209 InitARMMCInstrInfo(X); 210 return X; 211 } 212 213 static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { 214 MCRegisterInfo *X = new MCRegisterInfo(); 215 InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); 216 return X; 217 } 218 219 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { 220 Triple TheTriple(TT); 221 222 MCAsmInfo *MAI; 223 switch (TheTriple.getOS()) { 224 case llvm::Triple::Darwin: 225 case llvm::Triple::IOS: 226 case llvm::Triple::MacOSX: 227 MAI = new ARMMCAsmInfoDarwin(TT); 228 break; 229 case llvm::Triple::Win32: 230 switch (TheTriple.getEnvironment()) { 231 case llvm::Triple::Itanium: 232 MAI = new ARMCOFFMCAsmInfoGNU(); 233 break; 234 case llvm::Triple::MSVC: 235 MAI = new ARMCOFFMCAsmInfoMicrosoft(); 236 break; 237 default: 238 llvm_unreachable("invalid environment"); 239 } 240 break; 241 default: 242 if (TheTriple.isOSBinFormatMachO()) 243 MAI = new ARMMCAsmInfoDarwin(TT); 244 else 245 MAI = new ARMELFMCAsmInfo(TT); 246 break; 247 } 248 249 unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); 250 MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(0, Reg, 0)); 251 252 return MAI; 253 } 254 255 static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, 256 CodeModel::Model CM, 257 CodeGenOpt::Level OL) { 258 MCCodeGenInfo *X = new MCCodeGenInfo(); 259 if (RM == Reloc::Default) { 260 Triple TheTriple(TT); 261 // Default relocation model on Darwin is PIC, not DynamicNoPIC. 262 RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; 263 } 264 X->InitMCCodeGenInfo(RM, CM, OL); 265 return X; 266 } 267 268 // This is duplicated code. Refactor this. 269 static MCStreamer *createMCStreamer(const Target &T, StringRef TT, 270 MCContext &Ctx, MCAsmBackend &MAB, 271 raw_ostream &OS, 272 MCCodeEmitter *Emitter, 273 const MCSubtargetInfo &STI, 274 bool RelaxAll, 275 bool NoExecStack) { 276 Triple TheTriple(TT); 277 278 if (TheTriple.isOSBinFormatMachO()) { 279 MCStreamer *S = createMachOStreamer(Ctx, MAB, OS, Emitter, false); 280 new ARMTargetStreamer(*S); 281 return S; 282 } 283 284 if (TheTriple.isOSWindows()) { 285 llvm_unreachable("ARM does not support Windows COFF format"); 286 } 287 288 return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack, 289 TheTriple.getArch() == Triple::thumb); 290 } 291 292 static MCInstPrinter *createARMMCInstPrinter(const Target &T, 293 unsigned SyntaxVariant, 294 const MCAsmInfo &MAI, 295 const MCInstrInfo &MII, 296 const MCRegisterInfo &MRI, 297 const MCSubtargetInfo &STI) { 298 if (SyntaxVariant == 0) 299 return new ARMInstPrinter(MAI, MII, MRI, STI); 300 return 0; 301 } 302 303 static MCRelocationInfo *createARMMCRelocationInfo(StringRef TT, 304 MCContext &Ctx) { 305 Triple TheTriple(TT); 306 if (TheTriple.isOSBinFormatMachO()) 307 return createARMMachORelocationInfo(Ctx); 308 // Default to the stock relocation info. 309 return llvm::createMCRelocationInfo(TT, Ctx); 310 } 311 312 namespace { 313 314 class ARMMCInstrAnalysis : public MCInstrAnalysis { 315 public: 316 ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 317 318 bool isUnconditionalBranch(const MCInst &Inst) const override { 319 // BCCs with the "always" predicate are unconditional branches. 320 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 321 return true; 322 return MCInstrAnalysis::isUnconditionalBranch(Inst); 323 } 324 325 bool isConditionalBranch(const MCInst &Inst) const override { 326 // BCCs with the "always" predicate are unconditional branches. 327 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 328 return false; 329 return MCInstrAnalysis::isConditionalBranch(Inst); 330 } 331 332 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 333 uint64_t Size, uint64_t &Target) const override { 334 // We only handle PCRel branches for now. 335 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) 336 return false; 337 338 int64_t Imm = Inst.getOperand(0).getImm(); 339 // FIXME: This is not right for thumb. 340 Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 341 return true; 342 } 343 }; 344 345 } 346 347 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 348 return new ARMMCInstrAnalysis(Info); 349 } 350 351 // Force static initialization. 352 extern "C" void LLVMInitializeARMTargetMC() { 353 // Register the MC asm info. 354 RegisterMCAsmInfoFn X(TheARMLETarget, createARMMCAsmInfo); 355 RegisterMCAsmInfoFn Y(TheARMBETarget, createARMMCAsmInfo); 356 RegisterMCAsmInfoFn A(TheThumbLETarget, createARMMCAsmInfo); 357 RegisterMCAsmInfoFn B(TheThumbBETarget, createARMMCAsmInfo); 358 359 // Register the MC codegen info. 360 TargetRegistry::RegisterMCCodeGenInfo(TheARMLETarget, createARMMCCodeGenInfo); 361 TargetRegistry::RegisterMCCodeGenInfo(TheARMBETarget, createARMMCCodeGenInfo); 362 TargetRegistry::RegisterMCCodeGenInfo(TheThumbLETarget, createARMMCCodeGenInfo); 363 TargetRegistry::RegisterMCCodeGenInfo(TheThumbBETarget, createARMMCCodeGenInfo); 364 365 // Register the MC instruction info. 366 TargetRegistry::RegisterMCInstrInfo(TheARMLETarget, createARMMCInstrInfo); 367 TargetRegistry::RegisterMCInstrInfo(TheARMBETarget, createARMMCInstrInfo); 368 TargetRegistry::RegisterMCInstrInfo(TheThumbLETarget, createARMMCInstrInfo); 369 TargetRegistry::RegisterMCInstrInfo(TheThumbBETarget, createARMMCInstrInfo); 370 371 // Register the MC register info. 372 TargetRegistry::RegisterMCRegInfo(TheARMLETarget, createARMMCRegisterInfo); 373 TargetRegistry::RegisterMCRegInfo(TheARMBETarget, createARMMCRegisterInfo); 374 TargetRegistry::RegisterMCRegInfo(TheThumbLETarget, createARMMCRegisterInfo); 375 TargetRegistry::RegisterMCRegInfo(TheThumbBETarget, createARMMCRegisterInfo); 376 377 // Register the MC subtarget info. 378 TargetRegistry::RegisterMCSubtargetInfo(TheARMLETarget, 379 ARM_MC::createARMMCSubtargetInfo); 380 TargetRegistry::RegisterMCSubtargetInfo(TheARMBETarget, 381 ARM_MC::createARMMCSubtargetInfo); 382 TargetRegistry::RegisterMCSubtargetInfo(TheThumbLETarget, 383 ARM_MC::createARMMCSubtargetInfo); 384 TargetRegistry::RegisterMCSubtargetInfo(TheThumbBETarget, 385 ARM_MC::createARMMCSubtargetInfo); 386 387 // Register the MC instruction analyzer. 388 TargetRegistry::RegisterMCInstrAnalysis(TheARMLETarget, 389 createARMMCInstrAnalysis); 390 TargetRegistry::RegisterMCInstrAnalysis(TheARMBETarget, 391 createARMMCInstrAnalysis); 392 TargetRegistry::RegisterMCInstrAnalysis(TheThumbLETarget, 393 createARMMCInstrAnalysis); 394 TargetRegistry::RegisterMCInstrAnalysis(TheThumbBETarget, 395 createARMMCInstrAnalysis); 396 397 // Register the MC Code Emitter 398 TargetRegistry::RegisterMCCodeEmitter(TheARMLETarget, 399 createARMLEMCCodeEmitter); 400 TargetRegistry::RegisterMCCodeEmitter(TheARMBETarget, 401 createARMBEMCCodeEmitter); 402 TargetRegistry::RegisterMCCodeEmitter(TheThumbLETarget, 403 createARMLEMCCodeEmitter); 404 TargetRegistry::RegisterMCCodeEmitter(TheThumbBETarget, 405 createARMBEMCCodeEmitter); 406 407 // Register the asm backend. 408 TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend); 409 TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend); 410 TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget, 411 createThumbLEAsmBackend); 412 TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget, 413 createThumbBEAsmBackend); 414 415 // Register the object streamer. 416 TargetRegistry::RegisterMCObjectStreamer(TheARMLETarget, createMCStreamer); 417 TargetRegistry::RegisterMCObjectStreamer(TheARMBETarget, createMCStreamer); 418 TargetRegistry::RegisterMCObjectStreamer(TheThumbLETarget, createMCStreamer); 419 TargetRegistry::RegisterMCObjectStreamer(TheThumbBETarget, createMCStreamer); 420 421 // Register the asm streamer. 422 TargetRegistry::RegisterAsmStreamer(TheARMLETarget, createMCAsmStreamer); 423 TargetRegistry::RegisterAsmStreamer(TheARMBETarget, createMCAsmStreamer); 424 TargetRegistry::RegisterAsmStreamer(TheThumbLETarget, createMCAsmStreamer); 425 TargetRegistry::RegisterAsmStreamer(TheThumbBETarget, createMCAsmStreamer); 426 427 // Register the MCInstPrinter. 428 TargetRegistry::RegisterMCInstPrinter(TheARMLETarget, createARMMCInstPrinter); 429 TargetRegistry::RegisterMCInstPrinter(TheARMBETarget, createARMMCInstPrinter); 430 TargetRegistry::RegisterMCInstPrinter(TheThumbLETarget, 431 createARMMCInstPrinter); 432 TargetRegistry::RegisterMCInstPrinter(TheThumbBETarget, 433 createARMMCInstPrinter); 434 435 // Register the MC relocation info. 436 TargetRegistry::RegisterMCRelocationInfo(TheARMLETarget, 437 createARMMCRelocationInfo); 438 TargetRegistry::RegisterMCRelocationInfo(TheARMBETarget, 439 createARMMCRelocationInfo); 440 TargetRegistry::RegisterMCRelocationInfo(TheThumbLETarget, 441 createARMMCRelocationInfo); 442 TargetRegistry::RegisterMCRelocationInfo(TheThumbBETarget, 443 createARMMCRelocationInfo); 444 } 445