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 bool ARM_MC::isPredicated(const MCInst &MI, const MCInstrInfo *MCII) { 184 const MCInstrDesc &Desc = MCII->get(MI.getOpcode()); 185 int PredOpIdx = Desc.findFirstPredOperandIdx(); 186 return PredOpIdx != -1 && MI.getOperand(PredOpIdx).getImm() != ARMCC::AL; 187 } 188 189 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT, 190 StringRef CPU, StringRef FS) { 191 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 192 if (!FS.empty()) { 193 if (!ArchFS.empty()) 194 ArchFS = (Twine(ArchFS) + "," + FS).str(); 195 else 196 ArchFS = std::string(FS); 197 } 198 199 return createARMMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, ArchFS); 200 } 201 202 static MCInstrInfo *createARMMCInstrInfo() { 203 MCInstrInfo *X = new MCInstrInfo(); 204 InitARMMCInstrInfo(X); 205 return X; 206 } 207 208 static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) { 209 MCRegisterInfo *X = new MCRegisterInfo(); 210 InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); 211 return X; 212 } 213 214 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, 215 const Triple &TheTriple, 216 const MCTargetOptions &Options) { 217 MCAsmInfo *MAI; 218 if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO()) 219 MAI = new ARMMCAsmInfoDarwin(TheTriple); 220 else if (TheTriple.isWindowsMSVCEnvironment()) 221 MAI = new ARMCOFFMCAsmInfoMicrosoft(); 222 else if (TheTriple.isOSWindows()) 223 MAI = new ARMCOFFMCAsmInfoGNU(); 224 else 225 MAI = new ARMELFMCAsmInfo(TheTriple); 226 227 unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); 228 MAI->addInitialFrameState(MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0)); 229 230 return MAI; 231 } 232 233 static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx, 234 std::unique_ptr<MCAsmBackend> &&MAB, 235 std::unique_ptr<MCObjectWriter> &&OW, 236 std::unique_ptr<MCCodeEmitter> &&Emitter, 237 bool RelaxAll) { 238 return createARMELFStreamer( 239 Ctx, std::move(MAB), std::move(OW), std::move(Emitter), false, 240 (T.getArch() == Triple::thumb || T.getArch() == Triple::thumbeb), 241 T.isAndroid()); 242 } 243 244 static MCStreamer * 245 createARMMachOStreamer(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&MAB, 246 std::unique_ptr<MCObjectWriter> &&OW, 247 std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll, 248 bool DWARFMustBeAtTheEnd) { 249 return createMachOStreamer(Ctx, std::move(MAB), std::move(OW), 250 std::move(Emitter), false, DWARFMustBeAtTheEnd); 251 } 252 253 static MCInstPrinter *createARMMCInstPrinter(const Triple &T, 254 unsigned SyntaxVariant, 255 const MCAsmInfo &MAI, 256 const MCInstrInfo &MII, 257 const MCRegisterInfo &MRI) { 258 if (SyntaxVariant == 0) 259 return new ARMInstPrinter(MAI, MII, MRI); 260 return nullptr; 261 } 262 263 static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT, 264 MCContext &Ctx) { 265 if (TT.isOSBinFormatMachO()) 266 return createARMMachORelocationInfo(Ctx); 267 // Default to the stock relocation info. 268 return llvm::createMCRelocationInfo(TT, Ctx); 269 } 270 271 namespace { 272 273 class ARMMCInstrAnalysis : public MCInstrAnalysis { 274 public: 275 ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 276 277 bool isUnconditionalBranch(const MCInst &Inst) const override { 278 // BCCs with the "always" predicate are unconditional branches. 279 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 280 return true; 281 return MCInstrAnalysis::isUnconditionalBranch(Inst); 282 } 283 284 bool isConditionalBranch(const MCInst &Inst) const override { 285 // BCCs with the "always" predicate are unconditional branches. 286 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 287 return false; 288 return MCInstrAnalysis::isConditionalBranch(Inst); 289 } 290 291 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 292 uint64_t Size, uint64_t &Target) const override { 293 // We only handle PCRel branches for now. 294 if (Inst.getNumOperands() == 0 || 295 Info->get(Inst.getOpcode()).OpInfo[0].OperandType != 296 MCOI::OPERAND_PCREL) 297 return false; 298 299 int64_t Imm = Inst.getOperand(0).getImm(); 300 Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 301 return true; 302 } 303 }; 304 305 class ThumbMCInstrAnalysis : public ARMMCInstrAnalysis { 306 public: 307 ThumbMCInstrAnalysis(const MCInstrInfo *Info) : ARMMCInstrAnalysis(Info) {} 308 309 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, 310 uint64_t &Target) const override { 311 unsigned OpId; 312 switch (Inst.getOpcode()) { 313 default: 314 OpId = 0; 315 if (Inst.getNumOperands() == 0) 316 return false; 317 break; 318 case ARM::MVE_WLSTP_8: 319 case ARM::MVE_WLSTP_16: 320 case ARM::MVE_WLSTP_32: 321 case ARM::MVE_WLSTP_64: 322 case ARM::t2WLS: 323 case ARM::MVE_LETP: 324 case ARM::t2LEUpdate: 325 OpId = 2; 326 break; 327 case ARM::t2LE: 328 OpId = 1; 329 break; 330 } 331 332 // We only handle PCRel branches for now. 333 if (Info->get(Inst.getOpcode()).OpInfo[OpId].OperandType != 334 MCOI::OPERAND_PCREL) 335 return false; 336 337 // In Thumb mode the PC is always off by 4 bytes. 338 Target = Addr + Inst.getOperand(OpId).getImm() + 4; 339 return true; 340 } 341 }; 342 343 } 344 345 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 346 return new ARMMCInstrAnalysis(Info); 347 } 348 349 static MCInstrAnalysis *createThumbMCInstrAnalysis(const MCInstrInfo *Info) { 350 return new ThumbMCInstrAnalysis(Info); 351 } 352 353 bool ARM::isCDECoproc(size_t Coproc, const MCSubtargetInfo &STI) { 354 // Unfortunately we don't have ARMTargetInfo in the disassembler, so we have 355 // to rely on feature bits. 356 if (Coproc >= 8) 357 return false; 358 return STI.getFeatureBits()[ARM::FeatureCoprocCDE0 + Coproc]; 359 } 360 361 // Force static initialization. 362 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTargetMC() { 363 for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(), 364 &getTheThumbLETarget(), &getTheThumbBETarget()}) { 365 // Register the MC asm info. 366 RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo); 367 368 // Register the MC instruction info. 369 TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo); 370 371 // Register the MC register info. 372 TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo); 373 374 // Register the MC subtarget info. 375 TargetRegistry::RegisterMCSubtargetInfo(*T, 376 ARM_MC::createARMMCSubtargetInfo); 377 378 TargetRegistry::RegisterELFStreamer(*T, createELFStreamer); 379 TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer); 380 TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer); 381 382 // Register the obj target streamer. 383 TargetRegistry::RegisterObjectTargetStreamer(*T, 384 createARMObjectTargetStreamer); 385 386 // Register the asm streamer. 387 TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer); 388 389 // Register the null TargetStreamer. 390 TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer); 391 392 // Register the MCInstPrinter. 393 TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter); 394 395 // Register the MC relocation info. 396 TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo); 397 } 398 399 // Register the MC instruction analyzer. 400 for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget()}) 401 TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis); 402 for (Target *T : {&getTheThumbLETarget(), &getTheThumbBETarget()}) 403 TargetRegistry::RegisterMCInstrAnalysis(*T, createThumbMCInstrAnalysis); 404 405 for (Target *T : {&getTheARMLETarget(), &getTheThumbLETarget()}) { 406 TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter); 407 TargetRegistry::RegisterMCAsmBackend(*T, createARMLEAsmBackend); 408 } 409 for (Target *T : {&getTheARMBETarget(), &getTheThumbBETarget()}) { 410 TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter); 411 TargetRegistry::RegisterMCAsmBackend(*T, createARMBEAsmBackend); 412 } 413 } 414