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

          Line data    Source code
       1             : //===-- AArch64MCTargetDesc.cpp - AArch64 Target Descriptions ---*- C++ -*-===//
       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 AArch64 specific target descriptions.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "AArch64MCTargetDesc.h"
      15             : #include "AArch64ELFStreamer.h"
      16             : #include "AArch64MCAsmInfo.h"
      17             : #include "AArch64WinCOFFStreamer.h"
      18             : #include "InstPrinter/AArch64InstPrinter.h"
      19             : #include "llvm/MC/MCAsmBackend.h"
      20             : #include "llvm/MC/MCCodeEmitter.h"
      21             : #include "llvm/MC/MCInstrAnalysis.h"
      22             : #include "llvm/MC/MCInstrInfo.h"
      23             : #include "llvm/MC/MCObjectWriter.h"
      24             : #include "llvm/MC/MCRegisterInfo.h"
      25             : #include "llvm/MC/MCStreamer.h"
      26             : #include "llvm/MC/MCSubtargetInfo.h"
      27             : #include "llvm/Support/Endian.h"
      28             : #include "llvm/Support/ErrorHandling.h"
      29             : #include "llvm/Support/TargetRegistry.h"
      30             : 
      31             : using namespace llvm;
      32             : 
      33             : #define GET_INSTRINFO_MC_DESC
      34             : #include "AArch64GenInstrInfo.inc"
      35             : 
      36             : #define GET_SUBTARGETINFO_MC_DESC
      37             : #include "AArch64GenSubtargetInfo.inc"
      38             : 
      39             : #define GET_REGINFO_MC_DESC
      40             : #include "AArch64GenRegisterInfo.inc"
      41             : 
      42        4902 : static MCInstrInfo *createAArch64MCInstrInfo() {
      43        4902 :   MCInstrInfo *X = new MCInstrInfo();
      44             :   InitAArch64MCInstrInfo(X);
      45        4902 :   return X;
      46             : }
      47             : 
      48             : static MCSubtargetInfo *
      49        4806 : createAArch64MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
      50        4806 :   if (CPU.empty())
      51        4491 :     CPU = "generic";
      52             : 
      53        4806 :   return createAArch64MCSubtargetInfoImpl(TT, CPU, FS);
      54             : }
      55             : 
      56        6530 : void AArch64_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
      57     4309800 :   for (unsigned Reg = AArch64::NoRegister + 1;
      58     4316330 :        Reg < AArch64::NUM_TARGET_REGS; ++Reg) {
      59     4309800 :     unsigned CV = MRI->getEncodingValue(Reg);
      60     4309800 :     MRI->mapLLVMRegToCVReg(Reg, CV);
      61             :   }
      62        6530 : }
      63             : 
      64        4957 : static MCRegisterInfo *createAArch64MCRegisterInfo(const Triple &Triple) {
      65        4957 :   MCRegisterInfo *X = new MCRegisterInfo();
      66             :   InitAArch64MCRegisterInfo(X, AArch64::LR);
      67        4957 :   AArch64_MC::initLLVMToCVRegMapping(X);
      68        4957 :   return X;
      69             : }
      70             : 
      71        4939 : static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI,
      72             :                                          const Triple &TheTriple) {
      73             :   MCAsmInfo *MAI;
      74        4939 :   if (TheTriple.isOSBinFormatMachO())
      75         525 :     MAI = new AArch64MCAsmInfoDarwin();
      76             :   else if (TheTriple.isWindowsMSVCEnvironment())
      77          40 :     MAI = new AArch64MCAsmInfoMicrosoftCOFF();
      78        4374 :   else if (TheTriple.isOSBinFormatCOFF())
      79          14 :     MAI = new AArch64MCAsmInfoGNUCOFF();
      80             :   else {
      81             :     assert(TheTriple.isOSBinFormatELF() && "Invalid target");
      82        4360 :     MAI = new AArch64MCAsmInfoELF(TheTriple);
      83             :   }
      84             : 
      85             :   // Initial state of the frame pointer is SP.
      86        4939 :   unsigned Reg = MRI.getDwarfRegNum(AArch64::SP, true);
      87             :   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
      88             :   MAI->addInitialFrameState(Inst);
      89             : 
      90        4939 :   return MAI;
      91             : }
      92             : 
      93        3270 : static MCInstPrinter *createAArch64MCInstPrinter(const Triple &T,
      94             :                                                  unsigned SyntaxVariant,
      95             :                                                  const MCAsmInfo &MAI,
      96             :                                                  const MCInstrInfo &MII,
      97             :                                                  const MCRegisterInfo &MRI) {
      98        3270 :   if (SyntaxVariant == 0)
      99        2860 :     return new AArch64InstPrinter(MAI, MII, MRI);
     100         410 :   if (SyntaxVariant == 1)
     101         410 :     return new AArch64AppleInstPrinter(MAI, MII, MRI);
     102             : 
     103             :   return nullptr;
     104             : }
     105             : 
     106         829 : static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
     107             :                                      std::unique_ptr<MCAsmBackend> &&TAB,
     108             :                                      std::unique_ptr<MCObjectWriter> &&OW,
     109             :                                      std::unique_ptr<MCCodeEmitter> &&Emitter,
     110             :                                      bool RelaxAll) {
     111        2487 :   return createAArch64ELFStreamer(Ctx, std::move(TAB), std::move(OW),
     112         829 :                                   std::move(Emitter), RelaxAll);
     113             : }
     114             : 
     115          35 : static MCStreamer *createMachOStreamer(MCContext &Ctx,
     116             :                                        std::unique_ptr<MCAsmBackend> &&TAB,
     117             :                                        std::unique_ptr<MCObjectWriter> &&OW,
     118             :                                        std::unique_ptr<MCCodeEmitter> &&Emitter,
     119             :                                        bool RelaxAll,
     120             :                                        bool DWARFMustBeAtTheEnd) {
     121          35 :   return createMachOStreamer(Ctx, std::move(TAB), std::move(OW),
     122             :                              std::move(Emitter), RelaxAll, DWARFMustBeAtTheEnd,
     123          35 :                              /*LabelSections*/ true);
     124             : }
     125             : 
     126             : static MCStreamer *
     127          16 : createWinCOFFStreamer(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
     128             :                       std::unique_ptr<MCObjectWriter> &&OW,
     129             :                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
     130             :                       bool IncrementalLinkerCompatible) {
     131          48 :   return createAArch64WinCOFFStreamer(Ctx, std::move(TAB), std::move(OW),
     132             :                                       std::move(Emitter), RelaxAll,
     133          16 :                                       IncrementalLinkerCompatible);
     134             : }
     135             : 
     136             : namespace {
     137             : 
     138             : class AArch64MCInstrAnalysis : public MCInstrAnalysis {
     139             : public:
     140         748 :   AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
     141             : 
     142         257 :   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
     143             :                       uint64_t &Target) const override {
     144             :     // Search for a PC-relative argument.
     145             :     // This will handle instructions like bcc (where the first argument is the
     146             :     // condition code) and cbz (where it is a register).
     147         257 :     const auto &Desc = Info->get(Inst.getOpcode());
     148         390 :     for (unsigned i = 0, e = Inst.getNumOperands(); i != e; i++) {
     149         351 :       if (Desc.OpInfo[i].OperandType == MCOI::OPERAND_PCREL) {
     150         218 :         int64_t Imm = Inst.getOperand(i).getImm() * 4;
     151         218 :         Target = Addr + Imm;
     152         218 :         return true;
     153             :       }
     154             :     }
     155             :     return false;
     156             :   }
     157             : 
     158             :   std::vector<std::pair<uint64_t, uint64_t>>
     159           9 :   findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
     160             :                  uint64_t GotPltSectionVA,
     161             :                  const Triple &TargetTriple) const override {
     162             :     // Do a lightweight parsing of PLT entries.
     163             :     std::vector<std::pair<uint64_t, uint64_t>> Result;
     164         116 :     for (uint64_t Byte = 0, End = PltContents.size(); Byte + 7 < End;
     165         107 :          Byte += 4) {
     166         107 :       uint32_t Insn = support::endian::read32le(PltContents.data() + Byte);
     167             :       // Check for adrp.
     168         107 :       if ((Insn & 0x9f000000) != 0x90000000)
     169             :         continue;
     170          56 :       uint64_t Imm = (((PltSectionVA + Byte) >> 12) << 12) +
     171          56 :             (((Insn >> 29) & 3) << 12) + (((Insn >> 5) & 0x3ffff) << 14);
     172          28 :       uint32_t Insn2 = support::endian::read32le(PltContents.data() + Byte + 4);
     173             :       // Check for: ldr Xt, [Xn, #pimm].
     174          28 :       if (Insn2 >> 22 == 0x3e5) {
     175          28 :         Imm += ((Insn2 >> 10) & 0xfff) << 3;
     176          28 :         Result.push_back(std::make_pair(PltSectionVA + Byte, Imm));
     177             :         Byte += 4;
     178             :       }
     179             :     }
     180           9 :     return Result;
     181             :   }
     182             : };
     183             : 
     184             : } // end anonymous namespace
     185             : 
     186         748 : static MCInstrAnalysis *createAArch64InstrAnalysis(const MCInstrInfo *Info) {
     187         748 :   return new AArch64MCInstrAnalysis(Info);
     188             : }
     189             : 
     190             : // Force static initialization.
     191       79020 : extern "C" void LLVMInitializeAArch64TargetMC() {
     192      553140 :   for (Target *T : {&getTheAArch64leTarget(), &getTheAArch64beTarget(),
     193      316080 :                     &getTheARM64Target()}) {
     194             :     // Register the MC asm info.
     195             :     RegisterMCAsmInfoFn X(*T, createAArch64MCAsmInfo);
     196             : 
     197             :     // Register the MC instruction info.
     198             :     TargetRegistry::RegisterMCInstrInfo(*T, createAArch64MCInstrInfo);
     199             : 
     200             :     // Register the MC register info.
     201             :     TargetRegistry::RegisterMCRegInfo(*T, createAArch64MCRegisterInfo);
     202             : 
     203             :     // Register the MC subtarget info.
     204             :     TargetRegistry::RegisterMCSubtargetInfo(*T, createAArch64MCSubtargetInfo);
     205             : 
     206             :     // Register the MC instruction analyzer.
     207             :     TargetRegistry::RegisterMCInstrAnalysis(*T, createAArch64InstrAnalysis);
     208             : 
     209             :     // Register the MC Code Emitter
     210             :     TargetRegistry::RegisterMCCodeEmitter(*T, createAArch64MCCodeEmitter);
     211             : 
     212             :     // Register the obj streamers.
     213             :     TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
     214             :     TargetRegistry::RegisterMachOStreamer(*T, createMachOStreamer);
     215             :     TargetRegistry::RegisterCOFFStreamer(*T, createWinCOFFStreamer);
     216             : 
     217             :     // Register the obj target streamer.
     218             :     TargetRegistry::RegisterObjectTargetStreamer(
     219             :         *T, createAArch64ObjectTargetStreamer);
     220             : 
     221             :     // Register the asm streamer.
     222             :     TargetRegistry::RegisterAsmTargetStreamer(*T,
     223             :                                               createAArch64AsmTargetStreamer);
     224             :     // Register the MCInstPrinter.
     225             :     TargetRegistry::RegisterMCInstPrinter(*T, createAArch64MCInstPrinter);
     226             :   }
     227             : 
     228             :   // Register the asm backend.
     229      237060 :   for (Target *T : {&getTheAArch64leTarget(), &getTheARM64Target()})
     230             :     TargetRegistry::RegisterMCAsmBackend(*T, createAArch64leAsmBackend);
     231       79020 :   TargetRegistry::RegisterMCAsmBackend(getTheAArch64beTarget(),
     232             :                                        createAArch64beAsmBackend);
     233       79020 : }

Generated by: LCOV version 1.13