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