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/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, 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, 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, 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, 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 
    134 std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) {
    135   Triple triple(TT);
    136 
    137   bool isThumb = triple.getArch() == Triple::thumb ||
    138                  triple.getArch() == Triple::thumbeb;
    139 
    140   bool NoCPU = CPU == "generic" || CPU.empty();
    141   std::string ARMArchFeature;
    142   switch (triple.getSubArch()) {
    143   default:
    144     llvm_unreachable("invalid sub-architecture for ARM");
    145   case Triple::ARMSubArch_v8:
    146     if (NoCPU)
    147       // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2,
    148       //      FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone,
    149       //      FeatureT2XtPk, FeatureCrypto, FeatureCRC
    150       ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm,"
    151                        "+trustzone,+t2xtpk,+crypto,+crc";
    152     else
    153       // Use CPU to figure out the exact features
    154       ARMArchFeature = "+v8";
    155     break;
    156   case Triple::ARMSubArch_v8_1a:
    157     if (NoCPU)
    158       // v8.1a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2,
    159       //      FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone,
    160       //      FeatureT2XtPk, FeatureCrypto, FeatureCRC, FeatureV8_1a
    161       ARMArchFeature = "+v8.1a,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm,"
    162                        "+trustzone,+t2xtpk,+crypto,+crc";
    163     else
    164       // Use CPU to figure out the exact features
    165       ARMArchFeature = "+v8.1a";
    166     break;
    167   case Triple::ARMSubArch_v7m:
    168     isThumb = true;
    169     if (NoCPU)
    170       // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass
    171       ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass";
    172     else
    173       // Use CPU to figure out the exact features.
    174       ARMArchFeature = "+v7";
    175     break;
    176   case Triple::ARMSubArch_v7em:
    177     if (NoCPU)
    178       // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2,
    179       //       FeatureT2XtPk, FeatureMClass
    180       ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass";
    181     else
    182       // Use CPU to figure out the exact features.
    183       ARMArchFeature = "+v7";
    184     break;
    185   case Triple::ARMSubArch_v7s:
    186     if (NoCPU)
    187       // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS
    188       //      Swift
    189       ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+ras";
    190     else
    191       // Use CPU to figure out the exact features.
    192       ARMArchFeature = "+v7";
    193     break;
    194   case Triple::ARMSubArch_v7:
    195     // v7 CPUs have lots of different feature sets. If no CPU is specified,
    196     // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return
    197     // the "minimum" feature set and use CPU string to figure out the exact
    198     // features.
    199     if (NoCPU)
    200       // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk
    201       ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk";
    202     else
    203       // Use CPU to figure out the exact features.
    204       ARMArchFeature = "+v7";
    205     break;
    206   case Triple::ARMSubArch_v6t2:
    207     ARMArchFeature = "+v6t2";
    208     break;
    209   case Triple::ARMSubArch_v6k:
    210     ARMArchFeature = "+v6k";
    211     break;
    212   case Triple::ARMSubArch_v6m:
    213     isThumb = true;
    214     if (NoCPU)
    215       // v6m: FeatureNoARM, FeatureMClass
    216       ARMArchFeature = "+v6m,+noarm,+mclass";
    217     else
    218       ARMArchFeature = "+v6";
    219     break;
    220   case Triple::ARMSubArch_v6:
    221     ARMArchFeature = "+v6";
    222     break;
    223   case Triple::ARMSubArch_v5te:
    224     ARMArchFeature = "+v5te";
    225     break;
    226   case Triple::ARMSubArch_v5:
    227     ARMArchFeature = "+v5t";
    228     break;
    229   case Triple::ARMSubArch_v4t:
    230     ARMArchFeature = "+v4t";
    231     break;
    232   case Triple::NoSubArch:
    233     break;
    234   }
    235 
    236   if (isThumb) {
    237     if (ARMArchFeature.empty())
    238       ARMArchFeature = "+thumb-mode";
    239     else
    240       ARMArchFeature += ",+thumb-mode";
    241   }
    242 
    243   if (triple.isOSNaCl()) {
    244     if (ARMArchFeature.empty())
    245       ARMArchFeature = "+nacl-trap";
    246     else
    247       ARMArchFeature += ",+nacl-trap";
    248   }
    249 
    250   return ARMArchFeature;
    251 }
    252 
    253 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU,
    254                                                   StringRef FS) {
    255   std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
    256   if (!FS.empty()) {
    257     if (!ArchFS.empty())
    258       ArchFS = (Twine(ArchFS) + "," + FS).str();
    259     else
    260       ArchFS = FS;
    261   }
    262 
    263   MCSubtargetInfo *X = new MCSubtargetInfo();
    264   InitARMMCSubtargetInfo(X, TT, CPU, ArchFS);
    265   return X;
    266 }
    267 
    268 static MCInstrInfo *createARMMCInstrInfo() {
    269   MCInstrInfo *X = new MCInstrInfo();
    270   InitARMMCInstrInfo(X);
    271   return X;
    272 }
    273 
    274 static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
    275   MCRegisterInfo *X = new MCRegisterInfo();
    276   InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
    277   return X;
    278 }
    279 
    280 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
    281   Triple TheTriple(TT);
    282 
    283   MCAsmInfo *MAI;
    284   if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
    285     MAI = new ARMMCAsmInfoDarwin(TT);
    286   else if (TheTriple.isWindowsItaniumEnvironment())
    287     MAI = new ARMCOFFMCAsmInfoGNU();
    288   else if (TheTriple.isWindowsMSVCEnvironment())
    289     MAI = new ARMCOFFMCAsmInfoMicrosoft();
    290   else
    291     MAI = new ARMELFMCAsmInfo(TT);
    292 
    293   unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
    294   MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0));
    295 
    296   return MAI;
    297 }
    298 
    299 static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM,
    300                                              CodeModel::Model CM,
    301                                              CodeGenOpt::Level OL) {
    302   MCCodeGenInfo *X = new MCCodeGenInfo();
    303   if (RM == Reloc::Default) {
    304     Triple TheTriple(TT);
    305     // Default relocation model on Darwin is PIC, not DynamicNoPIC.
    306     RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC;
    307   }
    308   X->InitMCCodeGenInfo(RM, CM, OL);
    309   return X;
    310 }
    311 
    312 static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
    313                                      MCAsmBackend &MAB, raw_pwrite_stream &OS,
    314                                      MCCodeEmitter *Emitter, bool RelaxAll) {
    315   return createARMELFStreamer(Ctx, MAB, OS, Emitter, false,
    316                               T.getArch() == Triple::thumb);
    317 }
    318 
    319 static MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB,
    320                                           raw_pwrite_stream &OS,
    321                                           MCCodeEmitter *Emitter, bool RelaxAll,
    322                                           bool DWARFMustBeAtTheEnd) {
    323   return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd);
    324 }
    325 
    326 static MCInstPrinter *createARMMCInstPrinter(const Triple &T,
    327                                              unsigned SyntaxVariant,
    328                                              const MCAsmInfo &MAI,
    329                                              const MCInstrInfo &MII,
    330                                              const MCRegisterInfo &MRI) {
    331   if (SyntaxVariant == 0)
    332     return new ARMInstPrinter(MAI, MII, MRI);
    333   return nullptr;
    334 }
    335 
    336 static MCRelocationInfo *createARMMCRelocationInfo(StringRef TT,
    337                                                    MCContext &Ctx) {
    338   Triple TheTriple(TT);
    339   if (TheTriple.isOSBinFormatMachO())
    340     return createARMMachORelocationInfo(Ctx);
    341   // Default to the stock relocation info.
    342   return llvm::createMCRelocationInfo(TT, Ctx);
    343 }
    344 
    345 namespace {
    346 
    347 class ARMMCInstrAnalysis : public MCInstrAnalysis {
    348 public:
    349   ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
    350 
    351   bool isUnconditionalBranch(const MCInst &Inst) const override {
    352     // BCCs with the "always" predicate are unconditional branches.
    353     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
    354       return true;
    355     return MCInstrAnalysis::isUnconditionalBranch(Inst);
    356   }
    357 
    358   bool isConditionalBranch(const MCInst &Inst) const override {
    359     // BCCs with the "always" predicate are unconditional branches.
    360     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
    361       return false;
    362     return MCInstrAnalysis::isConditionalBranch(Inst);
    363   }
    364 
    365   bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
    366                       uint64_t Size, uint64_t &Target) const override {
    367     // We only handle PCRel branches for now.
    368     if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
    369       return false;
    370 
    371     int64_t Imm = Inst.getOperand(0).getImm();
    372     // FIXME: This is not right for thumb.
    373     Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes.
    374     return true;
    375   }
    376 };
    377 
    378 }
    379 
    380 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
    381   return new ARMMCInstrAnalysis(Info);
    382 }
    383 
    384 // Force static initialization.
    385 extern "C" void LLVMInitializeARMTargetMC() {
    386   for (Target *T : {&TheARMLETarget, &TheARMBETarget, &TheThumbLETarget,
    387                     &TheThumbBETarget}) {
    388     // Register the MC asm info.
    389     RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
    390 
    391     // Register the MC codegen info.
    392     TargetRegistry::RegisterMCCodeGenInfo(*T, createARMMCCodeGenInfo);
    393 
    394     // Register the MC instruction info.
    395     TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
    396 
    397     // Register the MC register info.
    398     TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
    399 
    400     // Register the MC subtarget info.
    401     TargetRegistry::RegisterMCSubtargetInfo(*T,
    402                                             ARM_MC::createARMMCSubtargetInfo);
    403 
    404     // Register the MC instruction analyzer.
    405     TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis);
    406 
    407     TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
    408     TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer);
    409     TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer);
    410 
    411     // Register the obj target streamer.
    412     TargetRegistry::RegisterObjectTargetStreamer(*T,
    413                                                  createARMObjectTargetStreamer);
    414 
    415     // Register the asm streamer.
    416     TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer);
    417 
    418     // Register the null TargetStreamer.
    419     TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer);
    420 
    421     // Register the MCInstPrinter.
    422     TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter);
    423 
    424     // Register the MC relocation info.
    425     TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo);
    426   }
    427 
    428   // Register the MC Code Emitter
    429   for (Target *T : {&TheARMLETarget, &TheThumbLETarget})
    430     TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
    431   for (Target *T : {&TheARMBETarget, &TheThumbBETarget})
    432     TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
    433 
    434   // Register the asm backend.
    435   TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend);
    436   TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend);
    437   TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget,
    438                                        createThumbLEAsmBackend);
    439   TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget,
    440                                        createThumbBEAsmBackend);
    441 }
    442