summaryrefslogtreecommitdiff
path: root/lib/Support/Host.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-08-14 18:21:51 +0000
committerReid Kleckner <reid@kleckner.net>2013-08-14 18:21:51 +0000
commitc97db8dfdd854430c28db74825a6bb7593b5ec05 (patch)
treef92900a9ebf9c06626eb8a8da638e030896823b5 /lib/Support/Host.cpp
parent1c6d387dc90fba589f8effb17c72a39f966f87df (diff)
downloadllvm-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.cpp45
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