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