What should be the last unnecessary <iostream>s in the library.
[oota-llvm.git] / lib / Target / X86 / X86Subtarget.cpp
1 //===-- X86Subtarget.cpp - X86 Subtarget Information ------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Nate Begeman and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the X86 specific subclass of TargetSubtarget.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "X86Subtarget.h"
15 #include "X86GenSubtarget.inc"
16 #include "llvm/Module.h"
17 #include "llvm/Support/CommandLine.h"
18 using namespace llvm;
19
20 cl::opt<X86Subtarget::AsmWriterFlavorTy>
21 AsmWriterFlavor("x86-asm-syntax", cl::init(X86Subtarget::unset),
22   cl::desc("Choose style of code to emit from X86 backend:"),
23   cl::values(
24     clEnumValN(X86Subtarget::att,   "att",   "  Emit AT&T-style assembly"),
25     clEnumValN(X86Subtarget::intel, "intel", "  Emit Intel-style assembly"),
26     clEnumValEnd));
27
28
29 /// True if accessing the GV requires an extra load. For Windows, dllimported
30 /// symbols are indirect, loading the value at address GV rather then the
31 /// value of GV itself. This means that the GlobalAddress must be in the base
32 /// or index register of the address, not the GV offset field.
33 bool X86Subtarget::GVRequiresExtraLoad(const GlobalValue* GV, bool isDirectCall) const
34 {
35   if (isTargetDarwin()) {
36     return (!isDirectCall &&
37             (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
38              (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())));
39   } else if (isTargetCygwin() || isTargetWindows()) {
40     return (GV->hasDLLImportLinkage());
41   }
42   
43   return false;
44 }
45
46 /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
47 /// specified arguments.  If we can't run cpuid on the host, return true.
48 bool X86::GetCpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
49                           unsigned *rECX, unsigned *rEDX) {
50 #if defined(__x86_64__)
51   // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
52   asm ("movq\t%%rbx, %%rsi\n\t"
53        "cpuid\n\t"
54        "xchgq\t%%rbx, %%rsi\n\t"
55        : "=a" (*rEAX),
56          "=S" (*rEBX),
57          "=c" (*rECX),
58          "=d" (*rEDX)
59        :  "a" (value));
60   return false;
61 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
62 #if defined(__GNUC__)
63   asm ("movl\t%%ebx, %%esi\n\t"
64        "cpuid\n\t"
65        "xchgl\t%%ebx, %%esi\n\t"
66        : "=a" (*rEAX),
67          "=S" (*rEBX),
68          "=c" (*rECX),
69          "=d" (*rEDX)
70        :  "a" (value));
71   return false;
72 #elif defined(_MSC_VER)
73   __asm {
74     mov   eax,value
75     cpuid
76     mov   esi,rEAX
77     mov   dword ptr [esi],eax
78     mov   esi,rEBX
79     mov   dword ptr [esi],ebx
80     mov   esi,rECX
81     mov   dword ptr [esi],ecx
82     mov   esi,rEDX
83     mov   dword ptr [esi],edx
84   }
85   return false;
86 #endif
87 #endif
88   return true;
89 }
90
91 void X86Subtarget::AutoDetectSubtargetFeatures() {
92   unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
93   union {
94     unsigned u[3];
95     char     c[12];
96   } text;
97   
98   if (X86::GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
99     return;
100   
101   // FIXME: support for AMD family of processors.
102   if (memcmp(text.c, "GenuineIntel", 12) == 0) {
103     X86::GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
104
105     if ((EDX >> 23) & 0x1) X86SSELevel = MMX;
106     if ((EDX >> 25) & 0x1) X86SSELevel = SSE1;
107     if ((EDX >> 26) & 0x1) X86SSELevel = SSE2;
108     if (ECX & 0x1)         X86SSELevel = SSE3;
109
110     X86::GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
111     HasX86_64 = (EDX >> 29) & 0x1;
112   }
113 }
114
115 static const char *GetCurrentX86CPU() {
116   unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
117   if (X86::GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
118     return "generic";
119   unsigned Family  = (EAX >> 8) & 0xf; // Bits 8 - 11
120   unsigned Model   = (EAX >> 4) & 0xf; // Bits 4 - 7
121   X86::GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
122   bool Em64T = (EDX >> 29) & 0x1;
123
124   union {
125     unsigned u[3];
126     char     c[12];
127   } text;
128
129   X86::GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1);
130   if (memcmp(text.c, "GenuineIntel", 12) == 0) {
131     switch (Family) {
132       case 3:
133         return "i386";
134       case 4:
135         return "i486";
136       case 5:
137         switch (Model) {
138         case 4:  return "pentium-mmx";
139         default: return "pentium";
140         }
141       case 6:
142         switch (Model) {
143         case 1:  return "pentiumpro";
144         case 3:
145         case 5:
146         case 6:  return "pentium2";
147         case 7:
148         case 8:
149         case 10:
150         case 11: return "pentium3";
151         case 9:
152         case 13: return "pentium-m";
153         case 14: return "yonah";
154         case 15: return "core2";
155         default: return "i686";
156         }
157       case 15: {
158         switch (Model) {
159         case 3:  
160         case 4:
161           return (Em64T) ? "nocona" : "prescott";
162         default:
163           return (Em64T) ? "x86-64" : "pentium4";
164         }
165       }
166         
167     default:
168       return "generic";
169     }
170   } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
171     // FIXME: this poorly matches the generated SubtargetFeatureKV table.  There
172     // appears to be no way to generate the wide variety of AMD-specific targets
173     // from the information returned from CPUID.
174     switch (Family) {
175       case 4:
176         return "i486";
177       case 5:
178         switch (Model) {
179         case 6:
180         case 7:  return "k6";
181         case 8:  return "k6-2";
182         case 9:
183         case 13: return "k6-3";
184         default: return "pentium";
185         }
186       case 6:
187         switch (Model) {
188         case 4:  return "athlon-tbird";
189         case 6:
190         case 7:
191         case 8:  return "athlon-mp";
192         case 10: return "athlon-xp";
193         default: return "athlon";
194         }
195       case 15:
196         switch (Model) {
197         case 5:  return "athlon-fx"; // also opteron
198         default: return "athlon64";
199         }
200
201     default:
202       return "generic";
203     }
204   } else {
205     return "generic";
206   }
207 }
208
209 X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit)
210   : AsmFlavor(AsmWriterFlavor)
211   , X86SSELevel(NoMMXSSE)
212   , HasX86_64(false)
213   , stackAlignment(8)
214   // FIXME: this is a known good value for Yonah. How about others?
215   , MinRepStrSizeThreshold(128)
216   , Is64Bit(is64Bit)
217   , TargetType(isELF) { // Default to ELF unless otherwise specified.
218
219   // Determine default and user specified characteristics
220   if (!FS.empty()) {
221     // If feature string is not empty, parse features string.
222     std::string CPU = GetCurrentX86CPU();
223     ParseSubtargetFeatures(FS, CPU);
224     
225     if (Is64Bit && !HasX86_64)
226       cerr << "Warning: Generation of 64-bit code for a 32-bit processor "
227            << "requested.\n";
228     if (Is64Bit && X86SSELevel < SSE2)
229       cerr << "Warning: 64-bit processors all have at least SSE2.\n";
230   } else {
231     // Otherwise, use CPUID to auto-detect feature set.
232     AutoDetectSubtargetFeatures();
233   }
234     
235   // If requesting codegen for X86-64, make sure that 64-bit and SSE2 features
236   // are enabled.  These are available on all x86-64 CPUs.
237   if (Is64Bit) {
238     HasX86_64 = true;
239     if (X86SSELevel < SSE2)
240       X86SSELevel = SSE2;
241   }
242
243   // Set the boolean corresponding to the current target triple, or the default
244   // if one cannot be determined, to true.
245   const std::string& TT = M.getTargetTriple();
246   if (TT.length() > 5) {
247     if (TT.find("cygwin") != std::string::npos ||
248         TT.find("mingw")  != std::string::npos)
249       TargetType = isCygwin;
250     else if (TT.find("darwin") != std::string::npos)
251       TargetType = isDarwin;
252     else if (TT.find("win32") != std::string::npos)
253       TargetType = isWindows;
254   } else if (TT.empty()) {
255 #if defined(__CYGWIN__) || defined(__MINGW32__)
256     TargetType = isCygwin;
257 #elif defined(__APPLE__)
258     TargetType = isDarwin;
259 #elif defined(_WIN32)
260     TargetType = isWindows;
261 #endif
262   }
263
264   // If the asm syntax hasn't been overridden on the command line, use whatever
265   // the target wants.
266   if (AsmFlavor == X86Subtarget::unset) {
267     if (TargetType == isWindows) {
268       AsmFlavor = X86Subtarget::intel;
269     } else {
270       AsmFlavor = X86Subtarget::att;
271     }
272   }
273
274   if (TargetType == isDarwin ||
275       TargetType == isCygwin ||
276       (TargetType == isELF && Is64Bit))
277     stackAlignment = 16;
278 }