Duh
[oota-llvm.git] / lib / Target / X86 / X86Subtarget.cpp
index 3553c60cada7c8af35a06527f67453a059043128..d0c5c4d39a4551411e5d5c264f719b4e953c940e 100644 (file)
 #include "X86GenSubtarget.inc"
 using namespace llvm;
 
-// FIXME: temporary.
-#include "llvm/Support/CommandLine.h"
-namespace {
-  cl::opt<bool> EnableSSE("enable-x86-sse", cl::Hidden,
-                          cl::desc("Enable sse on X86"));
-}
-
 /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
 /// specified arguments.  If we can't run cpuid on the host, return true.
-static bool GetCpuIDAndInfo(unsigned value, unsigned *EAX, unsigned *EBX,
-                            unsigned *ECX, unsigned *EDX) {
+static bool GetCpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
+                            unsigned *rECX, unsigned *rEDX) {
 #if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
 #if defined(__GNUC__)
   asm ("pushl\t%%ebx\n\t"
        "cpuid\n\t"
        "movl\t%%ebx, %%esi\n\t"
        "popl\t%%ebx"
-       : "=a" (*EAX),
-         "=S" (*EBX),
-         "=c" (*ECX),
-         "=d" (*EDX)
+       : "=a" (*rEAX),
+         "=S" (*rEBX),
+         "=c" (*rECX),
+         "=d" (*rEDX)
        :  "a" (value));
   return false;
+#elif defined(_MSC_VER)
+  __asm {
+    mov   eax,value
+    cpuid
+    mov   esi,rEAX
+    mov   dword ptr [esi],eax
+    mov   esi,rEBX
+    mov   dword ptr [esi],ebx
+    mov   esi,rECX
+    mov   dword ptr [esi],ecx
+    mov   esi,rEDX
+    mov   dword ptr [esi],edx
+  }
+  return false;
 #endif
 #endif
   return true;
@@ -53,42 +60,86 @@ static const char *GetCurrentX86CPU() {
   GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
   bool Em64T = EDX & (1 << 29);
 
-  switch (Family) {
-    case 3:
-      return "i386";
-    case 4:
-      return "i486";
-    case 5:
-      switch (Model) {
-      case 4:  return "pentium-mmx";
-      default: return "pentium";
-      }
-    case 6:
-      switch (Model) {
-      case 1:  return "pentiumpro";
+  union {
+    unsigned u[3];
+    char     c[12];
+  } text;
+
+  GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1);
+  if (memcmp(text.c, "GenuineIntel", 12) == 0) {
+    switch (Family) {
       case 3:
+        return "i386";
+      case 4:
+        return "i486";
       case 5:
-      case 6:  return "pentium2";
-      case 7:
-      case 8:
-      case 10:
-      case 11: return "pentium3";
-      case 9:
-      case 13: return "pentium-m";
-      case 14: return "yonah";
-      default: return "i686";
+        switch (Model) {
+        case 4:  return "pentium-mmx";
+        default: return "pentium";
+        }
+      case 6:
+        switch (Model) {
+        case 1:  return "pentiumpro";
+        case 3:
+        case 5:
+        case 6:  return "pentium2";
+        case 7:
+        case 8:
+        case 10:
+        case 11: return "pentium3";
+        case 9:
+        case 13: return "pentium-m";
+        case 14: return "yonah";
+        default: return "i686";
+        }
+      case 15: {
+        switch (Model) {
+        case 3:  
+        case 4:
+          return (Em64T) ? "nocona" : "prescott";
+        default:
+          return (Em64T) ? "x86-64" : "pentium4";
+        }
       }
-    case 15: {
-      switch (Model) {
-      case 3:  
+        
+    default:
+      return "generic";
+    }
+  } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
+    // FIXME: this poorly matches the generated SubtargetFeatureKV table.  There
+    // appears to be no way to generate the wide variety of AMD-specific targets
+    // from the information returned from CPUID.
+    switch (Family) {
       case 4:
-        return (Em64T) ? "nocona" : "prescott";
-      default:
-        return (Em64T) ? "x86-64" : "pentium4";
-      }
+        return "i486";
+      case 5:
+        switch (Model) {
+        case 6:
+        case 7:  return "k6";
+        case 8:  return "k6-2";
+        case 9:
+        case 13: return "k6-3";
+        default: return "pentium";
+        }
+      case 6:
+        switch (Model) {
+        case 4:  return "athlon-tbird";
+        case 6:
+        case 7:
+        case 8:  return "athlon-mp";
+        case 10: return "athlon-xp";
+        default: return "athlon";
+        }
+      case 15:
+        switch (Model) {
+        case 5:  return "athlon-fx"; // also opteron
+        default: return "athlon64";
+        }
+
+    default:
+      return "generic";
     }
-      
-  default:
+  } else {
     return "generic";
   }
 }
@@ -109,13 +160,6 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS) {
   // Default to ELF unless otherwise specified.
   TargetType = isELF;
   
-  // FIXME: Force these off until they work.  An llc-beta option should turn
-  // them back on.
-  if (!EnableSSE) {
-    X86SSELevel = NoMMXSSE;
-    X863DNowLevel = NoThreeDNow;
-  }
-      
   // Set the boolean corresponding to the current target triple, or the default
   // if one cannot be determined, to true.
   const std::string& TT = M.getTargetTriple();