Still need to support -mcpu=<> or cross compilation will fail. Doh.
authorEvan Cheng <evan.cheng@apple.com>
Fri, 6 Oct 2006 09:17:41 +0000 (09:17 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 6 Oct 2006 09:17:41 +0000 (09:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30764 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/Makefile
lib/Target/X86/X86.td
lib/Target/X86/X86Subtarget.cpp
lib/Target/X86/X86Subtarget.h

index b17703f23fbff6512b03059f9a296c1086c5d92c..a793a9d00ea574774d340c23a17e70f1d1d8c130 100644 (file)
@@ -14,6 +14,7 @@ EXTRA_DIST = README.txt
 BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
                 X86GenRegisterInfo.inc X86GenInstrNames.inc \
                 X86GenInstrInfo.inc X86GenAsmWriter.inc \
-                X86GenAsmWriter1.inc X86GenDAGISel.inc
+                X86GenAsmWriter1.inc X86GenDAGISel.inc  \
+                X86GenSubtarget.inc
 
 include $(LEVEL)/Makefile.common
index 7ed912bd9f1b0a3c1c17a2ee378a94c185b4f217..c4b3d8635ff78719184f0aac792363d69bae41e1 100644 (file)
 //
 include "../Target.td"
 
+//===----------------------------------------------------------------------===//
+// X86 Subtarget features.
+//
+def Feature64Bit     : SubtargetFeature<"64bit", "HasX86_64", "true",
+                                        "Support 64-bit instructions">;
+def FeatureMMX       : SubtargetFeature<"mmx","X86SSELevel", "MMX",
+                                        "Enable MMX instructions">;
+def FeatureSSE1      : SubtargetFeature<"sse", "X86SSELevel", "SSE1",
+                                        "Enable SSE instructions">;
+def FeatureSSE2      : SubtargetFeature<"sse2", "X86SSELevel", "SSE2",
+                                        "Enable SSE2 instructions">;
+def FeatureSSE3      : SubtargetFeature<"sse3", "X86SSELevel", "SSE3",
+                                        "Enable SSE3 instructions">;
+def Feature3DNow     : SubtargetFeature<"3dnow", "X863DNowLevel", "ThreeDNow",
+                                        "Enable 3DNow! instructions">;
+def Feature3DNowA    : SubtargetFeature<"3dnowa", "X863DNowLevel", "ThreeDNowA",
+                                        "Enable 3DNow! Athlon instructions">;
+
+//===----------------------------------------------------------------------===//
+// X86 processors supported.
+//===----------------------------------------------------------------------===//
+
+class Proc<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, NoItineraries, Features>;
+
+def : Proc<"generic",         []>;
+def : Proc<"i386",            []>;
+def : Proc<"i486",            []>;
+def : Proc<"pentium",         []>;
+def : Proc<"pentium-mmx",     [FeatureMMX]>;
+def : Proc<"i686",            []>;
+def : Proc<"pentiumpro",      []>;
+def : Proc<"pentium2",        [FeatureMMX]>;
+def : Proc<"pentium3",        [FeatureMMX, FeatureSSE1]>;
+def : Proc<"pentium-m",       [FeatureMMX, FeatureSSE1, FeatureSSE2]>;
+def : Proc<"pentium4",        [FeatureMMX, FeatureSSE1, FeatureSSE2]>;
+def : Proc<"x86-64",          [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               Feature64Bit]>;
+def : Proc<"yonah",           [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               FeatureSSE3]>;
+def : Proc<"prescott",        [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               FeatureSSE3]>;
+def : Proc<"nocona",          [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               FeatureSSE3, Feature64Bit]>;
+def : Proc<"core2",           [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               FeatureSSE3,  Feature64Bit]>;
+
+def : Proc<"k6",              [FeatureMMX]>;
+def : Proc<"k6-2",            [FeatureMMX, Feature3DNow]>;
+def : Proc<"k6-3",            [FeatureMMX, Feature3DNow]>;
+def : Proc<"athlon",          [FeatureMMX, Feature3DNow, Feature3DNowA]>;
+def : Proc<"athlon-tbird",    [FeatureMMX, Feature3DNow, Feature3DNowA]>;
+def : Proc<"athlon-4",        [FeatureMMX, FeatureSSE1, Feature3DNow,
+                               Feature3DNowA]>;
+def : Proc<"athlon-xp",       [FeatureMMX, FeatureSSE1, Feature3DNow,
+                               Feature3DNowA]>;
+def : Proc<"athlon-mp",       [FeatureMMX, FeatureSSE1, Feature3DNow,
+                               Feature3DNowA]>;
+def : Proc<"k8",              [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               Feature3DNow, Feature3DNowA, Feature64Bit]>;
+def : Proc<"opteron",         [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               Feature3DNow, Feature3DNowA, Feature64Bit]>;
+def : Proc<"athlon64",        [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               Feature3DNow, Feature3DNowA, Feature64Bit]>;
+def : Proc<"athlon-fx",       [FeatureMMX, FeatureSSE1, FeatureSSE2,
+                               Feature3DNow, Feature3DNowA, Feature64Bit]>;
+
+def : Proc<"winchip-c6",      [FeatureMMX]>;
+def : Proc<"winchip2",        [FeatureMMX, Feature3DNow]>;
+def : Proc<"c3",              [FeatureMMX, Feature3DNow]>;
+def : Proc<"c3-2",            [FeatureMMX, FeatureSSE1]>;
+
 //===----------------------------------------------------------------------===//
 // Register File Description
 //===----------------------------------------------------------------------===//
index caa846bc59d782a31da284350220beeb0b7f2734..3fe25fdac4d3a54a259e30e38bb2ef9ae1412dba 100644 (file)
@@ -12,7 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86Subtarget.h"
-//#include "X86GenSubtarget.inc"
+#include "X86GenSubtarget.inc"
 #include "llvm/Module.h"
 #include "llvm/Support/CommandLine.h"
 #include <iostream>
@@ -72,7 +72,7 @@ static inline bool GetCpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEB
   return true;
 }
 
-void X86Subtarget::DetectSubtargetFeatures() {
+void X86Subtarget::AutoDetectSubtargetFeatures() {
   unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
   union {
     unsigned u[3];
@@ -96,6 +96,100 @@ void X86Subtarget::DetectSubtargetFeatures() {
   }
 }
 
+static const char *GetCurrentX86CPU() {
+  unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+  if (GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
+    return "generic";
+  unsigned Family  = (EAX >> 8) & 0xf; // Bits 8 - 11
+  unsigned Model   = (EAX >> 4) & 0xf; // Bits 4 - 7
+  GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
+  bool Em64T = EDX & (1 << 29);
+
+  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:
+        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";
+        case 15: return "core2";
+        default: return "i686";
+        }
+      case 15: {
+        switch (Model) {
+        case 3:  
+        case 4:
+          return (Em64T) ? "nocona" : "prescott";
+        default:
+          return (Em64T) ? "x86-64" : "pentium4";
+        }
+      }
+        
+    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 "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";
+    }
+  } else {
+    return "generic";
+  }
+}
+
 X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit)
   : AsmFlavor(AsmWriterFlavor)
   , X86SSELevel(NoMMXSSE)
@@ -107,7 +201,14 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit)
   , TargetType(isELF) { // Default to ELF unless otherwise specified.
 
   // Determine default and user specified characteristics
-  DetectSubtargetFeatures();
+  if (!FS.empty()) {
+    // If feature string is not empty, parse features string.
+    std::string CPU = GetCurrentX86CPU();
+    ParseSubtargetFeatures(FS, CPU);
+  } else
+    // Otherwise, use CPUID to auto-detect feature set.
+    AutoDetectSubtargetFeatures();
+
   if (Is64Bit && !HasX86_64) {
       std::cerr << "Warning: Generation of 64-bit code for a 32-bit processor "
                    "requested.\n";
index e781d9527c8aec11e5c62a8d2658af2cf06b3c2d..b4907b64cf4fc9ce81b484c815bdb45c04a895e4 100644 (file)
@@ -32,12 +32,19 @@ protected:
     NoMMXSSE, MMX, SSE1, SSE2, SSE3
   };
 
+  enum X863DNowEnum {
+    NoThreeDNow, ThreeDNow, ThreeDNowA
+  };
+
   /// AsmFlavor - Which x86 asm dialect to use.
   AsmWriterFlavorTy AsmFlavor;
 
   /// X86SSELevel - MMX, SSE1, SSE2, SSE3, or none supported.
   X86SSEEnum X86SSELevel;
 
+  /// X863DNowLevel - 3DNow or 3DNow Athlon, or none supported.
+  X863DNowEnum X863DNowLevel;
+
   /// HasX86_64 - True if the processor supports X86-64 instructions.
   bool HasX86_64;
 
@@ -74,9 +81,13 @@ public:
   /// aligned.
   unsigned getMinRepStrSizeThreshold() const { return MinRepStrSizeThreshold; }
  
-  /// DetectSubtargetFeatures - Auto-detect CPU features using CPUID instruction.
-  ///
-  void DetectSubtargetFeatures();
+  /// ParseSubtargetFeatures - Parses features string setting specified 
+  /// subtarget options.  Definition of function is auto generated by tblgen.
+  void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
+
+  /// AutoDetectSubtargetFeatures - Auto-detect CPU features using CPUID
+  /// instruction.
+  void AutoDetectSubtargetFeatures();
 
   bool is64Bit() const { return Is64Bit; }
 
@@ -84,6 +95,8 @@ public:
   bool hasSSE1() const { return X86SSELevel >= SSE1; }
   bool hasSSE2() const { return X86SSELevel >= SSE2; }
   bool hasSSE3() const { return X86SSELevel >= SSE3; }
+  bool has3DNow() const { return X863DNowLevel >= ThreeDNow; }
+  bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
   
   bool isFlavorAtt() const { return AsmFlavor == att; }
   bool isFlavorIntel() const { return AsmFlavor == intel; }