From cde9e30bc6acdb22b21e1553f3460a9ab5363e62 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 27 Jan 2006 08:10:46 +0000 Subject: x86 CPU detection and proper subtarget support llvm-svn: 25679 --- llvm/lib/Target/X86/X86Subtarget.cpp | 103 +++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 41 deletions(-) (limited to 'llvm/lib/Target/X86/X86Subtarget.cpp') diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index e523f1448e0..3826c12f3c1 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -16,57 +16,78 @@ #include "X86GenSubtarget.inc" using namespace llvm; -#if defined(__APPLE__) -#include -#include -#include -#include +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" + "popl\t%%ebx" + : "=a" (*EAX), +#if !defined(__DYNAMIC__) // This works around a gcc -fPIC bug + "=b" (*EBX), +#endif + "=c" (*ECX), + "=d" (*EDX) + : "a" (value)); +#endif +#endif +} -/// GetCurrentX86CPU - Returns the current CPUs features. static const char *GetCurrentX86CPU() { - host_basic_info_data_t hostInfo; - mach_msg_type_number_t infoCount; + unsigned EAX = 0, DUMMY = 0, ECX = 0, EDX = 0; + GetCpuIDAndInfo(0x1, &EAX, &DUMMY, &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, &DUMMY, &ECX, &EDX); + bool Em64T = EDX & (1 << 29); - 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"; - - 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); -- cgit v1.2.3