Home | History | Annotate | Download | only in MCTargetDesc
      1 //===-- AArch64MCTargetDesc.cpp - AArch64 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 AArch64 specific target descriptions.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "AArch64MCTargetDesc.h"
     15 #include "AArch64ELFStreamer.h"
     16 #include "AArch64MCAsmInfo.h"
     17 #include "InstPrinter/AArch64InstPrinter.h"
     18 #include "llvm/ADT/APInt.h"
     19 #include "llvm/MC/MCCodeGenInfo.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/TargetRegistry.h"
     26 #include "llvm/Support/ErrorHandling.h"
     27 
     28 #define GET_REGINFO_MC_DESC
     29 #include "AArch64GenRegisterInfo.inc"
     30 
     31 #define GET_INSTRINFO_MC_DESC
     32 #include "AArch64GenInstrInfo.inc"
     33 
     34 #define GET_SUBTARGETINFO_MC_DESC
     35 #include "AArch64GenSubtargetInfo.inc"
     36 
     37 using namespace llvm;
     38 
     39 MCSubtargetInfo *AArch64_MC::createAArch64MCSubtargetInfo(StringRef TT,
     40                                                           StringRef CPU,
     41                                                           StringRef FS) {
     42   MCSubtargetInfo *X = new MCSubtargetInfo();
     43   InitAArch64MCSubtargetInfo(X, TT, CPU, FS);
     44   return X;
     45 }
     46 
     47 
     48 static MCInstrInfo *createAArch64MCInstrInfo() {
     49   MCInstrInfo *X = new MCInstrInfo();
     50   InitAArch64MCInstrInfo(X);
     51   return X;
     52 }
     53 
     54 static MCRegisterInfo *createAArch64MCRegisterInfo(StringRef Triple) {
     55   MCRegisterInfo *X = new MCRegisterInfo();
     56   InitAArch64MCRegisterInfo(X, AArch64::X30);
     57   return X;
     58 }
     59 
     60 static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI,
     61                                          StringRef TT) {
     62   Triple TheTriple(TT);
     63 
     64   MCAsmInfo *MAI = new AArch64ELFMCAsmInfo();
     65   unsigned Reg = MRI.getDwarfRegNum(AArch64::XSP, true);
     66   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0);
     67   MAI->addInitialFrameState(Inst);
     68 
     69   return MAI;
     70 }
     71 
     72 static MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM,
     73                                                  CodeModel::Model CM,
     74                                                  CodeGenOpt::Level OL) {
     75   MCCodeGenInfo *X = new MCCodeGenInfo();
     76   if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC) {
     77     // On ELF platforms the default static relocation model has a smart enough
     78     // linker to cope with referencing external symbols defined in a shared
     79     // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
     80     RM = Reloc::Static;
     81   }
     82 
     83   if (CM == CodeModel::Default)
     84     CM = CodeModel::Small;
     85   else if (CM == CodeModel::JITDefault) {
     86     // The default MCJIT memory managers make no guarantees about where they can
     87     // find an executable page; JITed code needs to be able to refer to globals
     88     // no matter how far away they are.
     89     CM = CodeModel::Large;
     90   }
     91 
     92   X->InitMCCodeGenInfo(RM, CM, OL);
     93   return X;
     94 }
     95 
     96 static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
     97                                     MCContext &Ctx, MCAsmBackend &MAB,
     98                                     raw_ostream &OS,
     99                                     MCCodeEmitter *Emitter,
    100                                     bool RelaxAll,
    101                                     bool NoExecStack) {
    102   Triple TheTriple(TT);
    103 
    104   return createAArch64ELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);
    105 }
    106 
    107 
    108 static MCInstPrinter *createAArch64MCInstPrinter(const Target &T,
    109                                                  unsigned SyntaxVariant,
    110                                                  const MCAsmInfo &MAI,
    111                                                  const MCInstrInfo &MII,
    112                                                  const MCRegisterInfo &MRI,
    113                                                  const MCSubtargetInfo &STI) {
    114   if (SyntaxVariant == 0)
    115     return new AArch64InstPrinter(MAI, MII, MRI, STI);
    116   return 0;
    117 }
    118 
    119 namespace {
    120 
    121 class AArch64MCInstrAnalysis : public MCInstrAnalysis {
    122 public:
    123   AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
    124 
    125   virtual bool isUnconditionalBranch(const MCInst &Inst) const {
    126     if (Inst.getOpcode() == AArch64::Bcc
    127         && Inst.getOperand(0).getImm() == A64CC::AL)
    128       return true;
    129     return MCInstrAnalysis::isUnconditionalBranch(Inst);
    130   }
    131 
    132   virtual bool isConditionalBranch(const MCInst &Inst) const {
    133     if (Inst.getOpcode() == AArch64::Bcc
    134         && Inst.getOperand(0).getImm() == A64CC::AL)
    135       return false;
    136     return MCInstrAnalysis::isConditionalBranch(Inst);
    137   }
    138 
    139   bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
    140                       uint64_t Size, uint64_t &Target) const {
    141     unsigned LblOperand = Inst.getOpcode() == AArch64::Bcc ? 1 : 0;
    142     // FIXME: We only handle PCRel branches for now.
    143     if (Info->get(Inst.getOpcode()).OpInfo[LblOperand].OperandType
    144         != MCOI::OPERAND_PCREL)
    145       return false;
    146 
    147     int64_t Imm = Inst.getOperand(LblOperand).getImm();
    148     Target = Addr + Imm;
    149     return true;
    150   }
    151 };
    152 
    153 }
    154 
    155 static MCInstrAnalysis *createAArch64MCInstrAnalysis(const MCInstrInfo *Info) {
    156   return new AArch64MCInstrAnalysis(Info);
    157 }
    158 
    159 
    160 
    161 extern "C" void LLVMInitializeAArch64TargetMC() {
    162   // Register the MC asm info.
    163   RegisterMCAsmInfoFn A(TheAArch64Target, createAArch64MCAsmInfo);
    164 
    165   // Register the MC codegen info.
    166   TargetRegistry::RegisterMCCodeGenInfo(TheAArch64Target,
    167                                         createAArch64MCCodeGenInfo);
    168 
    169   // Register the MC instruction info.
    170   TargetRegistry::RegisterMCInstrInfo(TheAArch64Target,
    171                                       createAArch64MCInstrInfo);
    172 
    173   // Register the MC register info.
    174   TargetRegistry::RegisterMCRegInfo(TheAArch64Target,
    175                                     createAArch64MCRegisterInfo);
    176 
    177   // Register the MC subtarget info.
    178   using AArch64_MC::createAArch64MCSubtargetInfo;
    179   TargetRegistry::RegisterMCSubtargetInfo(TheAArch64Target,
    180                                           createAArch64MCSubtargetInfo);
    181 
    182   // Register the MC instruction analyzer.
    183   TargetRegistry::RegisterMCInstrAnalysis(TheAArch64Target,
    184                                           createAArch64MCInstrAnalysis);
    185 
    186   // Register the MC Code Emitter
    187   TargetRegistry::RegisterMCCodeEmitter(TheAArch64Target,
    188                                         createAArch64MCCodeEmitter);
    189 
    190   // Register the asm backend.
    191   TargetRegistry::RegisterMCAsmBackend(TheAArch64Target,
    192                                        createAArch64AsmBackend);
    193 
    194   // Register the object streamer.
    195   TargetRegistry::RegisterMCObjectStreamer(TheAArch64Target,
    196                                            createMCStreamer);
    197 
    198   // Register the MCInstPrinter.
    199   TargetRegistry::RegisterMCInstPrinter(TheAArch64Target,
    200                                         createAArch64MCInstPrinter);
    201 }
    202