diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-08-14 18:21:51 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-08-14 18:21:51 +0000 |
commit | be85cb90984d4d68550687c96defb0dd150eaa4d (patch) | |
tree | 2c2dc21b32d7cee920f78c52dd5fd00225a03c3a /llvm/lib/Support | |
parent | 5d1a701d6def1e4e6ae3d5bce67efd40b07fba16 (diff) | |
download | bcm5719-llvm-be85cb90984d4d68550687c96defb0dd150eaa4d.tar.gz bcm5719-llvm-be85cb90984d4d68550687c96defb0dd150eaa4d.zip |
Use the MSVC __cpuid intrinsic instead of inline asm
This works around PR16830 in LLVM when self-hosting clang on Windows.
llvm-svn: 188397
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r-- | llvm/lib/Support/Host.cpp | 45 |
1 files changed, 14 insertions, 31 deletions
diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp index 90e43894c3c..9360cb979f7 100644 --- a/llvm/lib/Support/Host.cpp +++ b/llvm/lib/Support/Host.cpp @@ -52,10 +52,19 @@ using namespace llvm; /// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in the /// specified arguments. If we can't run cpuid on the host, return true. -static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, - unsigned *rEBX, unsigned *rECX, unsigned *rEDX) { -#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) - #if defined(__GNUC__) +static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX, + unsigned *rECX, unsigned *rEDX) { +#if defined(_MSC_VER) + // The MSVC intrinsic is portable across x86 and x64. + int registers[4]; + __cpuid(registers, value); + *rEAX = registers[0]; + *rEBX = registers[1]; + *rECX = registers[2]; + *rEDX = registers[3]; + return false; +#elif defined(__GNUC__) + #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually. asm ("movq\t%%rbx, %%rsi\n\t" "cpuid\n\t" @@ -66,19 +75,7 @@ static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, "=d" (*rEDX) : "a" (value)); return false; - #elif defined(_MSC_VER) - int registers[4]; - __cpuid(registers, value); - *rEAX = registers[0]; - *rEBX = registers[1]; - *rECX = registers[2]; - *rEDX = registers[3]; - return false; - #else - return true; - #endif -#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86) - #if defined(__GNUC__) + #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86) asm ("movl\t%%ebx, %%esi\n\t" "cpuid\n\t" "xchgl\t%%ebx, %%esi\n\t" @@ -88,20 +85,6 @@ static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, "=d" (*rEDX) : "a" (value)); return false; - #elif defined(_MSC_VER) - __asm { - mov eax,value - cpuid - mov esi,rEAX - mov dword ptr [esi],eax - mov esi,rEBX - mov dword ptr [esi],ebx - mov esi,rECX - mov dword ptr [esi],ecx - mov esi,rEDX - mov dword ptr [esi],edx - } - return false; // pedantic #else returns to appease -Wunreachable-code (so we don't generate // postprocessed code that looks like "return true; return false;") #else |