Added a temporary option -enable-x86-sse to enable sse support. It is used by
[oota-llvm.git] / lib / Target / X86 / X86Subtarget.cpp
index e523f1448e054f5848e36dcf116d28402a7976f6..32574d10536ed864c300ebf4c2eafcb483445ec9 100644 (file)
 #include "X86GenSubtarget.inc"
 using namespace llvm;
 
-#if defined(__APPLE__)
-#include <mach/mach.h>
-#include <mach/mach_host.h>
-#include <mach/host_info.h>
-#include <mach/machine.h>
+// FIXME: temporary.
+#include "llvm/Support/CommandLine.h"
+namespace {
+  cl::opt<bool> EnableSSE("enable-x86-sse", cl::Hidden,
+                          cl::desc("Enable sse on X86"));
+}
 
-/// GetCurrentX86CPU - Returns the current CPUs features.
-static const char *GetCurrentX86CPU() {
-  host_basic_info_data_t hostInfo;
-  mach_msg_type_number_t infoCount;
+static void GetCpuIDAndInfo(unsigned value, unsigned *EAX, unsigned *EBX,
+                            unsigned *ECX, unsigned *EDX) {
+#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" (value));
+#endif
+#endif
+}
 
-  infoCount = HOST_BASIC_INFO_COUNT;
-  host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, 
-            &infoCount);
-            
-  if (hostInfo.cpu_type != CPU_TYPE_I386) return "generic";
+static const char *GetCurrentX86CPU() {
+  unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+  GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
+  unsigned Family  = (EAX & (0xffffffff >> (32 - 4)) << 8) >> 8; // Bits 8 - 11
+  unsigned Model   = (EAX & (0xffffffff >> (32 - 4)) << 4) >> 4; // Bits 4 - 7
+  GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
+  bool Em64T = EDX & (1 << 29);
 
-  switch(hostInfo.cpu_subtype) {
-  case CPU_SUBTYPE_386:            return "i386";
-  case CPU_SUBTYPE_486:
-  case CPU_SUBTYPE_486SX:          return "i486";
-  case CPU_SUBTYPE_PENT:           return "pentium";
-  case CPU_SUBTYPE_PENTPRO:        return "pentiumpro";
-  case CPU_SUBTYPE_PENTII_M3:      return "pentium2";
-  case CPU_SUBTYPE_PENTII_M5:      return "pentium2";
-  case CPU_SUBTYPE_CELERON:
-  case CPU_SUBTYPE_CELERON_MOBILE: return "celeron";
-  case CPU_SUBTYPE_PENTIUM_3:      return "pentium3";
-  case CPU_SUBTYPE_PENTIUM_3_M:    return "pentium3m";
-  case CPU_SUBTYPE_PENTIUM_3_XEON: return "pentium3";   // FIXME: not sure.
-  case CPU_SUBTYPE_PENTIUM_M:      return "pentium-m";
-  case CPU_SUBTYPE_PENTIUM_4:      return "pentium4";
-  case CPU_SUBTYPE_PENTIUM_4_M:    return "pentium4m";
-  // FIXME: prescott, yonah? Check CPU_THREADTYPE_INTEL_HTT?
-  case CPU_SUBTYPE_XEON:
-  case CPU_SUBTYPE_XEON_MP:        return "nocona";
-  default: ;
+  switch (Family) {
+    case 3:
+      return "i386";
+    case 4:
+      return "i486";
+    case 5:
+      switch (Model) {
+      case 4:  return "pentium-mmx";
+      default: return "pentium";
+      }
+      break;
+    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";
+      }
+    }
+      
+  default:
+    return "generic";
   }
-  
-  return "generic";
 }
-#endif
 
 X86Subtarget::X86Subtarget(const Module &M, const std::string &FS)
   : stackAlignment(8), indirectExternAndWeakGlobals(false) {
       
   // Determine default and user specified characteristics
-  std::string CPU = "generic";
-#if defined(__APPLE__)
-  CPU = GetCurrentX86CPU();
-#endif
+  std::string CPU = GetCurrentX86CPU();
 
   // Parse features string.
   ParseSubtargetFeatures(FS, CPU);
 
   // 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.