LCOV - code coverage report
Current view: top level - lib/Target/ARM/MCTargetDesc - ARMMCTargetDesc.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 142 142 100.0 %
Date: 2017-09-14 15:23:50 Functions: 24 26 92.3 %
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/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          26 : static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
      35             :                                   std::string &Info) {
      36          73 :   if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
      37          54 :       (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
      38          62 :       (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          24 :       (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
      42          24 :     if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
      43          16 :       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
      44           4 :         Info = "deprecated since v7, use 'isb'";
      45           4 :         return true;
      46             :       }
      47             : 
      48             :       // Checks for the deprecated CP15DSB encoding:
      49             :       // mcr p15, #0, rX, c7, c10, #4
      50           8 :       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
      51           4 :         Info = "deprecated since v7, use 'dsb'";
      52           4 :         return true;
      53             :       }
      54             :     }
      55             :     // Checks for the deprecated CP15DMB encoding:
      56             :     // mcr p15, #0, rX, c7, c10, #5
      57          12 :     if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
      58           8 :         (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
      59           4 :       Info = "deprecated since v7, use 'dmb'";
      60           4 :       return true;
      61             :     }
      62             :   }
      63             :   return false;
      64             : }
      65             : 
      66        2766 : static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
      67             :                                  std::string &Info) {
      68        9974 :   if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
      69        2221 :       MI.getOperand(1).getImm() != 8) {
      70          13 :     Info = "applying IT instruction to more than one subsequent instruction is "
      71             :            "deprecated";
      72          13 :     return true;
      73             :   }
      74             : 
      75             :   return false;
      76             : }
      77             : 
      78         130 : 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         545 :   for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
      85             :     assert(MI.getOperand(OI).isReg() && "expected register");
      86         664 :     if (MI.getOperand(OI).getReg() == ARM::SP ||
      87         305 :         MI.getOperand(OI).getReg() == ARM::PC) {
      88          74 :       Info = "use of SP or PC in the list is deprecated";
      89          74 :       return true;
      90             :     }
      91             :   }
      92             :   return false;
      93             : }
      94             : 
      95         118 : 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         118 :   bool ListContainsPC = false, ListContainsLR = false;
     102         563 :   for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
     103             :     assert(MI.getOperand(OI).isReg() && "expected register");
     104         369 :     switch (MI.getOperand(OI).getReg()) {
     105             :     default:
     106             :       break;
     107          31 :     case ARM::LR:
     108          31 :       ListContainsLR = true;
     109          31 :       break;
     110          31 :     case ARM::PC:
     111          31 :       ListContainsPC = true;
     112          31 :       break;
     113          42 :     case ARM::SP:
     114          42 :       Info = "use of SP in the list is deprecated";
     115          42 :       return true;
     116             :     }
     117             :   }
     118             : 
     119          76 :   if (ListContainsPC && ListContainsLR) {
     120          20 :     Info = "use of LR and PC simultaneously in the list is deprecated";
     121          20 :     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       13736 : std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
     134       13736 :   std::string ARMArchFeature;
     135             : 
     136       13736 :   ARM::ArchKind ArchID = ARM::parseArch(TT.getArchName());
     137       13736 :   if (ArchID != ARM::ArchKind::INVALID &&  (CPU.empty() || CPU == "generic"))
     138       42882 :     ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();
     139             : 
     140             :   if (TT.isThumb()) {
     141        5460 :     if (ARMArchFeature.empty())
     142             :       ARMArchFeature = "+thumb-mode,+v4t";
     143             :     else
     144             :       ARMArchFeature += ",+thumb-mode,+v4t";
     145             :   }
     146             : 
     147       13736 :   if (TT.isOSNaCl()) {
     148          24 :     if (ARMArchFeature.empty())
     149             :       ARMArchFeature = "+nacl-trap";
     150             :     else
     151             :       ARMArchFeature += ",+nacl-trap";
     152             :   }
     153             : 
     154       13736 :   return ARMArchFeature;
     155             : }
     156             : 
     157        7494 : MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
     158             :                                                   StringRef CPU, StringRef FS) {
     159       14988 :   std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
     160        7494 :   if (!FS.empty()) {
     161        1168 :     if (!ArchFS.empty())
     162        4404 :       ArchFS = (Twine(ArchFS) + "," + FS).str();
     163             :     else
     164         868 :       ArchFS = FS;
     165             :   }
     166             : 
     167       14988 :   return createARMMCSubtargetInfoImpl(TT, CPU, ArchFS);
     168             : }
     169             : 
     170        4459 : static MCInstrInfo *createARMMCInstrInfo() {
     171        4459 :   MCInstrInfo *X = new MCInstrInfo();
     172        4459 :   InitARMMCInstrInfo(X);
     173        4459 :   return X;
     174             : }
     175             : 
     176        4399 : static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
     177        8798 :   MCRegisterInfo *X = new MCRegisterInfo();
     178        4399 :   InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
     179        4399 :   return X;
     180             : }
     181             : 
     182        4368 : static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
     183             :                                      const Triple &TheTriple) {
     184             :   MCAsmInfo *MAI;
     185        6578 :   if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
     186        1132 :     MAI = new ARMMCAsmInfoDarwin(TheTriple);
     187             :   else if (TheTriple.isWindowsMSVCEnvironment())
     188          72 :     MAI = new ARMCOFFMCAsmInfoMicrosoft();
     189        3164 :   else if (TheTriple.isOSWindows())
     190          55 :     MAI = new ARMCOFFMCAsmInfoGNU();
     191             :   else
     192        3109 :     MAI = new ARMELFMCAsmInfo(TheTriple);
     193             : 
     194        4368 :   unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
     195       13104 :   MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0));
     196             : 
     197        4368 :   return MAI;
     198             : }
     199             : 
     200         353 : static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
     201             :                                      MCAsmBackend &MAB, raw_pwrite_stream &OS,
     202             :                                      MCCodeEmitter *Emitter, bool RelaxAll) {
     203         353 :   return createARMELFStreamer(Ctx, MAB, OS, Emitter, false,
     204         637 :                               (T.getArch() == Triple::thumb ||
     205         637 :                                T.getArch() == Triple::thumbeb));
     206             : }
     207             : 
     208         112 : static MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB,
     209             :                                           raw_pwrite_stream &OS,
     210             :                                           MCCodeEmitter *Emitter, bool RelaxAll,
     211             :                                           bool DWARFMustBeAtTheEnd) {
     212         112 :   return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd);
     213             : }
     214             : 
     215        3266 : static MCInstPrinter *createARMMCInstPrinter(const Triple &T,
     216             :                                              unsigned SyntaxVariant,
     217             :                                              const MCAsmInfo &MAI,
     218             :                                              const MCInstrInfo &MII,
     219             :                                              const MCRegisterInfo &MRI) {
     220        3266 :   if (SyntaxVariant == 0)
     221        3266 :     return new ARMInstPrinter(MAI, MII, MRI);
     222             :   return nullptr;
     223             : }
     224             : 
     225          34 : static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT,
     226             :                                                    MCContext &Ctx) {
     227          34 :   if (TT.isOSBinFormatMachO())
     228          30 :     return createARMMachORelocationInfo(Ctx);
     229             :   // Default to the stock relocation info.
     230           4 :   return llvm::createMCRelocationInfo(TT, Ctx);
     231             : }
     232             : 
     233             : namespace {
     234             : 
     235         127 : class ARMMCInstrAnalysis : public MCInstrAnalysis {
     236             : public:
     237         254 :   ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
     238             : 
     239       11383 :   bool isUnconditionalBranch(const MCInst &Inst) const override {
     240             :     // BCCs with the "always" predicate are unconditional branches.
     241       11482 :     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
     242             :       return true;
     243       22714 :     return MCInstrAnalysis::isUnconditionalBranch(Inst);
     244             :   }
     245             : 
     246       11269 :   bool isConditionalBranch(const MCInst &Inst) const override {
     247             :     // BCCs with the "always" predicate are unconditional branches.
     248       11342 :     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
     249             :       return false;
     250       22538 :     return MCInstrAnalysis::isConditionalBranch(Inst);
     251             :   }
     252             : 
     253         277 :   bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
     254             :                       uint64_t Size, uint64_t &Target) const override {
     255             :     // We only handle PCRel branches for now.
     256         554 :     if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
     257             :       return false;
     258             : 
     259         268 :     int64_t Imm = Inst.getOperand(0).getImm();
     260         268 :     Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes.
     261         268 :     return true;
     262             :   }
     263             : };
     264             : 
     265         118 : class ThumbMCInstrAnalysis : public ARMMCInstrAnalysis {
     266             : public:
     267         118 :   ThumbMCInstrAnalysis(const MCInstrInfo *Info) : ARMMCInstrAnalysis(Info) {}
     268             : 
     269         452 :   bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
     270             :                       uint64_t Size, uint64_t &Target) const override {
     271             :     // We only handle PCRel branches for now.
     272         904 :     if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
     273             :       return false;
     274             : 
     275         202 :     int64_t Imm = Inst.getOperand(0).getImm();
     276         202 :     Target = Addr+Imm+4; // In Thumb mode the PC is always off by 4 bytes.
     277         202 :     return true;
     278             :   }
     279             : };
     280             : 
     281             : }
     282             : 
     283          68 : static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
     284         136 :   return new ARMMCInstrAnalysis(Info);
     285             : }
     286             : 
     287          59 : static MCInstrAnalysis *createThumbMCInstrAnalysis(const MCInstrInfo *Info) {
     288         118 :   return new ThumbMCInstrAnalysis(Info);
     289             : }
     290             : 
     291             : // Force static initialization.
     292       56330 : extern "C" void LLVMInitializeARMTargetMC() {
     293      563300 :   for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
     294      168990 :                     &getTheThumbLETarget(), &getTheThumbBETarget()}) {
     295             :     // Register the MC asm info.
     296      225320 :     RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
     297             : 
     298             :     // Register the MC instruction info.
     299      450640 :     TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
     300             : 
     301             :     // Register the MC register info.
     302      450640 :     TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
     303             : 
     304             :     // Register the MC subtarget info.
     305      450640 :     TargetRegistry::RegisterMCSubtargetInfo(*T,
     306             :                                             ARM_MC::createARMMCSubtargetInfo);
     307             : 
     308      450640 :     TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
     309      450640 :     TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer);
     310      450640 :     TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer);
     311             : 
     312             :     // Register the obj target streamer.
     313      450640 :     TargetRegistry::RegisterObjectTargetStreamer(*T,
     314             :                                                  createARMObjectTargetStreamer);
     315             : 
     316             :     // Register the asm streamer.
     317      450640 :     TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer);
     318             : 
     319             :     // Register the null TargetStreamer.
     320      450640 :     TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer);
     321             : 
     322             :     // Register the MCInstPrinter.
     323      450640 :     TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter);
     324             : 
     325             :     // Register the MC relocation info.
     326      450640 :     TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo);
     327             :   }
     328             : 
     329             :   // Register the MC instruction analyzer.
     330      225320 :   for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget()})
     331      225320 :     TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis);
     332      225320 :   for (Target *T : {&getTheThumbLETarget(), &getTheThumbBETarget()})
     333      225320 :     TargetRegistry::RegisterMCInstrAnalysis(*T, createThumbMCInstrAnalysis);
     334             : 
     335             :   // Register the MC Code Emitter
     336      225320 :   for (Target *T : {&getTheARMLETarget(), &getTheThumbLETarget()})
     337      225320 :     TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
     338      225320 :   for (Target *T : {&getTheARMBETarget(), &getTheThumbBETarget()})
     339      225320 :     TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
     340             : 
     341             :   // Register the asm backend.
     342      112660 :   TargetRegistry::RegisterMCAsmBackend(getTheARMLETarget(),
     343             :                                        createARMLEAsmBackend);
     344      112660 :   TargetRegistry::RegisterMCAsmBackend(getTheARMBETarget(),
     345             :                                        createARMBEAsmBackend);
     346      112660 :   TargetRegistry::RegisterMCAsmBackend(getTheThumbLETarget(),
     347             :                                        createThumbLEAsmBackend);
     348      112660 :   TargetRegistry::RegisterMCAsmBackend(getTheThumbBETarget(),
     349             :                                        createThumbBEAsmBackend);
     350      273248 : }

Generated by: LCOV version 1.13