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/MCStreamer.h" 25 #include "llvm/MC/MCSubtargetInfo.h" 26 #include "llvm/Support/ErrorHandling.h" 27 #include "llvm/Support/TargetParser.h" 28 #include "llvm/Support/TargetRegistry.h" 29 30 using namespace llvm; 31 32 #define GET_REGINFO_MC_DESC 33 #include "ARMGenRegisterInfo.inc" 34 35 static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 36 std::string &Info) { 37 if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] && 38 (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) && 39 (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) && 40 // Checks for the deprecated CP15ISB encoding: 41 // mcr p15, #0, rX, c7, c5, #4 42 (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) { 43 if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) { 44 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) { 45 Info = "deprecated since v7, use 'isb'"; 46 return true; 47 } 48 49 // Checks for the deprecated CP15DSB encoding: 50 // mcr p15, #0, rX, c7, c10, #4 51 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) { 52 Info = "deprecated since v7, use 'dsb'"; 53 return true; 54 } 55 } 56 // Checks for the deprecated CP15DMB encoding: 57 // mcr p15, #0, rX, c7, c10, #5 58 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 && 59 (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) { 60 Info = "deprecated since v7, use 'dmb'"; 61 return true; 62 } 63 } 64 return false; 65 } 66 67 static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 68 std::string &Info) { 69 if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() && 70 MI.getOperand(1).getImm() != 8) { 71 Info = "applying IT instruction to more than one subsequent instruction is " 72 "deprecated"; 73 return true; 74 } 75 76 return false; 77 } 78 79 static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 80 std::string &Info) { 81 assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] && 82 "cannot predicate thumb instructions"); 83 84 assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments"); 85 for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) { 86 assert(MI.getOperand(OI).isReg() && "expected register"); 87 if (MI.getOperand(OI).getReg() == ARM::SP || 88 MI.getOperand(OI).getReg() == ARM::PC) { 89 Info = "use of SP or PC in the list is deprecated"; 90 return true; 91 } 92 } 93 return false; 94 } 95 96 static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 97 std::string &Info) { 98 assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] && 99 "cannot predicate thumb instructions"); 100 101 assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments"); 102 bool ListContainsPC = false, ListContainsLR = false; 103 for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) { 104 assert(MI.getOperand(OI).isReg() && "expected register"); 105 switch (MI.getOperand(OI).getReg()) { 106 default: 107 break; 108 case ARM::LR: 109 ListContainsLR = true; 110 break; 111 case ARM::PC: 112 ListContainsPC = true; 113 break; 114 case ARM::SP: 115 Info = "use of SP in the list is deprecated"; 116 return true; 117 } 118 } 119 120 if (ListContainsPC && ListContainsLR) { 121 Info = "use of LR and PC simultaneously in the list is deprecated"; 122 return true; 123 } 124 125 return false; 126 } 127 128 #define GET_INSTRINFO_MC_DESC 129 #include "ARMGenInstrInfo.inc" 130 131 #define GET_SUBTARGETINFO_MC_DESC 132 #include "ARMGenSubtargetInfo.inc" 133 134 std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) { 135 bool isThumb = 136 TT.getArch() == Triple::thumb || TT.getArch() == Triple::thumbeb; 137 138 std::string ARMArchFeature; 139 140 unsigned ArchID = ARM::parseArch(TT.getArchName()); 141 if (ArchID != ARM::AK_INVALID && (CPU.empty() || CPU == "generic")) 142 ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str(); 143 144 if (isThumb) { 145 if (ARMArchFeature.empty()) 146 ARMArchFeature = "+thumb-mode"; 147 else 148 ARMArchFeature += ",+thumb-mode"; 149 } 150 151 if (TT.isOSNaCl()) { 152 if (ARMArchFeature.empty()) 153 ARMArchFeature = "+nacl-trap"; 154 else 155 ARMArchFeature += ",+nacl-trap"; 156 } 157 158 return ARMArchFeature; 159 } 160 161 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT, 162 StringRef CPU, StringRef FS) { 163 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 164 if (!FS.empty()) { 165 if (!ArchFS.empty()) 166 ArchFS = (Twine(ArchFS) + "," + FS).str(); 167 else 168 ArchFS = FS; 169 } 170 171 return createARMMCSubtargetInfoImpl(TT, CPU, ArchFS); 172 } 173 174 static MCInstrInfo *createARMMCInstrInfo() { 175 MCInstrInfo *X = new MCInstrInfo(); 176 InitARMMCInstrInfo(X); 177 return X; 178 } 179 180 static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) { 181 MCRegisterInfo *X = new MCRegisterInfo(); 182 InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); 183 return X; 184 } 185 186 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, 187 const Triple &TheTriple) { 188 MCAsmInfo *MAI; 189 if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO()) 190 MAI = new ARMMCAsmInfoDarwin(TheTriple); 191 else if (TheTriple.isWindowsMSVCEnvironment()) 192 MAI = new ARMCOFFMCAsmInfoMicrosoft(); 193 else if (TheTriple.isOSWindows()) 194 MAI = new ARMCOFFMCAsmInfoGNU(); 195 else 196 MAI = new ARMELFMCAsmInfo(TheTriple); 197 198 unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); 199 MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0)); 200 201 return MAI; 202 } 203 204 static MCCodeGenInfo *createARMMCCodeGenInfo(const Triple &TT, Reloc::Model RM, 205 CodeModel::Model CM, 206 CodeGenOpt::Level OL) { 207 MCCodeGenInfo *X = new MCCodeGenInfo(); 208 if (RM == Reloc::Default) { 209 // Default relocation model on Darwin is PIC, not DynamicNoPIC. 210 RM = TT.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; 211 } 212 X->initMCCodeGenInfo(RM, CM, OL); 213 return X; 214 } 215 216 static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx, 217 MCAsmBackend &MAB, raw_pwrite_stream &OS, 218 MCCodeEmitter *Emitter, bool RelaxAll) { 219 return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, 220 T.getArch() == Triple::thumb); 221 } 222 223 static MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB, 224 raw_pwrite_stream &OS, 225 MCCodeEmitter *Emitter, bool RelaxAll, 226 bool DWARFMustBeAtTheEnd) { 227 return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd); 228 } 229 230 static MCInstPrinter *createARMMCInstPrinter(const Triple &T, 231 unsigned SyntaxVariant, 232 const MCAsmInfo &MAI, 233 const MCInstrInfo &MII, 234 const MCRegisterInfo &MRI) { 235 if (SyntaxVariant == 0) 236 return new ARMInstPrinter(MAI, MII, MRI); 237 return nullptr; 238 } 239 240 static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT, 241 MCContext &Ctx) { 242 if (TT.isOSBinFormatMachO()) 243 return createARMMachORelocationInfo(Ctx); 244 // Default to the stock relocation info. 245 return llvm::createMCRelocationInfo(TT, Ctx); 246 } 247 248 namespace { 249 250 class ARMMCInstrAnalysis : public MCInstrAnalysis { 251 public: 252 ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 253 254 bool isUnconditionalBranch(const MCInst &Inst) const override { 255 // BCCs with the "always" predicate are unconditional branches. 256 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 257 return true; 258 return MCInstrAnalysis::isUnconditionalBranch(Inst); 259 } 260 261 bool isConditionalBranch(const MCInst &Inst) const override { 262 // BCCs with the "always" predicate are unconditional branches. 263 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 264 return false; 265 return MCInstrAnalysis::isConditionalBranch(Inst); 266 } 267 268 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 269 uint64_t Size, uint64_t &Target) const override { 270 // We only handle PCRel branches for now. 271 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) 272 return false; 273 274 int64_t Imm = Inst.getOperand(0).getImm(); 275 // FIXME: This is not right for thumb. 276 Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 277 return true; 278 } 279 }; 280 281 } 282 283 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 284 return new ARMMCInstrAnalysis(Info); 285 } 286 287 // Force static initialization. 288 extern "C" void LLVMInitializeARMTargetMC() { 289 for (Target *T : {&TheARMLETarget, &TheARMBETarget, &TheThumbLETarget, 290 &TheThumbBETarget}) { 291 // Register the MC asm info. 292 RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo); 293 294 // Register the MC codegen info. 295 TargetRegistry::RegisterMCCodeGenInfo(*T, createARMMCCodeGenInfo); 296 297 // Register the MC instruction info. 298 TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo); 299 300 // Register the MC register info. 301 TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo); 302 303 // Register the MC subtarget info. 304 TargetRegistry::RegisterMCSubtargetInfo(*T, 305 ARM_MC::createARMMCSubtargetInfo); 306 307 // Register the MC instruction analyzer. 308 TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis); 309 310 TargetRegistry::RegisterELFStreamer(*T, createELFStreamer); 311 TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer); 312 TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer); 313 314 // Register the obj target streamer. 315 TargetRegistry::RegisterObjectTargetStreamer(*T, 316 createARMObjectTargetStreamer); 317 318 // Register the asm streamer. 319 TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer); 320 321 // Register the null TargetStreamer. 322 TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer); 323 324 // Register the MCInstPrinter. 325 TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter); 326 327 // Register the MC relocation info. 328 TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo); 329 } 330 331 // Register the MC Code Emitter 332 for (Target *T : {&TheARMLETarget, &TheThumbLETarget}) 333 TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter); 334 for (Target *T : {&TheARMBETarget, &TheThumbBETarget}) 335 TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter); 336 337 // Register the asm backend. 338 TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend); 339 TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend); 340 TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget, 341 createThumbLEAsmBackend); 342 TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget, 343 createThumbBEAsmBackend); 344 } 345