1234353Sdim//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===// 2224133Sdim// 3224133Sdim// The LLVM Compiler Infrastructure 4224133Sdim// 5224133Sdim// This file is distributed under the University of Illinois Open Source 6224133Sdim// License. See LICENSE.TXT for details. 7224133Sdim// 8224133Sdim//===----------------------------------------------------------------------===// 9224133Sdim// 10224133Sdim// This file provides ARM specific target descriptions. 11224133Sdim// 12224133Sdim//===----------------------------------------------------------------------===// 13224133Sdim 14249423Sdim#include "ARMBaseInfo.h" 15249423Sdim#include "ARMMCAsmInfo.h" 16224133Sdim#include "ARMMCTargetDesc.h" 17226633Sdim#include "InstPrinter/ARMInstPrinter.h" 18249423Sdim#include "llvm/ADT/Triple.h" 19226633Sdim#include "llvm/MC/MCCodeGenInfo.h" 20261991Sdim#include "llvm/MC/MCELFStreamer.h" 21226633Sdim#include "llvm/MC/MCInstrAnalysis.h" 22224133Sdim#include "llvm/MC/MCInstrInfo.h" 23224133Sdim#include "llvm/MC/MCRegisterInfo.h" 24276479Sdim#include "llvm/MC/MCStreamer.h" 25224133Sdim#include "llvm/MC/MCSubtargetInfo.h" 26226633Sdim#include "llvm/Support/ErrorHandling.h" 27296417Sdim#include "llvm/Support/TargetParser.h" 28226633Sdim#include "llvm/Support/TargetRegistry.h" 29224133Sdim 30261991Sdimusing namespace llvm; 31261991Sdim 32224133Sdim#define GET_REGINFO_MC_DESC 33224133Sdim#include "ARMGenRegisterInfo.inc" 34224133Sdim 35288943Sdimstatic bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 36261991Sdim std::string &Info) { 37288943Sdim if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] && 38261991Sdim (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) && 39261991Sdim (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) && 40261991Sdim // Checks for the deprecated CP15ISB encoding: 41261991Sdim // mcr p15, #0, rX, c7, c5, #4 42261991Sdim (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) { 43261991Sdim if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) { 44261991Sdim if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) { 45261991Sdim Info = "deprecated since v7, use 'isb'"; 46261991Sdim return true; 47261991Sdim } 48261991Sdim 49261991Sdim // Checks for the deprecated CP15DSB encoding: 50261991Sdim // mcr p15, #0, rX, c7, c10, #4 51261991Sdim if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) { 52261991Sdim Info = "deprecated since v7, use 'dsb'"; 53261991Sdim return true; 54261991Sdim } 55261991Sdim } 56261991Sdim // Checks for the deprecated CP15DMB encoding: 57261991Sdim // mcr p15, #0, rX, c7, c10, #5 58261991Sdim if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 && 59261991Sdim (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) { 60261991Sdim Info = "deprecated since v7, use 'dmb'"; 61261991Sdim return true; 62261991Sdim } 63261991Sdim } 64261991Sdim return false; 65261991Sdim} 66261991Sdim 67288943Sdimstatic bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 68280031Sdim std::string &Info) { 69288943Sdim if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() && 70280031Sdim MI.getOperand(1).getImm() != 8) { 71280031Sdim Info = "applying IT instruction to more than one subsequent instruction is " 72280031Sdim "deprecated"; 73261991Sdim return true; 74261991Sdim } 75261991Sdim 76261991Sdim return false; 77261991Sdim} 78261991Sdim 79288943Sdimstatic bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 80280031Sdim std::string &Info) { 81288943Sdim assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] && 82280031Sdim "cannot predicate thumb instructions"); 83280031Sdim 84280031Sdim assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments"); 85280031Sdim for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) { 86280031Sdim assert(MI.getOperand(OI).isReg() && "expected register"); 87280031Sdim if (MI.getOperand(OI).getReg() == ARM::SP || 88280031Sdim MI.getOperand(OI).getReg() == ARM::PC) { 89280031Sdim Info = "use of SP or PC in the list is deprecated"; 90280031Sdim return true; 91280031Sdim } 92280031Sdim } 93280031Sdim return false; 94280031Sdim} 95280031Sdim 96288943Sdimstatic bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 97280031Sdim std::string &Info) { 98288943Sdim assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] && 99280031Sdim "cannot predicate thumb instructions"); 100280031Sdim 101280031Sdim assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments"); 102280031Sdim bool ListContainsPC = false, ListContainsLR = false; 103280031Sdim for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) { 104280031Sdim assert(MI.getOperand(OI).isReg() && "expected register"); 105280031Sdim switch (MI.getOperand(OI).getReg()) { 106280031Sdim default: 107280031Sdim break; 108280031Sdim case ARM::LR: 109280031Sdim ListContainsLR = true; 110280031Sdim break; 111280031Sdim case ARM::PC: 112280031Sdim ListContainsPC = true; 113280031Sdim break; 114280031Sdim case ARM::SP: 115280031Sdim Info = "use of SP in the list is deprecated"; 116280031Sdim return true; 117280031Sdim } 118280031Sdim } 119280031Sdim 120280031Sdim if (ListContainsPC && ListContainsLR) { 121280031Sdim Info = "use of LR and PC simultaneously in the list is deprecated"; 122280031Sdim return true; 123280031Sdim } 124280031Sdim 125280031Sdim return false; 126280031Sdim} 127280031Sdim 128224133Sdim#define GET_INSTRINFO_MC_DESC 129224133Sdim#include "ARMGenInstrInfo.inc" 130224133Sdim 131224133Sdim#define GET_SUBTARGETINFO_MC_DESC 132224133Sdim#include "ARMGenSubtargetInfo.inc" 133224133Sdim 134288943Sdimstd::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) { 135288943Sdim bool isThumb = 136288943Sdim TT.getArch() == Triple::thumb || TT.getArch() == Triple::thumbeb; 137224133Sdim 138224133Sdim std::string ARMArchFeature; 139224133Sdim 140296417Sdim unsigned ArchID = ARM::parseArch(TT.getArchName()); 141296417Sdim if (ArchID != ARM::AK_INVALID && (CPU.empty() || CPU == "generic")) 142296417Sdim ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str(); 143296417Sdim 144224133Sdim if (isThumb) { 145224133Sdim if (ARMArchFeature.empty()) 146224133Sdim ARMArchFeature = "+thumb-mode"; 147224133Sdim else 148224133Sdim ARMArchFeature += ",+thumb-mode"; 149224133Sdim } 150224133Sdim 151288943Sdim if (TT.isOSNaCl()) { 152249423Sdim if (ARMArchFeature.empty()) 153249423Sdim ARMArchFeature = "+nacl-trap"; 154249423Sdim else 155249423Sdim ARMArchFeature += ",+nacl-trap"; 156249423Sdim } 157249423Sdim 158224133Sdim return ARMArchFeature; 159224133Sdim} 160224133Sdim 161288943SdimMCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT, 162288943Sdim StringRef CPU, StringRef FS) { 163239462Sdim std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 164224133Sdim if (!FS.empty()) { 165224133Sdim if (!ArchFS.empty()) 166288943Sdim ArchFS = (Twine(ArchFS) + "," + FS).str(); 167224133Sdim else 168224133Sdim ArchFS = FS; 169224133Sdim } 170224133Sdim 171288943Sdim return createARMMCSubtargetInfoImpl(TT, CPU, ArchFS); 172224133Sdim} 173224133Sdim 174224133Sdimstatic MCInstrInfo *createARMMCInstrInfo() { 175224133Sdim MCInstrInfo *X = new MCInstrInfo(); 176224133Sdim InitARMMCInstrInfo(X); 177224133Sdim return X; 178224133Sdim} 179224133Sdim 180288943Sdimstatic MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) { 181224133Sdim MCRegisterInfo *X = new MCRegisterInfo(); 182249423Sdim InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); 183224133Sdim return X; 184224133Sdim} 185224133Sdim 186288943Sdimstatic MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, 187288943Sdim const Triple &TheTriple) { 188276479Sdim MCAsmInfo *MAI; 189280031Sdim if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO()) 190288943Sdim MAI = new ARMMCAsmInfoDarwin(TheTriple); 191280031Sdim else if (TheTriple.isWindowsMSVCEnvironment()) 192280031Sdim MAI = new ARMCOFFMCAsmInfoMicrosoft(); 193288943Sdim else if (TheTriple.isOSWindows()) 194288943Sdim MAI = new ARMCOFFMCAsmInfoGNU(); 195280031Sdim else 196288943Sdim MAI = new ARMELFMCAsmInfo(TheTriple); 197224133Sdim 198276479Sdim unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); 199276479Sdim MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0)); 200276479Sdim 201276479Sdim return MAI; 202224133Sdim} 203224133Sdim 204288943Sdimstatic MCCodeGenInfo *createARMMCCodeGenInfo(const Triple &TT, Reloc::Model RM, 205234353Sdim CodeModel::Model CM, 206234353Sdim CodeGenOpt::Level OL) { 207226633Sdim MCCodeGenInfo *X = new MCCodeGenInfo(); 208226633Sdim if (RM == Reloc::Default) { 209226633Sdim // Default relocation model on Darwin is PIC, not DynamicNoPIC. 210288943Sdim RM = TT.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; 211226633Sdim } 212288943Sdim X->initMCCodeGenInfo(RM, CM, OL); 213226633Sdim return X; 214226633Sdim} 215226633Sdim 216288943Sdimstatic MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx, 217288943Sdim MCAsmBackend &MAB, raw_pwrite_stream &OS, 218288943Sdim MCCodeEmitter *Emitter, bool RelaxAll) { 219288943Sdim return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, 220288943Sdim T.getArch() == Triple::thumb); 221288943Sdim} 222226633Sdim 223288943Sdimstatic MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB, 224288943Sdim raw_pwrite_stream &OS, 225288943Sdim MCCodeEmitter *Emitter, bool RelaxAll, 226288943Sdim bool DWARFMustBeAtTheEnd) { 227288943Sdim return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd); 228226633Sdim} 229226633Sdim 230288943Sdimstatic MCInstPrinter *createARMMCInstPrinter(const Triple &T, 231226633Sdim unsigned SyntaxVariant, 232226633Sdim const MCAsmInfo &MAI, 233234353Sdim const MCInstrInfo &MII, 234288943Sdim const MCRegisterInfo &MRI) { 235226633Sdim if (SyntaxVariant == 0) 236288943Sdim return new ARMInstPrinter(MAI, MII, MRI); 237276479Sdim return nullptr; 238226633Sdim} 239226633Sdim 240288943Sdimstatic MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT, 241261991Sdim MCContext &Ctx) { 242288943Sdim if (TT.isOSBinFormatMachO()) 243261991Sdim return createARMMachORelocationInfo(Ctx); 244261991Sdim // Default to the stock relocation info. 245261991Sdim return llvm::createMCRelocationInfo(TT, Ctx); 246261991Sdim} 247261991Sdim 248226633Sdimnamespace { 249226633Sdim 250226633Sdimclass ARMMCInstrAnalysis : public MCInstrAnalysis { 251226633Sdimpublic: 252226633Sdim ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 253226633Sdim 254276479Sdim bool isUnconditionalBranch(const MCInst &Inst) const override { 255226633Sdim // BCCs with the "always" predicate are unconditional branches. 256226633Sdim if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 257226633Sdim return true; 258226633Sdim return MCInstrAnalysis::isUnconditionalBranch(Inst); 259226633Sdim } 260226633Sdim 261276479Sdim bool isConditionalBranch(const MCInst &Inst) const override { 262226633Sdim // BCCs with the "always" predicate are unconditional branches. 263226633Sdim if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 264226633Sdim return false; 265226633Sdim return MCInstrAnalysis::isConditionalBranch(Inst); 266226633Sdim } 267226633Sdim 268261991Sdim bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 269276479Sdim uint64_t Size, uint64_t &Target) const override { 270226633Sdim // We only handle PCRel branches for now. 271226633Sdim if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) 272261991Sdim return false; 273226633Sdim 274226633Sdim int64_t Imm = Inst.getOperand(0).getImm(); 275226633Sdim // FIXME: This is not right for thumb. 276261991Sdim Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 277261991Sdim return true; 278226633Sdim } 279226633Sdim}; 280226633Sdim 281226633Sdim} 282226633Sdim 283226633Sdimstatic MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 284226633Sdim return new ARMMCInstrAnalysis(Info); 285226633Sdim} 286226633Sdim 287226633Sdim// Force static initialization. 288226633Sdimextern "C" void LLVMInitializeARMTargetMC() { 289288943Sdim for (Target *T : {&TheARMLETarget, &TheARMBETarget, &TheThumbLETarget, 290288943Sdim &TheThumbBETarget}) { 291288943Sdim // Register the MC asm info. 292288943Sdim RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo); 293226633Sdim 294288943Sdim // Register the MC codegen info. 295288943Sdim TargetRegistry::RegisterMCCodeGenInfo(*T, createARMMCCodeGenInfo); 296226633Sdim 297288943Sdim // Register the MC instruction info. 298288943Sdim TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo); 299226633Sdim 300288943Sdim // Register the MC register info. 301288943Sdim TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo); 302226633Sdim 303288943Sdim // Register the MC subtarget info. 304288943Sdim TargetRegistry::RegisterMCSubtargetInfo(*T, 305288943Sdim ARM_MC::createARMMCSubtargetInfo); 306226633Sdim 307288943Sdim // Register the MC instruction analyzer. 308288943Sdim TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis); 309226633Sdim 310288943Sdim TargetRegistry::RegisterELFStreamer(*T, createELFStreamer); 311288943Sdim TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer); 312288943Sdim TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer); 313288943Sdim 314288943Sdim // Register the obj target streamer. 315288943Sdim TargetRegistry::RegisterObjectTargetStreamer(*T, 316288943Sdim createARMObjectTargetStreamer); 317288943Sdim 318288943Sdim // Register the asm streamer. 319288943Sdim TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer); 320288943Sdim 321288943Sdim // Register the null TargetStreamer. 322288943Sdim TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer); 323288943Sdim 324288943Sdim // Register the MCInstPrinter. 325288943Sdim TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter); 326288943Sdim 327288943Sdim // Register the MC relocation info. 328288943Sdim TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo); 329288943Sdim } 330288943Sdim 331226633Sdim // Register the MC Code Emitter 332288943Sdim for (Target *T : {&TheARMLETarget, &TheThumbLETarget}) 333288943Sdim TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter); 334288943Sdim for (Target *T : {&TheARMBETarget, &TheThumbBETarget}) 335288943Sdim TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter); 336226633Sdim 337226633Sdim // Register the asm backend. 338276479Sdim TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend); 339276479Sdim TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend); 340276479Sdim TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget, 341276479Sdim createThumbLEAsmBackend); 342276479Sdim TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget, 343276479Sdim createThumbBEAsmBackend); 344224133Sdim} 345