llvm.org GIT mirror llvm / 18fb1d3
Add Mode64Bit feature and sink it down to MC layer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134641 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 8 years ago
11 changed file(s) with 183 addition(s) and 98 deletion(s). Raw diff Collapse all Expand all
1515 #include "llvm/MC/MCRegisterInfo.h"
1616 #include "llvm/MC/MCSubtargetInfo.h"
1717 #include "llvm/Target/TargetRegistry.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/Host.h"
1820
1921 #define GET_REGINFO_MC_DESC
2022 #include "X86GenRegisterInfo.inc"
2628 #include "X86GenSubtargetInfo.inc"
2729
2830 using namespace llvm;
31
32
33 std::string X86_MC::ParseX86Triple(StringRef TT) {
34 Triple TheTriple(TT);
35 if (TheTriple.getArch() == Triple::x86_64)
36 return "+64bit-mode";
37 return "";
38 }
39
40 /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
41 /// specified arguments. If we can't run cpuid on the host, return true.
42 bool X86_MC::GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
43 unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
44 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
45 #if defined(__GNUC__)
46 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
47 asm ("movq\t%%rbx, %%rsi\n\t"
48 "cpuid\n\t"
49 "xchgq\t%%rbx, %%rsi\n\t"
50 : "=a" (*rEAX),
51 "=S" (*rEBX),
52 "=c" (*rECX),
53 "=d" (*rEDX)
54 : "a" (value));
55 return false;
56 #elif defined(_MSC_VER)
57 int registers[4];
58 __cpuid(registers, value);
59 *rEAX = registers[0];
60 *rEBX = registers[1];
61 *rECX = registers[2];
62 *rEDX = registers[3];
63 return false;
64 #endif
65 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
66 #if defined(__GNUC__)
67 asm ("movl\t%%ebx, %%esi\n\t"
68 "cpuid\n\t"
69 "xchgl\t%%ebx, %%esi\n\t"
70 : "=a" (*rEAX),
71 "=S" (*rEBX),
72 "=c" (*rECX),
73 "=d" (*rEDX)
74 : "a" (value));
75 return false;
76 #elif defined(_MSC_VER)
77 __asm {
78 mov eax,value
79 cpuid
80 mov esi,rEAX
81 mov dword ptr [esi],eax
82 mov esi,rEBX
83 mov dword ptr [esi],ebx
84 mov esi,rECX
85 mov dword ptr [esi],ecx
86 mov esi,rEDX
87 mov dword ptr [esi],edx
88 }
89 return false;
90 #endif
91 #endif
92 return true;
93 }
94
95 void X86_MC::DetectFamilyModel(unsigned EAX, unsigned &Family,
96 unsigned &Model) {
97 Family = (EAX >> 8) & 0xf; // Bits 8 - 11
98 Model = (EAX >> 4) & 0xf; // Bits 4 - 7
99 if (Family == 6 || Family == 0xf) {
100 if (Family == 0xf)
101 // Examine extended family ID if family ID is F.
102 Family += (EAX >> 20) & 0xff; // Bits 20 - 27
103 // Examine extended model ID if family ID is 6 or F.
104 Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
105 }
106 }
107
108 static bool hasX86_64() {
109 // FIXME: Code duplication. See X86Subtarget::AutoDetectSubtargetFeatures.
110 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
111 union {
112 unsigned u[3];
113 char c[12];
114 } text;
115
116 if (X86_MC::GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
117 return false;
118
119 bool IsIntel = memcmp(text.c, "GenuineIntel", 12) == 0;
120 bool IsAMD = !IsIntel && memcmp(text.c, "AuthenticAMD", 12) == 0;
121 if (IsIntel || IsAMD) {
122 X86_MC::GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
123 if ((EDX >> 29) & 0x1)
124 return true;
125 }
126
127 return false;
128 }
29129
30130 MCInstrInfo *createX86MCInstrInfo() {
31131 MCInstrInfo *X = new MCInstrInfo();
41141
42142 MCSubtargetInfo *createX86MCSubtargetInfo(StringRef TT, StringRef CPU,
43143 StringRef FS) {
144 std::string ArchFS = X86_MC::ParseX86Triple(TT);
145 if (!FS.empty()) {
146 if (!ArchFS.empty())
147 ArchFS = ArchFS + "," + FS.str();
148 else
149 ArchFS = FS;
150 }
151
152 std::string CPUName = CPU;
153 if (CPUName.empty())
154 CPUName = sys::getHostCPUName();
155
156 if (ArchFS.empty() && CPUName.empty() && hasX86_64())
157 // Auto-detect if host is 64-bit capable, it's the default if true.
158 ArchFS = "+64bit-mode";
159
44160 MCSubtargetInfo *X = new MCSubtargetInfo();
45 InitX86MCSubtargetInfo(X, CPU, FS);
161 InitX86MCSubtargetInfo(X, CPU, ArchFS);
46162 return X;
47163 }
48164
1313 #ifndef X86MCTARGETDESC_H
1414 #define X86MCTARGETDESC_H
1515
16 #include
17
1618 namespace llvm {
1719 class Target;
20 class StringRef;
1821
1922 extern Target TheX86_32Target, TheX86_64Target;
23
24 namespace X86_MC {
25 std::string ParseX86Triple(StringRef TT);
26
27 /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in
28 /// the specified arguments. If we can't run cpuid on the host, return true.
29 bool GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
30 unsigned *rEBX, unsigned *rECX, unsigned *rEDX);
31
32 void DetectFamilyModel(unsigned EAX, unsigned &Family, unsigned &Model);
33 }
2034 } // End llvm namespace
2135
2236 // Defines symbolic names for X86 registers. This defines a mapping from
1414 // Get the target-independent interfaces which we are implementing...
1515 //
1616 include "llvm/Target/Target.td"
17
18 //===----------------------------------------------------------------------===//
19 // X86 Subtarget state.
20 //
21
22 def Mode64Bit : SubtargetFeature<"64bit-mode", "In64BitMode", "true",
23 "64-bit mode (x86_64)">;
1724
1825 //===----------------------------------------------------------------------===//
1926 // X86 Subtarget features.
157157 /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls
158158 /// to immediate address.
159159 bool X86Subtarget::IsLegalToCallImmediateAddr(const TargetMachine &TM) const {
160 if (Is64Bit)
160 if (In64BitMode)
161161 return false;
162162 return isTargetELF() || TM.getRelocationModel() == Reloc::Static;
163163 }
173173 return 200;
174174 }
175175
176 /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
177 /// specified arguments. If we can't run cpuid on the host, return true.
178 static bool GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
179 unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
180 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
181 #if defined(__GNUC__)
182 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
183 asm ("movq\t%%rbx, %%rsi\n\t"
184 "cpuid\n\t"
185 "xchgq\t%%rbx, %%rsi\n\t"
186 : "=a" (*rEAX),
187 "=S" (*rEBX),
188 "=c" (*rECX),
189 "=d" (*rEDX)
190 : "a" (value));
191 return false;
192 #elif defined(_MSC_VER)
193 int registers[4];
194 __cpuid(registers, value);
195 *rEAX = registers[0];
196 *rEBX = registers[1];
197 *rECX = registers[2];
198 *rEDX = registers[3];
199 return false;
200 #endif
201 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
202 #if defined(__GNUC__)
203 asm ("movl\t%%ebx, %%esi\n\t"
204 "cpuid\n\t"
205 "xchgl\t%%ebx, %%esi\n\t"
206 : "=a" (*rEAX),
207 "=S" (*rEBX),
208 "=c" (*rECX),
209 "=d" (*rEDX)
210 : "a" (value));
211 return false;
212 #elif defined(_MSC_VER)
213 __asm {
214 mov eax,value
215 cpuid
216 mov esi,rEAX
217 mov dword ptr [esi],eax
218 mov esi,rEBX
219 mov dword ptr [esi],ebx
220 mov esi,rECX
221 mov dword ptr [esi],ecx
222 mov esi,rEDX
223 mov dword ptr [esi],edx
224 }
225 return false;
226 #endif
227 #endif
228 return true;
229 }
230
231 static void DetectFamilyModel(unsigned EAX, unsigned &Family, unsigned &Model) {
232 Family = (EAX >> 8) & 0xf; // Bits 8 - 11
233 Model = (EAX >> 4) & 0xf; // Bits 4 - 7
234 if (Family == 6 || Family == 0xf) {
235 if (Family == 0xf)
236 // Examine extended family ID if family ID is F.
237 Family += (EAX >> 20) & 0xff; // Bits 20 - 27
238 // Examine extended model ID if family ID is 6 or F.
239 Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
240 }
241 }
242
243176 void X86Subtarget::AutoDetectSubtargetFeatures() {
244177 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
245178 union {
247180 char c[12];
248181 } text;
249182
250 if (GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
183 if (X86_MC::GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
251184 return;
252185
253 GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
186 X86_MC::GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
254187
255188 if ((EDX >> 15) & 1) HasCMov = true;
256189 if ((EDX >> 23) & 1) X86SSELevel = MMX;
275208 // Determine if bit test memory instructions are slow.
276209 unsigned Family = 0;
277210 unsigned Model = 0;
278 DetectFamilyModel(EAX, Family, Model);
211 X86_MC::DetectFamilyModel(EAX, Family, Model);
279212 IsBTMemSlow = IsAMD || (Family == 6 && Model >= 13);
280213 // If it's Nehalem, unaligned memory access is fast.
281214 if (Family == 15 && Model == 26)
282215 IsUAMemFast = true;
283216
284 GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
217 X86_MC::GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
285218 HasX86_64 = (EDX >> 29) & 0x1;
286219 HasSSE4A = IsAMD && ((ECX >> 6) & 0x1);
287220 HasFMA4 = IsAMD && ((ECX >> 16) & 0x1);
290223
291224 X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU,
292225 const std::string &FS,
293 bool is64Bit, unsigned StackAlignOverride)
226 unsigned StackAlignOverride)
294227 : X86GenSubtargetInfo(TT, CPU, FS)
295228 , PICStyle(PICStyles::None)
296229 , X86SSELevel(NoMMXSSE)
311244 // FIXME: this is a known good value for Yonah. How about others?
312245 , MaxInlineSizeThreshold(128)
313246 , TargetTriple(TT)
314 , Is64Bit(is64Bit) {
247 , In64BitMode(false) {
248 // Insert the architecture feature derived from the target triple into the
249 // feature string. This is important for setting features that are implied
250 // based on the architecture version.
251 std::string ArchFS = X86_MC::ParseX86Triple(TT);
252 if (!FS.empty()) {
253 if (!ArchFS.empty())
254 ArchFS = ArchFS + "," + FS;
255 else
256 ArchFS = FS;
257 }
258
259 std::string CPUName = CPU;
260 if (CPUName.empty())
261 CPUName = sys::getHostCPUName();
315262
316263 // Determine default and user specified characteristics
317 if (!CPU.empty() || !FS.empty()) {
264 if (!CPUName.empty() || !ArchFS.empty()) {
318265 // If feature string is not empty, parse features string.
319 std::string CPUName = CPU;
320 if (CPUName.empty())
321 CPUName = sys::getHostCPUName();
322 ParseSubtargetFeatures(CPUName, FS);
266 ParseSubtargetFeatures(CPUName, ArchFS);
323267 // All X86-64 CPUs also have SSE2, however user might request no SSE via
324268 // -mattr, so don't force SSELevel here.
325269 if (HasAVX)
327271 } else {
328272 // Otherwise, use CPUID to auto-detect feature set.
329273 AutoDetectSubtargetFeatures();
274
275 // If CPU is 64-bit capable, default to 64-bit mode if not specified.
276 In64BitMode = HasX86_64;
277
330278 // Make sure SSE2 is enabled; it is available on all X86-64 CPUs.
331 if (Is64Bit && !HasAVX && X86SSELevel < SSE2)
279 if (In64BitMode && !HasAVX && X86SSELevel < SSE2)
332280 X86SSELevel = SSE2;
333281 }
334282
335283 // If requesting codegen for X86-64, make sure that 64-bit features
336284 // are enabled.
337 if (Is64Bit) {
285 // FIXME: Remove this feature since it's not actually being used.
286 if (In64BitMode) {
338287 HasX86_64 = true;
339288
340289 // All 64-bit cpus have cmov support.
344293 DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel
345294 << ", 3DNowLevel " << X863DNowLevel
346295 << ", 64bit " << HasX86_64 << "\n");
347 assert((!Is64Bit || HasX86_64) &&
296 assert((!In64BitMode || HasX86_64) &&
348297 "64-bit code requested on a subtarget that doesn't support it!");
349298
350299 // Stack alignment is 16 bytes on Darwin, FreeBSD, Linux and Solaris (both
352301 if (StackAlignOverride)
353302 stackAlignment = StackAlignOverride;
354303 else if (isTargetDarwin() || isTargetFreeBSD() || isTargetLinux() ||
355 isTargetSolaris() || Is64Bit)
304 isTargetSolaris() || In64BitMode)
356305 stackAlignment = 16;
357306 }
111111 Triple TargetTriple;
112112
113113 private:
114 /// Is64Bit - True if the processor supports 64-bit instructions and
115 /// pointer size is 64 bit.
116 bool Is64Bit;
114 /// In64BitMode - True if compiling for 64-bit, false for 32-bit.
115 bool In64BitMode;
117116
118117 public:
119118
121120 /// of the specified triple.
122121 ///
123122 X86Subtarget(const std::string &TT, const std::string &CPU,
124 const std::string &FS, bool is64Bit,
123 const std::string &FS,
125124 unsigned StackAlignOverride);
126125
127126 /// getStackAlignment - Returns the minimum alignment known to hold of the
141140 /// instruction.
142141 void AutoDetectSubtargetFeatures();
143142
144 bool is64Bit() const { return Is64Bit; }
143 bool is64Bit() const { return In64BitMode; }
145144
146145 PICStyles::Style getPICStyle() const { return PICStyle; }
147146 void setPICStyle(PICStyles::Style Style) { PICStyle = Style; }
199198 }
200199
201200 bool isTargetWin64() const {
202 return Is64Bit && (isTargetMingw() || isTargetWindows());
201 return In64BitMode && (isTargetMingw() || isTargetWindows());
203202 }
204203
205204 bool isTargetEnvMacho() const {
207206 }
208207
209208 bool isTargetWin32() const {
210 return !Is64Bit && (isTargetMingw() || isTargetWindows());
209 return !In64BitMode && (isTargetMingw() || isTargetWindows());
211210 }
212211
213212 bool isPICStyleSet() const { return PICStyle != PICStyles::None; }
119119 const std::string &CPU,
120120 const std::string &FS, bool is64Bit)
121121 : LLVMTargetMachine(T, TT),
122 Subtarget(TT, CPU, FS, is64Bit, StackAlignmentOverride),
122 Subtarget(TT, CPU, FS, StackAlignmentOverride),
123123 FrameLowering(*this, Subtarget),
124124 ELFWriterInfo(is64Bit, true) {
125125 DefRelocModel = getRelocationModel();
None ; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
0 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | FileCheck %s
11 ; rdar://7842028
22
33 ; Do not delete partially dead copy instructions.
None ; RUN: llc -O1 -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic -disable-fp-elim < %s | FileCheck %s
0 ; RUN: llc -O1 -mtriple=x86_64-unknown-linux-gnu -mcpu=core2 -relocation-model=pic -disable-fp-elim < %s | FileCheck %s
11 ;
22
33 %struct.type = type { %struct.subtype*, i32, i8, i32, i8, i32, i32, i32, i32, i32, i8, i32, i32, i32, i32, i32, [256 x i32], i32, [257 x i32], [257 x i32], i32*, i16*, i8*, i32, i32, i32, i32, i32, [256 x i8], [16 x i8], [256 x i8], [4096 x i8], [16 x i32], [18002 x i8], [18002 x i8], [6 x [258 x i8]], [6 x [258 x i32]], [6 x [258 x i32]], [6 x [258 x i32]], [6 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32*, i32*, i32* }
None ; RUN: llc < %s -combiner-alias-analysis -march=x86-64 | FileCheck %s
0 ; RUN: llc < %s -combiner-alias-analysis -march=x86-64 -mcpu=core2 | FileCheck %s
11
22 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
33 target triple = "x86_64-apple-darwin10.4"
None ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s -check-prefix=LINUX
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s -check-prefix=DARWIN
0 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=core2 | FileCheck %s -check-prefix=LINUX
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=DARWIN
22
33 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
44
None ; RUN: llc < %s -mtriple x86_64-apple-darwin | FileCheck %s
0 ; RUN: llc < %s -mtriple x86_64-apple-darwin -mcpu=core2 | FileCheck %s
11
22 %struct.A = type { [48 x i8], i32, i32, i32 }
33