diff --git a/lib/Target/X86/Makefile b/lib/Target/X86/Makefile index a793a9d00ea..b17703f23fb 100644 --- a/lib/Target/X86/Makefile +++ b/lib/Target/X86/Makefile @@ -14,7 +14,6 @@ EXTRA_DIST = README.txt BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \ X86GenRegisterInfo.inc X86GenInstrNames.inc \ X86GenInstrInfo.inc X86GenAsmWriter.inc \ - X86GenAsmWriter1.inc X86GenDAGISel.inc \ - X86GenSubtarget.inc + X86GenAsmWriter1.inc X86GenDAGISel.inc include $(LEVEL)/Makefile.common diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt index 4a0be7bbb0c..9f22bab55d2 100644 --- a/lib/Target/X86/README.txt +++ b/lib/Target/X86/README.txt @@ -562,10 +562,6 @@ is pessimized by -loop-reduce and -indvars //===---------------------------------------------------------------------===// -Use cpuid to auto-detect CPU features such as SSE, SSE2, and SSE3. - -//===---------------------------------------------------------------------===// - u32 to float conversion improvement: float uint32_2_float( unsigned u ) { diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index c4b3d8635ff..7ed912bd9f1 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -16,79 +16,6 @@ // 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 Features> - : Processor; - -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 //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index f32ae5bad7c..caa846bc59d 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "X86Subtarget.h" -#include "X86GenSubtarget.inc" +//#include "X86GenSubtarget.inc" #include "llvm/Module.h" #include "llvm/Support/CommandLine.h" #include @@ -72,104 +72,33 @@ static inline bool GetCpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEB return true; } -static const char *GetCurrentX86CPU() { +void X86Subtarget::DetectSubtargetFeatures() { 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"; - } + if (GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1)) + return; - default: - return "generic"; - } - } else { - return "generic"; + // FIXME: support for AMD family of processors. + if (memcmp(text.c, "GenuineIntel", 12) == 0) { + GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX); + + if ((EDX >> 23) & 0x1) X86SSELevel = MMX; + if ((EDX >> 25) & 0x1) X86SSELevel = SSE1; + if ((EDX >> 26) & 0x1) X86SSELevel = SSE2; + if (ECX & 0x1) X86SSELevel = SSE3; + + GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); + HasX86_64 = (EDX >> 29) & 0x1; } } X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) : AsmFlavor(AsmWriterFlavor) , X86SSELevel(NoMMXSSE) - , X863DNowLevel(NoThreeDNow) , HasX86_64(false) , stackAlignment(8) // FIXME: this is a known good value for Yonah. How about others? @@ -178,11 +107,7 @@ 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 - std::string CPU = GetCurrentX86CPU(); - - // Parse features string. - ParseSubtargetFeatures(FS, CPU); - + DetectSubtargetFeatures(); if (Is64Bit && !HasX86_64) { std::cerr << "Warning: Generation of 64-bit code for a 32-bit processor " "requested.\n"; diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 6e0d1dbae6e..e781d9527c8 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -32,19 +32,12 @@ 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; @@ -81,9 +74,9 @@ public: /// aligned. unsigned getMinRepStrSizeThreshold() const { return MinRepStrSizeThreshold; } - /// 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); + /// DetectSubtargetFeatures - Auto-detect CPU features using CPUID instruction. + /// + void DetectSubtargetFeatures(); bool is64Bit() const { return Is64Bit; } @@ -91,8 +84,6 @@ 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; }