X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FHost.cpp;h=27c99c89aeee059af03f1556e6c52ad52803a10f;hb=3579a29dba8fcc7285a3a5bec4512b4ca0a91ab3;hp=367ab6bfd4ebec1d2a41fdf09bcae856dec4122e;hpb=d4d961615c67082bc24bfa5d372a93a1dcff3457;p=oota-llvm.git diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index 367ab6bfd4e..27c99c89aee 100644 --- a/lib/Support/Host.cpp +++ b/lib/Support/Host.cpp @@ -11,14 +11,15 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/Host.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Config/config.h" #include "llvm/Support/DataStream.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Host.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Config/config.h" #include // Include the platform-specific parts of this class. @@ -111,6 +112,21 @@ static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, #endif } +static bool OSHasAVXSupport() { +#if defined(__GNUC__) + // Check xgetbv; this uses a .byte sequence instead of the instruction + // directly because older assemblers do not include support for xgetbv and + // there is no easy way to conditionally compile based on the assembler used. + int rEAX, rEDX; + __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (rEAX), "=d" (rEDX) : "c" (0)); +#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) + unsigned long long rEAX = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); +#else + int rEAX = 0; // Ensures we return false +#endif + return (rEAX & 6) == 6; +} + static void DetectX86FamilyModel(unsigned EAX, unsigned &Family, unsigned &Model) { Family = (EAX >> 8) & 0xf; // Bits 8 - 11 @@ -133,6 +149,11 @@ std::string sys::getHostCPUName() { DetectX86FamilyModel(EAX, Family, Model); bool HasSSE3 = (ECX & 0x1); + // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV + // indicates that the AVX registers will be saved and restored on context + // switch, then we have full AVX support. + const unsigned AVXBits = (1 << 27) | (1 << 28); + bool HasAVX = ((ECX & AVXBits) == AVXBits) && OSHasAVXSupport(); GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); bool Em64T = (EDX >> 29) & 0x1; @@ -234,24 +255,29 @@ std::string sys::getHostCPUName() { case 37: // Intel Core i7, laptop version. case 44: // Intel Core i7 processor and Intel Xeon processor. All // processors are manufactured using the 32 nm process. + case 46: // Nehalem EX + case 47: // Westmere EX return "corei7"; // SandyBridge: case 42: // Intel Core i7 processor. All processors are manufactured // using the 32 nm process. case 45: - return "corei7-avx"; + // Not all Sandy Bridge processors support AVX (such as the Pentium + // versions instead of the i7 versions). + return HasAVX ? "corei7-avx" : "corei7"; // Ivy Bridge: case 58: - return "core-avx-i"; + // Not all Ivy Bridge processors support AVX (such as the Pentium + // versions instead of the i7 versions). + return HasAVX ? "core-avx-i" : "corei7"; case 28: // Most 45 nm Intel Atom processors case 38: // 45 nm Atom Lincroft case 39: // 32 nm Atom Medfield - // re-enable when buildbot will pass all atom tests - //case 53: // 32 nm Atom Midview - //case 54: // 32 nm Atom Midview + case 53: // 32 nm Atom Midview + case 54: // 32 nm Atom Midview return "atom"; default: return (Em64T) ? "x86-64" : "i686"; @@ -304,6 +330,7 @@ std::string sys::getHostCPUName() { case 8: return "k6-2"; case 9: case 13: return "k6-3"; + case 10: return "geode"; default: return "pentium"; } case 6: @@ -328,7 +355,10 @@ std::string sys::getHostCPUName() { case 20: return "btver1"; case 21: - return "bdver1"; + if (Model <= 15) + return "bdver1"; + else if (Model <= 31) + return "bdver2"; default: return "generic"; } @@ -501,6 +531,7 @@ std::string sys::getHostCPUName() { .Case("0xb76", "arm1176jz-s") .Case("0xc08", "cortex-a8") .Case("0xc09", "cortex-a9") + .Case("0xc0f", "cortex-a15") .Case("0xc20", "cortex-m0") .Case("0xc23", "cortex-m3") .Case("0xc24", "cortex-m4") @@ -514,6 +545,75 @@ std::string sys::getHostCPUName() { } #endif +#if defined(__linux__) && defined(__arm__) +bool sys::getHostCPUFeatures(StringMap &Features) { + std::string Err; + DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); + if (!DS) { + DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n"); + return false; + } + + // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line + // in all cases. + char buffer[1024]; + size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer)); + delete DS; + + StringRef Str(buffer, CPUInfoSize); + + SmallVector Lines; + Str.split(Lines, "\n"); + + // Look for the CPU implementer line. + StringRef Implementer; + for (unsigned I = 0, E = Lines.size(); I != E; ++I) + if (Lines[I].startswith("CPU implementer")) + Implementer = Lines[I].substr(15).ltrim("\t :"); + + if (Implementer == "0x41") { // ARM Ltd. + SmallVector CPUFeatures; + + // Look for the CPU features. + for (unsigned I = 0, E = Lines.size(); I != E; ++I) + if (Lines[I].startswith("Features")) { + Lines[I].split(CPUFeatures, " "); + break; + } + + for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { + StringRef LLVMFeatureStr = StringSwitch(CPUFeatures[I]) + .Case("half", "fp16") + .Case("neon", "neon") + .Case("vfpv3", "vfp3") + .Case("vfpv3d16", "d16") + .Case("vfpv4", "vfp4") + .Case("idiva", "hwdiv-arm") + .Case("idivt", "hwdiv") + .Default(""); + + if (LLVMFeatureStr != "") + Features.GetOrCreateValue(LLVMFeatureStr).setValue(true); + } + + return true; + } + + return false; +} +#else bool sys::getHostCPUFeatures(StringMap &Features){ return false; } +#endif + +std::string sys::getProcessTriple() { + Triple PT(LLVM_HOSTTRIPLE); + + if (sizeof(void *) == 8 && PT.isArch32Bit()) + PT = PT.get64BitArchVariant(); + if (sizeof(void *) == 4 && PT.isArch64Bit()) + PT = PT.get32BitArchVariant(); + + return PT.str(); +}