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