LLVM API Documentation

ARMMCTargetDesc.cpp
Go to the documentation of this file.
00001 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file provides ARM specific target descriptions.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "ARMBaseInfo.h"
00015 #include "ARMMCAsmInfo.h"
00016 #include "ARMMCTargetDesc.h"
00017 #include "InstPrinter/ARMInstPrinter.h"
00018 #include "llvm/ADT/Triple.h"
00019 #include "llvm/MC/MCCodeGenInfo.h"
00020 #include "llvm/MC/MCELFStreamer.h"
00021 #include "llvm/MC/MCInstrAnalysis.h"
00022 #include "llvm/MC/MCInstrInfo.h"
00023 #include "llvm/MC/MCRegisterInfo.h"
00024 #include "llvm/MC/MCStreamer.h"
00025 #include "llvm/MC/MCSubtargetInfo.h"
00026 #include "llvm/Support/ErrorHandling.h"
00027 #include "llvm/Support/TargetRegistry.h"
00028 
00029 using namespace llvm;
00030 
00031 #define GET_REGINFO_MC_DESC
00032 #include "ARMGenRegisterInfo.inc"
00033 
00034 static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
00035                                   std::string &Info) {
00036   if (STI.getFeatureBits() & llvm::ARM::HasV7Ops &&
00037       (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
00038       (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
00039       // Checks for the deprecated CP15ISB encoding:
00040       // mcr p15, #0, rX, c7, c5, #4
00041       (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
00042     if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
00043       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
00044         Info = "deprecated since v7, use 'isb'";
00045         return true;
00046       }
00047 
00048       // Checks for the deprecated CP15DSB encoding:
00049       // mcr p15, #0, rX, c7, c10, #4
00050       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
00051         Info = "deprecated since v7, use 'dsb'";
00052         return true;
00053       }
00054     }
00055     // Checks for the deprecated CP15DMB encoding:
00056     // mcr p15, #0, rX, c7, c10, #5
00057     if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
00058         (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
00059       Info = "deprecated since v7, use 'dmb'";
00060       return true;
00061     }
00062   }
00063   return false;
00064 }
00065 
00066 static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
00067                                   std::string &Info) {
00068   if (STI.getFeatureBits() & llvm::ARM::HasV8Ops &&
00069       MI.getOperand(1).isImm() && MI.getOperand(1).getImm() != 8) {
00070     Info = "applying IT instruction to more than one subsequent instruction is deprecated";
00071     return true;
00072   }
00073 
00074   return false;
00075 }
00076 
00077 #define GET_INSTRINFO_MC_DESC
00078 #include "ARMGenInstrInfo.inc"
00079 
00080 #define GET_SUBTARGETINFO_MC_DESC
00081 #include "ARMGenSubtargetInfo.inc"
00082 
00083 
00084 std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) {
00085   Triple triple(TT);
00086 
00087   bool isThumb = triple.getArch() == Triple::thumb ||
00088                  triple.getArch() == Triple::thumbeb;
00089 
00090   bool NoCPU = CPU == "generic" || CPU.empty();
00091   std::string ARMArchFeature;
00092   switch (triple.getSubArch()) {
00093   default:
00094     llvm_unreachable("invalid sub-architecture for ARM");
00095   case Triple::ARMSubArch_v8:
00096     if (NoCPU)
00097       // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2,
00098       //      FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone,
00099       //      FeatureT2XtPk, FeatureCrypto, FeatureCRC
00100       ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm,"
00101                        "+trustzone,+t2xtpk,+crypto,+crc";
00102     else
00103       // Use CPU to figure out the exact features
00104       ARMArchFeature = "+v8";
00105     break;
00106   case Triple::ARMSubArch_v7m:
00107     isThumb = true;
00108     if (NoCPU)
00109       // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass
00110       ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass";
00111     else
00112       // Use CPU to figure out the exact features.
00113       ARMArchFeature = "+v7";
00114     break;
00115   case Triple::ARMSubArch_v7em:
00116     if (NoCPU)
00117       // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2,
00118       //       FeatureT2XtPk, FeatureMClass
00119       ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass";
00120     else
00121       // Use CPU to figure out the exact features.
00122       ARMArchFeature = "+v7";
00123     break;
00124   case Triple::ARMSubArch_v7s:
00125     if (NoCPU)
00126       // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS
00127       //      Swift
00128       ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+ras";
00129     else
00130       // Use CPU to figure out the exact features.
00131       ARMArchFeature = "+v7";
00132     break;
00133   case Triple::ARMSubArch_v7:
00134     // v7 CPUs have lots of different feature sets. If no CPU is specified,
00135     // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return
00136     // the "minimum" feature set and use CPU string to figure out the exact
00137     // features.
00138     if (NoCPU)
00139       // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk
00140       ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk";
00141     else
00142       // Use CPU to figure out the exact features.
00143       ARMArchFeature = "+v7";
00144     break;
00145   case Triple::ARMSubArch_v6t2:
00146     ARMArchFeature = "+v6t2";
00147     break;
00148   case Triple::ARMSubArch_v6m:
00149     isThumb = true;
00150     if (NoCPU)
00151       // v6m: FeatureNoARM, FeatureMClass
00152       ARMArchFeature = "+v6m,+noarm,+mclass";
00153     else
00154       ARMArchFeature = "+v6";
00155     break;
00156   case Triple::ARMSubArch_v6:
00157     ARMArchFeature = "+v6";
00158     break;
00159   case Triple::ARMSubArch_v5te:
00160     ARMArchFeature = "+v5te";
00161     break;
00162   case Triple::ARMSubArch_v5:
00163     ARMArchFeature = "+v5t";
00164     break;
00165   case Triple::ARMSubArch_v4t:
00166     ARMArchFeature = "+v4t";
00167     break;
00168   case Triple::NoSubArch:
00169     break;
00170   }
00171 
00172   if (isThumb) {
00173     if (ARMArchFeature.empty())
00174       ARMArchFeature = "+thumb-mode";
00175     else
00176       ARMArchFeature += ",+thumb-mode";
00177   }
00178 
00179   if (triple.isOSNaCl()) {
00180     if (ARMArchFeature.empty())
00181       ARMArchFeature = "+nacl-trap";
00182     else
00183       ARMArchFeature += ",+nacl-trap";
00184   }
00185 
00186   return ARMArchFeature;
00187 }
00188 
00189 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU,
00190                                                   StringRef FS) {
00191   std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
00192   if (!FS.empty()) {
00193     if (!ArchFS.empty())
00194       ArchFS = ArchFS + "," + FS.str();
00195     else
00196       ArchFS = FS;
00197   }
00198 
00199   MCSubtargetInfo *X = new MCSubtargetInfo();
00200   InitARMMCSubtargetInfo(X, TT, CPU, ArchFS);
00201   return X;
00202 }
00203 
00204 static MCInstrInfo *createARMMCInstrInfo() {
00205   MCInstrInfo *X = new MCInstrInfo();
00206   InitARMMCInstrInfo(X);
00207   return X;
00208 }
00209 
00210 static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
00211   MCRegisterInfo *X = new MCRegisterInfo();
00212   InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
00213   return X;
00214 }
00215 
00216 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
00217   Triple TheTriple(TT);
00218 
00219   MCAsmInfo *MAI;
00220   switch (TheTriple.getOS()) {
00221   case llvm::Triple::Darwin:
00222   case llvm::Triple::IOS:
00223   case llvm::Triple::MacOSX:
00224     MAI = new ARMMCAsmInfoDarwin(TT);
00225     break;
00226   case llvm::Triple::Win32:
00227     switch (TheTriple.getEnvironment()) {
00228     case llvm::Triple::Itanium:
00229       MAI = new ARMCOFFMCAsmInfoGNU();
00230       break;
00231     case llvm::Triple::MSVC:
00232       MAI = new ARMCOFFMCAsmInfoMicrosoft();
00233       break;
00234     default:
00235       llvm_unreachable("invalid environment");
00236     }
00237     break;
00238   default:
00239     if (TheTriple.isOSBinFormatMachO())
00240       MAI = new ARMMCAsmInfoDarwin(TT);
00241     else
00242       MAI = new ARMELFMCAsmInfo(TT);
00243     break;
00244   }
00245 
00246   unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
00247   MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0));
00248 
00249   return MAI;
00250 }
00251 
00252 static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM,
00253                                              CodeModel::Model CM,
00254                                              CodeGenOpt::Level OL) {
00255   MCCodeGenInfo *X = new MCCodeGenInfo();
00256   if (RM == Reloc::Default) {
00257     Triple TheTriple(TT);
00258     // Default relocation model on Darwin is PIC, not DynamicNoPIC.
00259     RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC;
00260   }
00261   X->InitMCCodeGenInfo(RM, CM, OL);
00262   return X;
00263 }
00264 
00265 // This is duplicated code. Refactor this.
00266 static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
00267                                     MCContext &Ctx, MCAsmBackend &MAB,
00268                                     raw_ostream &OS,
00269                                     MCCodeEmitter *Emitter,
00270                                     const MCSubtargetInfo &STI,
00271                                     bool RelaxAll,
00272                                     bool NoExecStack) {
00273   Triple TheTriple(TT);
00274 
00275   switch (TheTriple.getObjectFormat()) {
00276   default: llvm_unreachable("unsupported object format");
00277   case Triple::MachO: {
00278     MCStreamer *S = createMachOStreamer(Ctx, MAB, OS, Emitter, false);
00279     new ARMTargetStreamer(*S);
00280     return S;
00281   }
00282   case Triple::COFF:
00283     assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported");
00284     return createARMWinCOFFStreamer(Ctx, MAB, *Emitter, OS);
00285   case Triple::ELF:
00286     return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack,
00287                                 TheTriple.getArch() == Triple::thumb);
00288   }
00289 }
00290 
00291 static MCInstPrinter *createARMMCInstPrinter(const Target &T,
00292                                              unsigned SyntaxVariant,
00293                                              const MCAsmInfo &MAI,
00294                                              const MCInstrInfo &MII,
00295                                              const MCRegisterInfo &MRI,
00296                                              const MCSubtargetInfo &STI) {
00297   if (SyntaxVariant == 0)
00298     return new ARMInstPrinter(MAI, MII, MRI, STI);
00299   return nullptr;
00300 }
00301 
00302 static MCRelocationInfo *createARMMCRelocationInfo(StringRef TT,
00303                                                    MCContext &Ctx) {
00304   Triple TheTriple(TT);
00305   if (TheTriple.isOSBinFormatMachO())
00306     return createARMMachORelocationInfo(Ctx);
00307   // Default to the stock relocation info.
00308   return llvm::createMCRelocationInfo(TT, Ctx);
00309 }
00310 
00311 namespace {
00312 
00313 class ARMMCInstrAnalysis : public MCInstrAnalysis {
00314 public:
00315   ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
00316 
00317   bool isUnconditionalBranch(const MCInst &Inst) const override {
00318     // BCCs with the "always" predicate are unconditional branches.
00319     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
00320       return true;
00321     return MCInstrAnalysis::isUnconditionalBranch(Inst);
00322   }
00323 
00324   bool isConditionalBranch(const MCInst &Inst) const override {
00325     // BCCs with the "always" predicate are unconditional branches.
00326     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
00327       return false;
00328     return MCInstrAnalysis::isConditionalBranch(Inst);
00329   }
00330 
00331   bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
00332                       uint64_t Size, uint64_t &Target) const override {
00333     // We only handle PCRel branches for now.
00334     if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
00335       return false;
00336 
00337     int64_t Imm = Inst.getOperand(0).getImm();
00338     // FIXME: This is not right for thumb.
00339     Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes.
00340     return true;
00341   }
00342 };
00343 
00344 }
00345 
00346 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
00347   return new ARMMCInstrAnalysis(Info);
00348 }
00349 
00350 // Force static initialization.
00351 extern "C" void LLVMInitializeARMTargetMC() {
00352   // Register the MC asm info.
00353   RegisterMCAsmInfoFn X(TheARMLETarget, createARMMCAsmInfo);
00354   RegisterMCAsmInfoFn Y(TheARMBETarget, createARMMCAsmInfo);
00355   RegisterMCAsmInfoFn A(TheThumbLETarget, createARMMCAsmInfo);
00356   RegisterMCAsmInfoFn B(TheThumbBETarget, createARMMCAsmInfo);
00357 
00358   // Register the MC codegen info.
00359   TargetRegistry::RegisterMCCodeGenInfo(TheARMLETarget, createARMMCCodeGenInfo);
00360   TargetRegistry::RegisterMCCodeGenInfo(TheARMBETarget, createARMMCCodeGenInfo);
00361   TargetRegistry::RegisterMCCodeGenInfo(TheThumbLETarget,
00362                                         createARMMCCodeGenInfo);
00363   TargetRegistry::RegisterMCCodeGenInfo(TheThumbBETarget,
00364                                         createARMMCCodeGenInfo);
00365 
00366   // Register the MC instruction info.
00367   TargetRegistry::RegisterMCInstrInfo(TheARMLETarget, createARMMCInstrInfo);
00368   TargetRegistry::RegisterMCInstrInfo(TheARMBETarget, createARMMCInstrInfo);
00369   TargetRegistry::RegisterMCInstrInfo(TheThumbLETarget, createARMMCInstrInfo);
00370   TargetRegistry::RegisterMCInstrInfo(TheThumbBETarget, createARMMCInstrInfo);
00371 
00372   // Register the MC register info.
00373   TargetRegistry::RegisterMCRegInfo(TheARMLETarget, createARMMCRegisterInfo);
00374   TargetRegistry::RegisterMCRegInfo(TheARMBETarget, createARMMCRegisterInfo);
00375   TargetRegistry::RegisterMCRegInfo(TheThumbLETarget, createARMMCRegisterInfo);
00376   TargetRegistry::RegisterMCRegInfo(TheThumbBETarget, createARMMCRegisterInfo);
00377 
00378   // Register the MC subtarget info.
00379   TargetRegistry::RegisterMCSubtargetInfo(TheARMLETarget,
00380                                           ARM_MC::createARMMCSubtargetInfo);
00381   TargetRegistry::RegisterMCSubtargetInfo(TheARMBETarget,
00382                                           ARM_MC::createARMMCSubtargetInfo);
00383   TargetRegistry::RegisterMCSubtargetInfo(TheThumbLETarget,
00384                                           ARM_MC::createARMMCSubtargetInfo);
00385   TargetRegistry::RegisterMCSubtargetInfo(TheThumbBETarget,
00386                                           ARM_MC::createARMMCSubtargetInfo);
00387 
00388   // Register the MC instruction analyzer.
00389   TargetRegistry::RegisterMCInstrAnalysis(TheARMLETarget,
00390                                           createARMMCInstrAnalysis);
00391   TargetRegistry::RegisterMCInstrAnalysis(TheARMBETarget,
00392                                           createARMMCInstrAnalysis);
00393   TargetRegistry::RegisterMCInstrAnalysis(TheThumbLETarget,
00394                                           createARMMCInstrAnalysis);
00395   TargetRegistry::RegisterMCInstrAnalysis(TheThumbBETarget,
00396                                           createARMMCInstrAnalysis);
00397 
00398   // Register the MC Code Emitter
00399   TargetRegistry::RegisterMCCodeEmitter(TheARMLETarget,
00400                                         createARMLEMCCodeEmitter);
00401   TargetRegistry::RegisterMCCodeEmitter(TheARMBETarget,
00402                                         createARMBEMCCodeEmitter);
00403   TargetRegistry::RegisterMCCodeEmitter(TheThumbLETarget,
00404                                         createARMLEMCCodeEmitter);
00405   TargetRegistry::RegisterMCCodeEmitter(TheThumbBETarget,
00406                                         createARMBEMCCodeEmitter);
00407 
00408   // Register the asm backend.
00409   TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend);
00410   TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend);
00411   TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget,
00412                                        createThumbLEAsmBackend);
00413   TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget,
00414                                        createThumbBEAsmBackend);
00415 
00416   // Register the object streamer.
00417   TargetRegistry::RegisterMCObjectStreamer(TheARMLETarget, createMCStreamer);
00418   TargetRegistry::RegisterMCObjectStreamer(TheARMBETarget, createMCStreamer);
00419   TargetRegistry::RegisterMCObjectStreamer(TheThumbLETarget, createMCStreamer);
00420   TargetRegistry::RegisterMCObjectStreamer(TheThumbBETarget, createMCStreamer);
00421 
00422   // Register the asm streamer.
00423   TargetRegistry::RegisterAsmStreamer(TheARMLETarget, createMCAsmStreamer);
00424   TargetRegistry::RegisterAsmStreamer(TheARMBETarget, createMCAsmStreamer);
00425   TargetRegistry::RegisterAsmStreamer(TheThumbLETarget, createMCAsmStreamer);
00426   TargetRegistry::RegisterAsmStreamer(TheThumbBETarget, createMCAsmStreamer);
00427 
00428   // Register the null streamer.
00429   TargetRegistry::RegisterNullStreamer(TheARMLETarget, createARMNullStreamer);
00430   TargetRegistry::RegisterNullStreamer(TheARMBETarget, createARMNullStreamer);
00431   TargetRegistry::RegisterNullStreamer(TheThumbLETarget, createARMNullStreamer);
00432   TargetRegistry::RegisterNullStreamer(TheThumbBETarget, createARMNullStreamer);
00433 
00434   // Register the MCInstPrinter.
00435   TargetRegistry::RegisterMCInstPrinter(TheARMLETarget, createARMMCInstPrinter);
00436   TargetRegistry::RegisterMCInstPrinter(TheARMBETarget, createARMMCInstPrinter);
00437   TargetRegistry::RegisterMCInstPrinter(TheThumbLETarget,
00438                                         createARMMCInstPrinter);
00439   TargetRegistry::RegisterMCInstPrinter(TheThumbBETarget,
00440                                         createARMMCInstPrinter);
00441 
00442   // Register the MC relocation info.
00443   TargetRegistry::RegisterMCRelocationInfo(TheARMLETarget,
00444                                            createARMMCRelocationInfo);
00445   TargetRegistry::RegisterMCRelocationInfo(TheARMBETarget,
00446                                            createARMMCRelocationInfo);
00447   TargetRegistry::RegisterMCRelocationInfo(TheThumbLETarget,
00448                                            createARMMCRelocationInfo);
00449   TargetRegistry::RegisterMCRelocationInfo(TheThumbBETarget,
00450                                            createARMMCRelocationInfo);
00451 }