1 //===-- X86MCTargetDesc.cpp - X86 Target Descriptions -----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides X86 specific target descriptions.
12 //===----------------------------------------------------------------------===//
14 #include "X86MCTargetDesc.h"
15 #include "llvm/MC/MCInstrInfo.h"
16 #include "llvm/MC/MCRegisterInfo.h"
17 #include "llvm/MC/MCSubtargetInfo.h"
18 #include "llvm/Target/TargetRegistry.h"
19 #include "llvm/ADT/Triple.h"
20 #include "llvm/Support/Host.h"
22 #define GET_REGINFO_MC_DESC
23 #include "X86GenRegisterInfo.inc"
25 #define GET_INSTRINFO_MC_DESC
26 #include "X86GenInstrInfo.inc"
28 #define GET_SUBTARGETINFO_ENUM
29 #define GET_SUBTARGETINFO_MC_DESC
30 #include "X86GenSubtargetInfo.inc"
35 std::string X86_MC::ParseX86Triple(StringRef TT) {
37 if (TheTriple.getArch() == Triple::x86_64)
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.
44 bool 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)
48 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
49 asm ("movq\t%%rbx, %%rsi\n\t"
51 "xchgq\t%%rbx, %%rsi\n\t"
58 #elif defined(_MSC_VER)
60 __cpuid(registers, value);
67 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
69 asm ("movl\t%%ebx, %%esi\n\t"
71 "xchgl\t%%ebx, %%esi\n\t"
78 #elif defined(_MSC_VER)
83 mov dword ptr [esi],eax
85 mov dword ptr [esi],ebx
87 mov dword ptr [esi],ecx
89 mov dword ptr [esi],edx
97 void X86_MC::DetectFamilyModel(unsigned EAX, unsigned &Family,
99 Family = (EAX >> 8) & 0xf; // Bits 8 - 11
100 Model = (EAX >> 4) & 0xf; // Bits 4 - 7
101 if (Family == 6 || 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
110 static bool hasX86_64() {
111 // FIXME: Code duplication. See X86Subtarget::AutoDetectSubtargetFeatures.
112 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
118 if (X86_MC::GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
121 bool IsIntel = memcmp(text.c, "GenuineIntel", 12) == 0;
122 bool IsAMD = !IsIntel && memcmp(text.c, "AuthenticAMD", 12) == 0;
123 if (IsIntel || IsAMD) {
124 X86_MC::GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
125 if ((EDX >> 29) & 0x1)
132 MCSubtargetInfo *X86_MC::createX86MCSubtargetInfo(StringRef TT, StringRef CPU,
134 std::string ArchFS = X86_MC::ParseX86Triple(TT);
137 ArchFS = ArchFS + "," + FS.str();
142 std::string CPUName = CPU;
144 CPUName = sys::getHostCPUName();
146 if (ArchFS.empty() && CPUName.empty() && hasX86_64())
147 // Auto-detect if host is 64-bit capable, it's the default if true.
148 ArchFS = "+64bit-mode";
150 MCSubtargetInfo *X = new MCSubtargetInfo();
151 InitX86MCSubtargetInfo(X, CPUName, ArchFS);
155 MCInstrInfo *createX86MCInstrInfo() {
156 MCInstrInfo *X = new MCInstrInfo();
157 InitX86MCInstrInfo(X);
161 MCRegisterInfo *createX86MCRegisterInfo() {
162 MCRegisterInfo *X = new MCRegisterInfo();
163 InitX86MCRegisterInfo(X);
167 // Force static initialization.
168 extern "C" void LLVMInitializeX86MCInstrInfo() {
169 RegisterMCInstrInfo<MCInstrInfo> X(TheX86_32Target);
170 RegisterMCInstrInfo<MCInstrInfo> Y(TheX86_64Target);
172 TargetRegistry::RegisterMCInstrInfo(TheX86_32Target, createX86MCInstrInfo);
173 TargetRegistry::RegisterMCInstrInfo(TheX86_64Target, createX86MCInstrInfo);
176 extern "C" void LLVMInitializeX86MCRegInfo() {
177 RegisterMCRegInfo<MCRegisterInfo> X(TheX86_32Target);
178 RegisterMCRegInfo<MCRegisterInfo> Y(TheX86_64Target);
180 TargetRegistry::RegisterMCRegInfo(TheX86_32Target, createX86MCRegisterInfo);
181 TargetRegistry::RegisterMCRegInfo(TheX86_64Target, createX86MCRegisterInfo);