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(StringRef TT) {
     46   Triple TheTriple(TT);
     47   std::string FS;
     48   if (TheTriple.getArch() == Triple::x86_64)
     49     FS = "+64bit-mode,-32bit-mode,-16bit-mode";
     50   else if (TheTriple.getEnvironment() != Triple::CODE16)
     51     FS = "-64bit-mode,+32bit-mode,-16bit-mode";
     52   else
     53     FS = "-64bit-mode,-32bit-mode,+16bit-mode";
     54 
     55   return FS;
     56 }
     57 
     58 /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
     59 /// specified arguments.  If we can't run cpuid on the host, return true.
     60 bool X86_MC::GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
     61                              unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
     62 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
     63   #if defined(__GNUC__)
     64     // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
     65     asm ("movq\t%%rbx, %%rsi\n\t"
     66          "cpuid\n\t"
     67          "xchgq\t%%rbx, %%rsi\n\t"
     68          : "=a" (*rEAX),
     69            "=S" (*rEBX),
     70            "=c" (*rECX),
     71            "=d" (*rEDX)
     72          :  "a" (value));
     73     return false;
     74   #elif defined(_MSC_VER)
     75     int registers[4];
     76     __cpuid(registers, value);
     77     *rEAX = registers[0];
     78     *rEBX = registers[1];
     79     *rECX = registers[2];
     80     *rEDX = registers[3];
     81     return false;
     82   #else
     83     return true;
     84   #endif
     85 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
     86   #if defined(__GNUC__)
     87     asm ("movl\t%%ebx, %%esi\n\t"
     88          "cpuid\n\t"
     89          "xchgl\t%%ebx, %%esi\n\t"
     90          : "=a" (*rEAX),
     91            "=S" (*rEBX),
     92            "=c" (*rECX),
     93            "=d" (*rEDX)
     94          :  "a" (value));
     95     return false;
     96   #elif defined(_MSC_VER)
     97     __asm {
     98       mov   eax,value
     99       cpuid
    100       mov   esi,rEAX
    101       mov   dword ptr [esi],eax
    102       mov   esi,rEBX
    103       mov   dword ptr [esi],ebx
    104       mov   esi,rECX
    105       mov   dword ptr [esi],ecx
    106       mov   esi,rEDX
    107       mov   dword ptr [esi],edx
    108     }
    109     return false;
    110   #else
    111     return true;
    112   #endif
    113 #else
    114   return true;
    115 #endif
    116 }
    117 
    118 /// GetCpuIDAndInfoEx - Execute the specified cpuid with subleaf and return the
    119 /// 4 values in the specified arguments.  If we can't run cpuid on the host,
    120 /// return true.
    121 bool X86_MC::GetCpuIDAndInfoEx(unsigned value, unsigned subleaf, unsigned *rEAX,
    122                                unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
    123 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
    124   #if defined(__GNUC__)
    125     // gcc desn't know cpuid would clobber ebx/rbx. Preseve it manually.
    126     asm ("movq\t%%rbx, %%rsi\n\t"
    127          "cpuid\n\t"
    128          "xchgq\t%%rbx, %%rsi\n\t"
    129          : "=a" (*rEAX),
    130            "=S" (*rEBX),
    131            "=c" (*rECX),
    132            "=d" (*rEDX)
    133          :  "a" (value),
    134             "c" (subleaf));
    135     return false;
    136   #elif defined(_MSC_VER)
    137     // __cpuidex was added in MSVC++ 9.0 SP1
    138     #if (_MSC_VER > 1500) || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729)
    139       int registers[4];
    140       __cpuidex(registers, value, subleaf);
    141       *rEAX = registers[0];
    142       *rEBX = registers[1];
    143       *rECX = registers[2];
    144       *rEDX = registers[3];
    145       return false;
    146     #else
    147       return true;
    148     #endif
    149   #else
    150     return true;
    151   #endif
    152 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
    153   #if defined(__GNUC__)
    154     asm ("movl\t%%ebx, %%esi\n\t"
    155          "cpuid\n\t"
    156          "xchgl\t%%ebx, %%esi\n\t"
    157          : "=a" (*rEAX),
    158            "=S" (*rEBX),
    159            "=c" (*rECX),
    160            "=d" (*rEDX)
    161          :  "a" (value),
    162             "c" (subleaf));
    163     return false;
    164   #elif defined(_MSC_VER)
    165     __asm {
    166       mov   eax,value
    167       mov   ecx,subleaf
    168       cpuid
    169       mov   esi,rEAX
    170       mov   dword ptr [esi],eax
    171       mov   esi,rEBX
    172       mov   dword ptr [esi],ebx
    173       mov   esi,rECX
    174       mov   dword ptr [esi],ecx
    175       mov   esi,rEDX
    176       mov   dword ptr [esi],edx
    177     }
    178     return false;
    179   #else
    180     return true;
    181   #endif
    182 #else
    183   return true;
    184 #endif
    185 }
    186 
    187 void X86_MC::DetectFamilyModel(unsigned EAX, unsigned &Family,
    188                                unsigned &Model) {
    189   Family = (EAX >> 8) & 0xf; // Bits 8 - 11
    190   Model  = (EAX >> 4) & 0xf; // Bits 4 - 7
    191   if (Family == 6 || Family == 0xf) {
    192     if (Family == 0xf)
    193       // Examine extended family ID if family ID is F.
    194       Family += (EAX >> 20) & 0xff;    // Bits 20 - 27
    195     // Examine extended model ID if family ID is 6 or F.
    196     Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
    197   }
    198 }
    199 
    200 unsigned X86_MC::getDwarfRegFlavour(Triple TT, bool isEH) {
    201   if (TT.getArch() == Triple::x86_64)
    202     return DWARFFlavour::X86_64;
    203 
    204   if (TT.isOSDarwin())
    205     return isEH ? DWARFFlavour::X86_32_DarwinEH : DWARFFlavour::X86_32_Generic;
    206   if (TT.isOSCygMing())
    207     // Unsupported by now, just quick fallback
    208     return DWARFFlavour::X86_32_Generic;
    209   return DWARFFlavour::X86_32_Generic;
    210 }
    211 
    212 void X86_MC::InitLLVM2SEHRegisterMapping(MCRegisterInfo *MRI) {
    213   // FIXME: TableGen these.
    214   for (unsigned Reg = X86::NoRegister+1; Reg < X86::NUM_TARGET_REGS; ++Reg) {
    215     unsigned SEH = MRI->getEncodingValue(Reg);
    216     MRI->mapLLVMRegToSEHReg(Reg, SEH);
    217   }
    218 }
    219 
    220 MCSubtargetInfo *X86_MC::createX86MCSubtargetInfo(StringRef TT, StringRef CPU,
    221                                                   StringRef FS) {
    222   std::string ArchFS = X86_MC::ParseX86Triple(TT);
    223   if (!FS.empty()) {
    224     if (!ArchFS.empty())
    225       ArchFS = ArchFS + "," + FS.str();
    226     else
    227       ArchFS = FS;
    228   }
    229 
    230   std::string CPUName = CPU;
    231   if (CPUName.empty())
    232     CPUName = "generic";
    233 
    234   MCSubtargetInfo *X = new MCSubtargetInfo();
    235   InitX86MCSubtargetInfo(X, TT, CPUName, ArchFS);
    236   return X;
    237 }
    238 
    239 static MCInstrInfo *createX86MCInstrInfo() {
    240   MCInstrInfo *X = new MCInstrInfo();
    241   InitX86MCInstrInfo(X);
    242   return X;
    243 }
    244 
    245 static MCRegisterInfo *createX86MCRegisterInfo(StringRef TT) {
    246   Triple TheTriple(TT);
    247   unsigned RA = (TheTriple.getArch() == Triple::x86_64)
    248     ? X86::RIP     // Should have dwarf #16.
    249     : X86::EIP;    // Should have dwarf #8.
    250 
    251   MCRegisterInfo *X = new MCRegisterInfo();
    252   InitX86MCRegisterInfo(X, RA,
    253                         X86_MC::getDwarfRegFlavour(TheTriple, false),
    254                         X86_MC::getDwarfRegFlavour(TheTriple, true),
    255                         RA);
    256   X86_MC::InitLLVM2SEHRegisterMapping(X);
    257   return X;
    258 }
    259 
    260 static MCAsmInfo *createX86MCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
    261   Triple TheTriple(TT);
    262   bool is64Bit = TheTriple.getArch() == Triple::x86_64;
    263 
    264   MCAsmInfo *MAI;
    265   if (TheTriple.isOSBinFormatMachO()) {
    266     if (is64Bit)
    267       MAI = new X86_64MCAsmInfoDarwin(TheTriple);
    268     else
    269       MAI = new X86MCAsmInfoDarwin(TheTriple);
    270   } else if (TheTriple.isOSBinFormatELF()) {
    271     // Force the use of an ELF container.
    272     MAI = new X86ELFMCAsmInfo(TheTriple);
    273   } else if (TheTriple.isWindowsMSVCEnvironment()) {
    274     MAI = new X86MCAsmInfoMicrosoft(TheTriple);
    275   } else if (TheTriple.isOSCygMing()) {
    276     MAI = new X86MCAsmInfoGNUCOFF(TheTriple);
    277   } else {
    278     // The default is ELF.
    279     MAI = new X86ELFMCAsmInfo(TheTriple);
    280   }
    281 
    282   // Initialize initial frame state.
    283   // Calculate amount of bytes used for return address storing
    284   int stackGrowth = is64Bit ? -8 : -4;
    285 
    286   // Initial state of the frame pointer is esp+stackGrowth.
    287   unsigned StackPtr = is64Bit ? X86::RSP : X86::ESP;
    288   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(
    289       nullptr, MRI.getDwarfRegNum(StackPtr, true), -stackGrowth);
    290   MAI->addInitialFrameState(Inst);
    291 
    292   // Add return address to move list
    293   unsigned InstPtr = is64Bit ? X86::RIP : X86::EIP;
    294   MCCFIInstruction Inst2 = MCCFIInstruction::createOffset(
    295       nullptr, MRI.getDwarfRegNum(InstPtr, true), stackGrowth);
    296   MAI->addInitialFrameState(Inst2);
    297 
    298   return MAI;
    299 }
    300 
    301 static MCCodeGenInfo *createX86MCCodeGenInfo(StringRef TT, Reloc::Model RM,
    302                                              CodeModel::Model CM,
    303                                              CodeGenOpt::Level OL) {
    304   MCCodeGenInfo *X = new MCCodeGenInfo();
    305 
    306   Triple T(TT);
    307   bool is64Bit = T.getArch() == Triple::x86_64;
    308 
    309   if (RM == Reloc::Default) {
    310     // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode.
    311     // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we
    312     // use static relocation model by default.
    313     if (T.isOSDarwin()) {
    314       if (is64Bit)
    315         RM = Reloc::PIC_;
    316       else
    317         RM = Reloc::DynamicNoPIC;
    318     } else if (T.isOSWindows() && is64Bit)
    319       RM = Reloc::PIC_;
    320     else
    321       RM = Reloc::Static;
    322   }
    323 
    324   // ELF and X86-64 don't have a distinct DynamicNoPIC model.  DynamicNoPIC
    325   // is defined as a model for code which may be used in static or dynamic
    326   // executables but not necessarily a shared library. On X86-32 we just
    327   // compile in -static mode, in x86-64 we use PIC.
    328   if (RM == Reloc::DynamicNoPIC) {
    329     if (is64Bit)
    330       RM = Reloc::PIC_;
    331     else if (!T.isOSDarwin())
    332       RM = Reloc::Static;
    333   }
    334 
    335   // If we are on Darwin, disallow static relocation model in X86-64 mode, since
    336   // the Mach-O file format doesn't support it.
    337   if (RM == Reloc::Static && T.isOSDarwin() && is64Bit)
    338     RM = Reloc::PIC_;
    339 
    340   // For static codegen, if we're not already set, use Small codegen.
    341   if (CM == CodeModel::Default)
    342     CM = CodeModel::Small;
    343   else if (CM == CodeModel::JITDefault)
    344     // 64-bit JIT places everything in the same buffer except external funcs.
    345     CM = is64Bit ? CodeModel::Large : CodeModel::Small;
    346 
    347   X->InitMCCodeGenInfo(RM, CM, OL);
    348   return X;
    349 }
    350 
    351 static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
    352                                     MCContext &Ctx, MCAsmBackend &MAB,
    353                                     raw_ostream &_OS,
    354                                     MCCodeEmitter *_Emitter,
    355                                     const MCSubtargetInfo &STI,
    356                                     bool RelaxAll,
    357                                     bool NoExecStack) {
    358   Triple TheTriple(TT);
    359 
    360   switch (TheTriple.getObjectFormat()) {
    361   default: llvm_unreachable("unsupported object format");
    362   case Triple::MachO:
    363     return createMachOStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll);
    364   case Triple::COFF:
    365     assert(TheTriple.isOSWindows() && "only Windows COFF is supported");
    366     return createX86WinCOFFStreamer(Ctx, MAB, _Emitter, _OS, RelaxAll);
    367   case Triple::ELF:
    368     return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
    369   }
    370 }
    371 
    372 static MCInstPrinter *createX86MCInstPrinter(const Target &T,
    373                                              unsigned SyntaxVariant,
    374                                              const MCAsmInfo &MAI,
    375                                              const MCInstrInfo &MII,
    376                                              const MCRegisterInfo &MRI,
    377                                              const MCSubtargetInfo &STI) {
    378   if (SyntaxVariant == 0)
    379     return new X86ATTInstPrinter(MAI, MII, MRI);
    380   if (SyntaxVariant == 1)
    381     return new X86IntelInstPrinter(MAI, MII, MRI);
    382   return nullptr;
    383 }
    384 
    385 static MCRelocationInfo *createX86MCRelocationInfo(StringRef TT,
    386                                                    MCContext &Ctx) {
    387   Triple TheTriple(TT);
    388   if (TheTriple.isOSBinFormatMachO() && TheTriple.getArch() == Triple::x86_64)
    389     return createX86_64MachORelocationInfo(Ctx);
    390   else if (TheTriple.isOSBinFormatELF())
    391     return createX86_64ELFRelocationInfo(Ctx);
    392   // Default to the stock relocation info.
    393   return llvm::createMCRelocationInfo(TT, Ctx);
    394 }
    395 
    396 static MCInstrAnalysis *createX86MCInstrAnalysis(const MCInstrInfo *Info) {
    397   return new MCInstrAnalysis(Info);
    398 }
    399 
    400 // Force static initialization.
    401 extern "C" void LLVMInitializeX86TargetMC() {
    402   // Register the MC asm info.
    403   RegisterMCAsmInfoFn A(TheX86_32Target, createX86MCAsmInfo);
    404   RegisterMCAsmInfoFn B(TheX86_64Target, createX86MCAsmInfo);
    405 
    406   // Register the MC codegen info.
    407   RegisterMCCodeGenInfoFn C(TheX86_32Target, createX86MCCodeGenInfo);
    408   RegisterMCCodeGenInfoFn D(TheX86_64Target, createX86MCCodeGenInfo);
    409 
    410   // Register the MC instruction info.
    411   TargetRegistry::RegisterMCInstrInfo(TheX86_32Target, createX86MCInstrInfo);
    412   TargetRegistry::RegisterMCInstrInfo(TheX86_64Target, createX86MCInstrInfo);
    413 
    414   // Register the MC register info.
    415   TargetRegistry::RegisterMCRegInfo(TheX86_32Target, createX86MCRegisterInfo);
    416   TargetRegistry::RegisterMCRegInfo(TheX86_64Target, createX86MCRegisterInfo);
    417 
    418   // Register the MC subtarget info.
    419   TargetRegistry::RegisterMCSubtargetInfo(TheX86_32Target,
    420                                           X86_MC::createX86MCSubtargetInfo);
    421   TargetRegistry::RegisterMCSubtargetInfo(TheX86_64Target,
    422                                           X86_MC::createX86MCSubtargetInfo);
    423 
    424   // Register the MC instruction analyzer.
    425   TargetRegistry::RegisterMCInstrAnalysis(TheX86_32Target,
    426                                           createX86MCInstrAnalysis);
    427   TargetRegistry::RegisterMCInstrAnalysis(TheX86_64Target,
    428                                           createX86MCInstrAnalysis);
    429 
    430   // Register the code emitter.
    431   TargetRegistry::RegisterMCCodeEmitter(TheX86_32Target,
    432                                         createX86MCCodeEmitter);
    433   TargetRegistry::RegisterMCCodeEmitter(TheX86_64Target,
    434                                         createX86MCCodeEmitter);
    435 
    436   // Register the asm backend.
    437   TargetRegistry::RegisterMCAsmBackend(TheX86_32Target,
    438                                        createX86_32AsmBackend);
    439   TargetRegistry::RegisterMCAsmBackend(TheX86_64Target,
    440                                        createX86_64AsmBackend);
    441 
    442   // Register the object streamer.
    443   TargetRegistry::RegisterMCObjectStreamer(TheX86_32Target,
    444                                            createMCStreamer);
    445   TargetRegistry::RegisterMCObjectStreamer(TheX86_64Target,
    446                                            createMCStreamer);
    447 
    448   // Register the MCInstPrinter.
    449   TargetRegistry::RegisterMCInstPrinter(TheX86_32Target,
    450                                         createX86MCInstPrinter);
    451   TargetRegistry::RegisterMCInstPrinter(TheX86_64Target,
    452                                         createX86MCInstPrinter);
    453 
    454   // Register the MC relocation info.
    455   TargetRegistry::RegisterMCRelocationInfo(TheX86_32Target,
    456                                            createX86MCRelocationInfo);
    457   TargetRegistry::RegisterMCRelocationInfo(TheX86_64Target,
    458                                            createX86MCRelocationInfo);
    459 }
    460