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