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 X->initMCCodeGenInfo(RM, CM, OL); 209 return X; 210 } 211 212 static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx, 213 MCAsmBackend &MAB, raw_pwrite_stream &OS, 214 MCCodeEmitter *Emitter, bool RelaxAll) { 215 return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, 216 T.getArch() == Triple::thumb); 217 } 218 219 static MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB, 220 raw_pwrite_stream &OS, 221 MCCodeEmitter *Emitter, bool RelaxAll, 222 bool DWARFMustBeAtTheEnd) { 223 return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd); 224 } 225 226 static MCInstPrinter *createARMMCInstPrinter(const Triple &T, 227 unsigned SyntaxVariant, 228 const MCAsmInfo &MAI, 229 const MCInstrInfo &MII, 230 const MCRegisterInfo &MRI) { 231 if (SyntaxVariant == 0) 232 return new ARMInstPrinter(MAI, MII, MRI); 233 return nullptr; 234 } 235 236 static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT, 237 MCContext &Ctx) { 238 if (TT.isOSBinFormatMachO()) 239 return createARMMachORelocationInfo(Ctx); 240 // Default to the stock relocation info. 241 return llvm::createMCRelocationInfo(TT, Ctx); 242 } 243 244 namespace { 245 246 class ARMMCInstrAnalysis : public MCInstrAnalysis { 247 public: 248 ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 249 250 bool isUnconditionalBranch(const MCInst &Inst) const override { 251 // BCCs with the "always" predicate are unconditional branches. 252 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 253 return true; 254 return MCInstrAnalysis::isUnconditionalBranch(Inst); 255 } 256 257 bool isConditionalBranch(const MCInst &Inst) const override { 258 // BCCs with the "always" predicate are unconditional branches. 259 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 260 return false; 261 return MCInstrAnalysis::isConditionalBranch(Inst); 262 } 263 264 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 265 uint64_t Size, uint64_t &Target) const override { 266 // We only handle PCRel branches for now. 267 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) 268 return false; 269 270 int64_t Imm = Inst.getOperand(0).getImm(); 271 // FIXME: This is not right for thumb. 272 Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 273 return true; 274 } 275 }; 276 277 } 278 279 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 280 return new ARMMCInstrAnalysis(Info); 281 } 282 283 // Force static initialization. 284 extern "C" void LLVMInitializeARMTargetMC() { 285 for (Target *T : {&TheARMLETarget, &TheARMBETarget, &TheThumbLETarget, 286 &TheThumbBETarget}) { 287 // Register the MC asm info. 288 RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo); 289 290 // Register the MC codegen info. 291 TargetRegistry::RegisterMCCodeGenInfo(*T, createARMMCCodeGenInfo); 292 293 // Register the MC instruction info. 294 TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo); 295 296 // Register the MC register info. 297 TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo); 298 299 // Register the MC subtarget info. 300 TargetRegistry::RegisterMCSubtargetInfo(*T, 301 ARM_MC::createARMMCSubtargetInfo); 302 303 // Register the MC instruction analyzer. 304 TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis); 305 306 TargetRegistry::RegisterELFStreamer(*T, createELFStreamer); 307 TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer); 308 TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer); 309 310 // Register the obj target streamer. 311 TargetRegistry::RegisterObjectTargetStreamer(*T, 312 createARMObjectTargetStreamer); 313 314 // Register the asm streamer. 315 TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer); 316 317 // Register the null TargetStreamer. 318 TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer); 319 320 // Register the MCInstPrinter. 321 TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter); 322 323 // Register the MC relocation info. 324 TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo); 325 } 326 327 // Register the MC Code Emitter 328 for (Target *T : {&TheARMLETarget, &TheThumbLETarget}) 329 TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter); 330 for (Target *T : {&TheARMBETarget, &TheThumbBETarget}) 331 TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter); 332 333 // Register the asm backend. 334 TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend); 335 TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend); 336 TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget, 337 createThumbLEAsmBackend); 338 TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget, 339 createThumbBEAsmBackend); 340 } 341