Home | History | Annotate | Download | only in MCTargetDesc
      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 "InstPrinter/AArch64InstPrinter.h"
     18 #include "llvm/MC/MCCodeGenInfo.h"
     19 #include "llvm/MC/MCInstrInfo.h"
     20 #include "llvm/MC/MCRegisterInfo.h"
     21 #include "llvm/MC/MCStreamer.h"
     22 #include "llvm/MC/MCSubtargetInfo.h"
     23 #include "llvm/Support/ErrorHandling.h"
     24 #include "llvm/Support/TargetRegistry.h"
     25 
     26 using namespace llvm;
     27 
     28 #define GET_INSTRINFO_MC_DESC
     29 #include "AArch64GenInstrInfo.inc"
     30 
     31 #define GET_SUBTARGETINFO_MC_DESC
     32 #include "AArch64GenSubtargetInfo.inc"
     33 
     34 #define GET_REGINFO_MC_DESC
     35 #include "AArch64GenRegisterInfo.inc"
     36 
     37 static MCInstrInfo *createAArch64MCInstrInfo() {
     38   MCInstrInfo *X = new MCInstrInfo();
     39   InitAArch64MCInstrInfo(X);
     40   return X;
     41 }
     42 
     43 static MCSubtargetInfo *
     44 createAArch64MCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) {
     45   MCSubtargetInfo *X = new MCSubtargetInfo();
     46 
     47   if (CPU.empty())
     48     CPU = "generic";
     49 
     50   InitAArch64MCSubtargetInfo(X, TT, CPU, FS);
     51   return X;
     52 }
     53 
     54 static MCRegisterInfo *createAArch64MCRegisterInfo(StringRef Triple) {
     55   MCRegisterInfo *X = new MCRegisterInfo();
     56   InitAArch64MCRegisterInfo(X, AArch64::LR);
     57   return X;
     58 }
     59 
     60 static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI,
     61                                          StringRef TT) {
     62   Triple TheTriple(TT);
     63 
     64   MCAsmInfo *MAI;
     65   if (TheTriple.isOSDarwin())
     66     MAI = new AArch64MCAsmInfoDarwin();
     67   else {
     68     assert(TheTriple.isOSBinFormatELF() && "Only expect Darwin or ELF");
     69     MAI = new AArch64MCAsmInfoELF(TT);
     70   }
     71 
     72   // Initial state of the frame pointer is SP.
     73   unsigned Reg = MRI.getDwarfRegNum(AArch64::SP, true);
     74   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
     75   MAI->addInitialFrameState(Inst);
     76 
     77   return MAI;
     78 }
     79 
     80 static MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM,
     81                                                  CodeModel::Model CM,
     82                                                  CodeGenOpt::Level OL) {
     83   Triple TheTriple(TT);
     84   assert((TheTriple.isOSBinFormatELF() || TheTriple.isOSBinFormatMachO()) &&
     85          "Only expect Darwin and ELF targets");
     86 
     87   if (CM == CodeModel::Default)
     88     CM = CodeModel::Small;
     89   // The default MCJIT memory managers make no guarantees about where they can
     90   // find an executable page; JITed code needs to be able to refer to globals
     91   // no matter how far away they are.
     92   else if (CM == CodeModel::JITDefault)
     93     CM = CodeModel::Large;
     94   else if (CM != CodeModel::Small && CM != CodeModel::Large)
     95     report_fatal_error(
     96         "Only small and large code models are allowed on AArch64");
     97 
     98   // AArch64 Darwin is always PIC.
     99   if (TheTriple.isOSDarwin())
    100     RM = Reloc::PIC_;
    101   // On ELF platforms the default static relocation model has a smart enough
    102   // linker to cope with referencing external symbols defined in a shared
    103   // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
    104   else if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC)
    105     RM = Reloc::Static;
    106 
    107   MCCodeGenInfo *X = new MCCodeGenInfo();
    108   X->InitMCCodeGenInfo(RM, CM, OL);
    109   return X;
    110 }
    111 
    112 static MCInstPrinter *createAArch64MCInstPrinter(const Target &T,
    113                                                  unsigned SyntaxVariant,
    114                                                  const MCAsmInfo &MAI,
    115                                                  const MCInstrInfo &MII,
    116                                                  const MCRegisterInfo &MRI,
    117                                                  const MCSubtargetInfo &STI) {
    118   if (SyntaxVariant == 0)
    119     return new AArch64InstPrinter(MAI, MII, MRI, STI);
    120   if (SyntaxVariant == 1)
    121     return new AArch64AppleInstPrinter(MAI, MII, MRI, STI);
    122 
    123   return nullptr;
    124 }
    125 
    126 static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
    127                                     MCContext &Ctx, MCAsmBackend &TAB,
    128                                     raw_ostream &OS, MCCodeEmitter *Emitter,
    129                                     const MCSubtargetInfo &STI, bool RelaxAll,
    130                                     bool NoExecStack) {
    131   Triple TheTriple(TT);
    132 
    133   if (TheTriple.isOSDarwin())
    134     return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
    135                                /*LabelSections*/ true);
    136 
    137   return createAArch64ELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack);
    138 }
    139 
    140 // Force static initialization.
    141 extern "C" void LLVMInitializeAArch64TargetMC() {
    142   // Register the MC asm info.
    143   RegisterMCAsmInfoFn X(TheAArch64leTarget, createAArch64MCAsmInfo);
    144   RegisterMCAsmInfoFn Y(TheAArch64beTarget, createAArch64MCAsmInfo);
    145   RegisterMCAsmInfoFn Z(TheARM64leTarget, createAArch64MCAsmInfo);
    146   RegisterMCAsmInfoFn W(TheARM64beTarget, createAArch64MCAsmInfo);
    147 
    148   // Register the MC codegen info.
    149   TargetRegistry::RegisterMCCodeGenInfo(TheAArch64leTarget,
    150                                         createAArch64MCCodeGenInfo);
    151   TargetRegistry::RegisterMCCodeGenInfo(TheAArch64beTarget,
    152                                         createAArch64MCCodeGenInfo);
    153   TargetRegistry::RegisterMCCodeGenInfo(TheARM64leTarget,
    154                                         createAArch64MCCodeGenInfo);
    155   TargetRegistry::RegisterMCCodeGenInfo(TheARM64beTarget,
    156                                         createAArch64MCCodeGenInfo);
    157 
    158   // Register the MC instruction info.
    159   TargetRegistry::RegisterMCInstrInfo(TheAArch64leTarget,
    160                                       createAArch64MCInstrInfo);
    161   TargetRegistry::RegisterMCInstrInfo(TheAArch64beTarget,
    162                                       createAArch64MCInstrInfo);
    163   TargetRegistry::RegisterMCInstrInfo(TheARM64leTarget,
    164                                       createAArch64MCInstrInfo);
    165   TargetRegistry::RegisterMCInstrInfo(TheARM64beTarget,
    166                                       createAArch64MCInstrInfo);
    167 
    168   // Register the MC register info.
    169   TargetRegistry::RegisterMCRegInfo(TheAArch64leTarget,
    170                                     createAArch64MCRegisterInfo);
    171   TargetRegistry::RegisterMCRegInfo(TheAArch64beTarget,
    172                                     createAArch64MCRegisterInfo);
    173   TargetRegistry::RegisterMCRegInfo(TheARM64leTarget,
    174                                     createAArch64MCRegisterInfo);
    175   TargetRegistry::RegisterMCRegInfo(TheARM64beTarget,
    176                                     createAArch64MCRegisterInfo);
    177 
    178   // Register the MC subtarget info.
    179   TargetRegistry::RegisterMCSubtargetInfo(TheAArch64leTarget,
    180                                           createAArch64MCSubtargetInfo);
    181   TargetRegistry::RegisterMCSubtargetInfo(TheAArch64beTarget,
    182                                           createAArch64MCSubtargetInfo);
    183   TargetRegistry::RegisterMCSubtargetInfo(TheARM64leTarget,
    184                                           createAArch64MCSubtargetInfo);
    185   TargetRegistry::RegisterMCSubtargetInfo(TheARM64beTarget,
    186                                           createAArch64MCSubtargetInfo);
    187 
    188   // Register the asm backend.
    189   TargetRegistry::RegisterMCAsmBackend(TheAArch64leTarget,
    190                                        createAArch64leAsmBackend);
    191   TargetRegistry::RegisterMCAsmBackend(TheAArch64beTarget,
    192                                        createAArch64beAsmBackend);
    193   TargetRegistry::RegisterMCAsmBackend(TheARM64leTarget,
    194                                        createAArch64leAsmBackend);
    195   TargetRegistry::RegisterMCAsmBackend(TheARM64beTarget,
    196                                        createAArch64beAsmBackend);
    197 
    198   // Register the MC Code Emitter
    199   TargetRegistry::RegisterMCCodeEmitter(TheAArch64leTarget,
    200                                         createAArch64MCCodeEmitter);
    201   TargetRegistry::RegisterMCCodeEmitter(TheAArch64beTarget,
    202                                         createAArch64MCCodeEmitter);
    203   TargetRegistry::RegisterMCCodeEmitter(TheARM64leTarget,
    204                                         createAArch64MCCodeEmitter);
    205   TargetRegistry::RegisterMCCodeEmitter(TheARM64beTarget,
    206                                         createAArch64MCCodeEmitter);
    207 
    208   // Register the object streamer.
    209   TargetRegistry::RegisterMCObjectStreamer(TheAArch64leTarget,
    210                                            createMCStreamer);
    211   TargetRegistry::RegisterMCObjectStreamer(TheAArch64beTarget,
    212                                            createMCStreamer);
    213   TargetRegistry::RegisterMCObjectStreamer(TheARM64leTarget, createMCStreamer);
    214   TargetRegistry::RegisterMCObjectStreamer(TheARM64beTarget, createMCStreamer);
    215 
    216   // Register the MCInstPrinter.
    217   TargetRegistry::RegisterMCInstPrinter(TheAArch64leTarget,
    218                                         createAArch64MCInstPrinter);
    219   TargetRegistry::RegisterMCInstPrinter(TheAArch64beTarget,
    220                                         createAArch64MCInstPrinter);
    221   TargetRegistry::RegisterMCInstPrinter(TheARM64leTarget,
    222                                         createAArch64MCInstPrinter);
    223   TargetRegistry::RegisterMCInstPrinter(TheARM64beTarget,
    224                                         createAArch64MCInstPrinter);
    225 }
    226