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
//===---------------------------------------------------------------------===//
-Use cpuid to auto-detect CPU features such as SSE, SSE2, and SSE3.
-
-//===---------------------------------------------------------------------===//
-
u32 to float conversion improvement:
float uint32_2_float( unsigned u ) {
//
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
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
#include "X86Subtarget.h"
-#include "X86GenSubtarget.inc"
+//#include "X86GenSubtarget.inc"
#include "llvm/Module.h"
#include "llvm/Support/CommandLine.h"
#include <iostream>
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 (GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
+ return;
+
+ // FIXME: support for AMD family of processors.
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";
- }
+ GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
- default:
- return "generic";
- }
- } else {
- return "generic";
+ 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?
, 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";
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;
/// 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; }
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; }