Home | History | Annotate | Download | only in MCTargetDesc
      1 //===-- X86MCTargetDesc.cpp - X86 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 X86 specific target descriptions.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "X86MCTargetDesc.h"
     15 #include "InstPrinter/X86ATTInstPrinter.h"
     16 #include "InstPrinter/X86IntelInstPrinter.h"
     17 #include "X86MCAsmInfo.h"
     18 #include "llvm/ADT/Triple.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/MC/MachineLocation.h"
     26 #include "llvm/Support/ErrorHandling.h"
     27 #include "llvm/Support/Host.h"
     28 #include "llvm/Support/TargetRegistry.h"
     29 
     30 #if _MSC_VER
     31 #include <intrin.h>
     32 #endif
     33 
     34 using namespace llvm;
     35 
     36 #define GET_REGINFO_MC_DESC
     37 #include "X86GenRegisterInfo.inc"
     38 
     39 #define GET_INSTRINFO_MC_DESC
     40 #include "X86GenInstrInfo.inc"
     41 
     42 #define GET_SUBTARGETINFO_MC_DESC
     43 #include "X86GenSubtargetInfo.inc"
     44 
     45 std::string X86_MC::ParseX86Triple(const Triple &TT) {
     46   std::string FS;
     47   if (TT.getArch() == Triple::x86_64)
     48     FS = "+64bit-mode,-32bit-mode,-16bit-mode";
     49   else if (TT.getEnvironment() != Triple::CODE16)
     50     FS = "-64bit-mode,+32bit-mode,-16bit-mode";
     51   else
     52     FS = "-64bit-mode,-32bit-mode,+16bit-mode";
     53 
     54   return FS;
     55 }
     56 
     57 unsigned X86_MC::getDwarfRegFlavour(const Triple &TT, bool isEH) {
     58   if (TT.getArch() == Triple::x86_64)
     59     return DWARFFlavour::X86_64;
     60 
     61   if (TT.isOSDarwin())
     62     return isEH ? DWARFFlavour::X86_32_DarwinEH : DWARFFlavour::X86_32_Generic;
     63   if (TT.isOSCygMing())
     64     // Unsupported by now, just quick fallback
     65     return DWARFFlavour::X86_32_Generic;
     66   return DWARFFlavour::X86_32_Generic;
     67 }
     68 
     69 void X86_MC::InitLLVM2SEHRegisterMapping(MCRegisterInfo *MRI) {
     70   // FIXME: TableGen these.
     71   for (unsigned Reg = X86::NoRegister+1; Reg < X86::NUM_TARGET_REGS; ++Reg) {
     72     unsigned SEH = MRI->getEncodingValue(Reg);
     73     MRI->mapLLVMRegToSEHReg(Reg, SEH);
     74   }
     75 }
     76 
     77 MCSubtargetInfo *X86_MC::createX86MCSubtargetInfo(const Triple &TT,
     78                                                   StringRef CPU, StringRef FS) {
     79   std::string ArchFS = X86_MC::ParseX86Triple(TT);
     80   if (!FS.empty()) {
     81     if (!ArchFS.empty())
     82       ArchFS = (Twine(ArchFS) + "," + FS).str();
     83     else
     84       ArchFS = FS;
     85   }
     86 
     87   std::string CPUName = CPU;
     88   if (CPUName.empty())
     89     CPUName = "generic";
     90 
     91   return createX86MCSubtargetInfoImpl(TT, CPUName, ArchFS);
     92 }
     93 
     94 static MCInstrInfo *createX86MCInstrInfo() {
     95   MCInstrInfo *X = new MCInstrInfo();
     96   InitX86MCInstrInfo(X);
     97   return X;
     98 }
     99 
    100 static MCRegisterInfo *createX86MCRegisterInfo(const Triple &TT) {
    101   unsigned RA = (TT.getArch() == Triple::x86_64)
    102                     ? X86::RIP  // Should have dwarf #16.
    103                     : X86::EIP; // Should have dwarf #8.
    104 
    105   MCRegisterInfo *X = new MCRegisterInfo();
    106   InitX86MCRegisterInfo(X, RA, X86_MC::getDwarfRegFlavour(TT, false),
    107                         X86_MC::getDwarfRegFlavour(TT, true), RA);
    108   X86_MC::InitLLVM2SEHRegisterMapping(X);
    109   return X;
    110 }
    111 
    112 static MCAsmInfo *createX86MCAsmInfo(const MCRegisterInfo &MRI,
    113                                      const Triple &TheTriple) {
    114   bool is64Bit = TheTriple.getArch() == Triple::x86_64;
    115 
    116   MCAsmInfo *MAI;
    117   if (TheTriple.isOSBinFormatMachO()) {
    118     if (is64Bit)
    119       MAI = new X86_64MCAsmInfoDarwin(TheTriple);
    120     else
    121       MAI = new X86MCAsmInfoDarwin(TheTriple);
    122   } else if (TheTriple.isOSBinFormatELF()) {
    123     // Force the use of an ELF container.
    124     MAI = new X86ELFMCAsmInfo(TheTriple);
    125   } else if (TheTriple.isWindowsMSVCEnvironment() ||
    126              TheTriple.isWindowsCoreCLREnvironment()) {
    127     MAI = new X86MCAsmInfoMicrosoft(TheTriple);
    128   } else if (TheTriple.isOSCygMing() ||
    129              TheTriple.isWindowsItaniumEnvironment()) {
    130     MAI = new X86MCAsmInfoGNUCOFF(TheTriple);
    131   } else {
    132     // The default is ELF.
    133     MAI = new X86ELFMCAsmInfo(TheTriple);
    134   }
    135 
    136   // Initialize initial frame state.
    137   // Calculate amount of bytes used for return address storing
    138   int stackGrowth = is64Bit ? -8 : -4;
    139 
    140   // Initial state of the frame pointer is esp+stackGrowth.
    141   unsigned StackPtr = is64Bit ? X86::RSP : X86::ESP;
    142   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(
    143       nullptr, MRI.getDwarfRegNum(StackPtr, true), -stackGrowth);
    144   MAI->addInitialFrameState(Inst);
    145 
    146   // Add return address to move list
    147   unsigned InstPtr = is64Bit ? X86::RIP : X86::EIP;
    148   MCCFIInstruction Inst2 = MCCFIInstruction::createOffset(
    149       nullptr, MRI.getDwarfRegNum(InstPtr, true), stackGrowth);
    150   MAI->addInitialFrameState(Inst2);
    151 
    152   return MAI;
    153 }
    154 
    155 static MCCodeGenInfo *createX86MCCodeGenInfo(const Triple &TT, Reloc::Model RM,
    156                                              CodeModel::Model CM,
    157                                              CodeGenOpt::Level OL) {
    158   MCCodeGenInfo *X = new MCCodeGenInfo();
    159 
    160   bool is64Bit = TT.getArch() == Triple::x86_64;
    161 
    162   if (RM == Reloc::Default) {
    163     // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode.
    164     // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we
    165     // use static relocation model by default.
    166     if (TT.isOSDarwin()) {
    167       if (is64Bit)
    168         RM = Reloc::PIC_;
    169       else
    170         RM = Reloc::DynamicNoPIC;
    171     } else if (TT.isOSWindows() && is64Bit)
    172       RM = Reloc::PIC_;
    173     else
    174       RM = Reloc::Static;
    175   }
    176 
    177   // ELF and X86-64 don't have a distinct DynamicNoPIC model.  DynamicNoPIC
    178   // is defined as a model for code which may be used in static or dynamic
    179   // executables but not necessarily a shared library. On X86-32 we just
    180   // compile in -static mode, in x86-64 we use PIC.
    181   if (RM == Reloc::DynamicNoPIC) {
    182     if (is64Bit)
    183       RM = Reloc::PIC_;
    184     else if (!TT.isOSDarwin())
    185       RM = Reloc::Static;
    186   }
    187 
    188   // If we are on Darwin, disallow static relocation model in X86-64 mode, since
    189   // the Mach-O file format doesn't support it.
    190   if (RM == Reloc::Static && TT.isOSDarwin() && is64Bit)
    191     RM = Reloc::PIC_;
    192 
    193   // For static codegen, if we're not already set, use Small codegen.
    194   if (CM == CodeModel::Default)
    195     CM = CodeModel::Small;
    196   else if (CM == CodeModel::JITDefault)
    197     // 64-bit JIT places everything in the same buffer except external funcs.
    198     CM = is64Bit ? CodeModel::Large : CodeModel::Small;
    199 
    200   X->initMCCodeGenInfo(RM, CM, OL);
    201   return X;
    202 }
    203 
    204 static MCInstPrinter *createX86MCInstPrinter(const Triple &T,
    205                                              unsigned SyntaxVariant,
    206                                              const MCAsmInfo &MAI,
    207                                              const MCInstrInfo &MII,
    208                                              const MCRegisterInfo &MRI) {
    209   if (SyntaxVariant == 0)
    210     return new X86ATTInstPrinter(MAI, MII, MRI);
    211   if (SyntaxVariant == 1)
    212     return new X86IntelInstPrinter(MAI, MII, MRI);
    213   return nullptr;
    214 }
    215 
    216 static MCRelocationInfo *createX86MCRelocationInfo(const Triple &TheTriple,
    217                                                    MCContext &Ctx) {
    218   if (TheTriple.isOSBinFormatMachO() && TheTriple.getArch() == Triple::x86_64)
    219     return createX86_64MachORelocationInfo(Ctx);
    220   else if (TheTriple.isOSBinFormatELF())
    221     return createX86_64ELFRelocationInfo(Ctx);
    222   // Default to the stock relocation info.
    223   return llvm::createMCRelocationInfo(TheTriple, Ctx);
    224 }
    225 
    226 static MCInstrAnalysis *createX86MCInstrAnalysis(const MCInstrInfo *Info) {
    227   return new MCInstrAnalysis(Info);
    228 }
    229 
    230 // Force static initialization.
    231 extern "C" void LLVMInitializeX86TargetMC() {
    232   for (Target *T : {&TheX86_32Target, &TheX86_64Target}) {
    233     // Register the MC asm info.
    234     RegisterMCAsmInfoFn X(*T, createX86MCAsmInfo);
    235 
    236     // Register the MC codegen info.
    237     RegisterMCCodeGenInfoFn Y(*T, createX86MCCodeGenInfo);
    238 
    239     // Register the MC instruction info.
    240     TargetRegistry::RegisterMCInstrInfo(*T, createX86MCInstrInfo);
    241 
    242     // Register the MC register info.
    243     TargetRegistry::RegisterMCRegInfo(*T, createX86MCRegisterInfo);
    244 
    245     // Register the MC subtarget info.
    246     TargetRegistry::RegisterMCSubtargetInfo(*T,
    247                                             X86_MC::createX86MCSubtargetInfo);
    248 
    249     // Register the MC instruction analyzer.
    250     TargetRegistry::RegisterMCInstrAnalysis(*T, createX86MCInstrAnalysis);
    251 
    252     // Register the code emitter.
    253     TargetRegistry::RegisterMCCodeEmitter(*T, createX86MCCodeEmitter);
    254 
    255     // Register the object streamer.
    256     TargetRegistry::RegisterCOFFStreamer(*T, createX86WinCOFFStreamer);
    257 
    258     // Register the MCInstPrinter.
    259     TargetRegistry::RegisterMCInstPrinter(*T, createX86MCInstPrinter);
    260 
    261     // Register the MC relocation info.
    262     TargetRegistry::RegisterMCRelocationInfo(*T, createX86MCRelocationInfo);
    263   }
    264 
    265   // Register the asm backend.
    266   TargetRegistry::RegisterMCAsmBackend(TheX86_32Target,
    267                                        createX86_32AsmBackend);
    268   TargetRegistry::RegisterMCAsmBackend(TheX86_64Target,
    269                                        createX86_64AsmBackend);
    270 }
    271