X86MCTargetDesc.cpp revision 224133
1//===-- X86MCTargetDesc.cpp - X86 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 X86 specific target descriptions. 11// 12//===----------------------------------------------------------------------===// 13 14#include "X86MCTargetDesc.h" 15#include "X86MCAsmInfo.h" 16#include "llvm/MC/MCInstrInfo.h" 17#include "llvm/MC/MCRegisterInfo.h" 18#include "llvm/MC/MCSubtargetInfo.h" 19#include "llvm/Target/TargetRegistry.h" 20#include "llvm/ADT/Triple.h" 21#include "llvm/Support/Host.h" 22 23#define GET_REGINFO_MC_DESC 24#include "X86GenRegisterInfo.inc" 25 26#define GET_INSTRINFO_MC_DESC 27#include "X86GenInstrInfo.inc" 28 29#define GET_SUBTARGETINFO_MC_DESC 30#include "X86GenSubtargetInfo.inc" 31 32using namespace llvm; 33 34 35std::string X86_MC::ParseX86Triple(StringRef TT) { 36 Triple TheTriple(TT); 37 if (TheTriple.getArch() == Triple::x86_64) 38 return "+64bit-mode"; 39 return "-64bit-mode"; 40} 41 42/// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the 43/// specified arguments. If we can't run cpuid on the host, return true. 44bool X86_MC::GetCpuIDAndInfo(unsigned value, unsigned *rEAX, 45 unsigned *rEBX, unsigned *rECX, unsigned *rEDX) { 46#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) 47 #if defined(__GNUC__) 48 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually. 49 asm ("movq\t%%rbx, %%rsi\n\t" 50 "cpuid\n\t" 51 "xchgq\t%%rbx, %%rsi\n\t" 52 : "=a" (*rEAX), 53 "=S" (*rEBX), 54 "=c" (*rECX), 55 "=d" (*rEDX) 56 : "a" (value)); 57 return false; 58 #elif defined(_MSC_VER) 59 int registers[4]; 60 __cpuid(registers, value); 61 *rEAX = registers[0]; 62 *rEBX = registers[1]; 63 *rECX = registers[2]; 64 *rEDX = registers[3]; 65 return false; 66 #endif 67#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86) 68 #if defined(__GNUC__) 69 asm ("movl\t%%ebx, %%esi\n\t" 70 "cpuid\n\t" 71 "xchgl\t%%ebx, %%esi\n\t" 72 : "=a" (*rEAX), 73 "=S" (*rEBX), 74 "=c" (*rECX), 75 "=d" (*rEDX) 76 : "a" (value)); 77 return false; 78 #elif defined(_MSC_VER) 79 __asm { 80 mov eax,value 81 cpuid 82 mov esi,rEAX 83 mov dword ptr [esi],eax 84 mov esi,rEBX 85 mov dword ptr [esi],ebx 86 mov esi,rECX 87 mov dword ptr [esi],ecx 88 mov esi,rEDX 89 mov dword ptr [esi],edx 90 } 91 return false; 92 #endif 93#endif 94 return true; 95} 96 97void X86_MC::DetectFamilyModel(unsigned EAX, unsigned &Family, 98 unsigned &Model) { 99 Family = (EAX >> 8) & 0xf; // Bits 8 - 11 100 Model = (EAX >> 4) & 0xf; // Bits 4 - 7 101 if (Family == 6 || Family == 0xf) { 102 if (Family == 0xf) 103 // Examine extended family ID if family ID is F. 104 Family += (EAX >> 20) & 0xff; // Bits 20 - 27 105 // Examine extended model ID if family ID is 6 or F. 106 Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 107 } 108} 109 110MCSubtargetInfo *X86_MC::createX86MCSubtargetInfo(StringRef TT, StringRef CPU, 111 StringRef FS) { 112 std::string ArchFS = X86_MC::ParseX86Triple(TT); 113 if (!FS.empty()) { 114 if (!ArchFS.empty()) 115 ArchFS = ArchFS + "," + FS.str(); 116 else 117 ArchFS = FS; 118 } 119 120 std::string CPUName = CPU; 121 if (CPUName.empty()) { 122#if defined (__x86_64__) || defined(__i386__) 123 CPUName = sys::getHostCPUName(); 124#else 125 CPUName = "generic"; 126#endif 127 } 128 129 MCSubtargetInfo *X = new MCSubtargetInfo(); 130 InitX86MCSubtargetInfo(X, TT, CPUName, ArchFS); 131 return X; 132} 133 134// Force static initialization. 135extern "C" void LLVMInitializeX86MCSubtargetInfo() { 136 TargetRegistry::RegisterMCSubtargetInfo(TheX86_32Target, 137 X86_MC::createX86MCSubtargetInfo); 138 TargetRegistry::RegisterMCSubtargetInfo(TheX86_64Target, 139 X86_MC::createX86MCSubtargetInfo); 140} 141 142static MCInstrInfo *createX86MCInstrInfo() { 143 MCInstrInfo *X = new MCInstrInfo(); 144 InitX86MCInstrInfo(X); 145 return X; 146} 147 148extern "C" void LLVMInitializeX86MCInstrInfo() { 149 TargetRegistry::RegisterMCInstrInfo(TheX86_32Target, createX86MCInstrInfo); 150 TargetRegistry::RegisterMCInstrInfo(TheX86_64Target, createX86MCInstrInfo); 151} 152 153static MCRegisterInfo *createX86MCRegisterInfo() { 154 MCRegisterInfo *X = new MCRegisterInfo(); 155 InitX86MCRegisterInfo(X); 156 return X; 157} 158 159extern "C" void LLVMInitializeX86MCRegInfo() { 160 TargetRegistry::RegisterMCRegInfo(TheX86_32Target, createX86MCRegisterInfo); 161 TargetRegistry::RegisterMCRegInfo(TheX86_64Target, createX86MCRegisterInfo); 162} 163 164 165static MCAsmInfo *createX86MCAsmInfo(const Target &T, StringRef TT) { 166 Triple TheTriple(TT); 167 168 if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) { 169 if (TheTriple.getArch() == Triple::x86_64) 170 return new X86_64MCAsmInfoDarwin(TheTriple); 171 else 172 return new X86MCAsmInfoDarwin(TheTriple); 173 } 174 175 if (TheTriple.isOSWindows()) 176 return new X86MCAsmInfoCOFF(TheTriple); 177 178 return new X86ELFMCAsmInfo(TheTriple); 179} 180 181extern "C" void LLVMInitializeX86MCAsmInfo() { 182 // Register the target asm info. 183 RegisterMCAsmInfoFn A(TheX86_32Target, createX86MCAsmInfo); 184 RegisterMCAsmInfoFn B(TheX86_64Target, createX86MCAsmInfo); 185} 186