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 | c97db8dfdd854430c28db74825a6bb7593b5ec05 (patch) | |
tree | f92900a9ebf9c06626eb8a8da638e030896823b5 /lib/Support/Host.cpp | |
parent | 1c6d387dc90fba589f8effb17c72a39f966f87df (diff) | |
download | llvm-c97db8dfdd854430c28db74825a6bb7593b5ec05.tar.gz llvm-c97db8dfdd854430c28db74825a6bb7593b5ec05.tar.bz2 llvm-c97db8dfdd854430c28db74825a6bb7593b5ec05.tar.xz |
Use the MSVC __cpuid intrinsic instead of inline asm
This works around PR16830 in LLVM when self-hosting clang on Windows.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188397 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/Host.cpp')
-rw-r--r-- | lib/Support/Host.cpp | 45 |
1 files changed, 14 insertions, 31 deletions
diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index 90e43894c3..9360cb979f 100644 --- a/lib/Support/Host.cpp +++ b/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 |