]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / lib / Target / X86 / MCTargetDesc / X86MCTargetDesc.cpp
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
32 using namespace llvm;
33
34
35 std::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.
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)
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
97 void 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
110 MCSubtargetInfo *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.
135 extern "C" void LLVMInitializeX86MCSubtargetInfo() {
136   TargetRegistry::RegisterMCSubtargetInfo(TheX86_32Target,
137                                           X86_MC::createX86MCSubtargetInfo);
138   TargetRegistry::RegisterMCSubtargetInfo(TheX86_64Target,
139                                           X86_MC::createX86MCSubtargetInfo);
140 }
141
142 static MCInstrInfo *createX86MCInstrInfo() {
143   MCInstrInfo *X = new MCInstrInfo();
144   InitX86MCInstrInfo(X);
145   return X;
146 }
147
148 extern "C" void LLVMInitializeX86MCInstrInfo() {
149   TargetRegistry::RegisterMCInstrInfo(TheX86_32Target, createX86MCInstrInfo);
150   TargetRegistry::RegisterMCInstrInfo(TheX86_64Target, createX86MCInstrInfo);
151 }
152
153 static MCRegisterInfo *createX86MCRegisterInfo() {
154   MCRegisterInfo *X = new MCRegisterInfo();
155   InitX86MCRegisterInfo(X);
156   return X;
157 }
158
159 extern "C" void LLVMInitializeX86MCRegInfo() {
160   TargetRegistry::RegisterMCRegInfo(TheX86_32Target, createX86MCRegisterInfo);
161   TargetRegistry::RegisterMCRegInfo(TheX86_64Target, createX86MCRegisterInfo);
162 }
163
164
165 static 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
181 extern "C" void LLVMInitializeX86MCAsmInfo() {
182   // Register the target asm info.
183   RegisterMCAsmInfoFn A(TheX86_32Target, createX86MCAsmInfo);
184   RegisterMCAsmInfoFn B(TheX86_64Target, createX86MCAsmInfo);
185 }