Do away with CPU feature list. Just use CPUID to detect MMX, SSE, SSE2, SSE3, and 64-bit support.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30763 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2006-10-06 08:21:07 +00:00
parent 88c1578011
commit abc346ceda
5 changed files with 20 additions and 182 deletions

View File

@ -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

View File

@ -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 ) {

View File

@ -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<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
//===----------------------------------------------------------------------===//

View 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,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";

View File

@ -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; }