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