LCOV - code coverage report
Current view: top level - lib/Target/ARM/MCTargetDesc - ARMMCTargetDesc.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 107 107 100.0 %
Date: 2018-10-20 13:21:21 Functions: 20 20 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13