diff options
-rw-r--r-- | clang/lib/Headers/cpuid.h | 28 | ||||
-rw-r--r-- | clang/test/Headers/cpuid.c | 18 |
2 files changed, 31 insertions, 15 deletions
diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index f9254e9738e..5f3b01a9e5a 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -92,31 +92,29 @@ #define bit_SMEP 0x00000080 #define bit_ENH_MOVSB 0x00000200 -/* PIC on i386 uses %ebx, so preserve it. */ #if __i386__ #define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ - __asm(" pushl %%ebx\n" \ + __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ + : "0"(__level)) + +#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ + __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ + : "0"(__level), "2"(__count)) +#else +/* x86-64 uses %rbx as the base register, so preserve it. */ +#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ + __asm(" xchgq %%rbx,%q1\n" \ " cpuid\n" \ - " mov %%ebx,%1\n" \ - " popl %%ebx" \ + " xchgq %%rbx,%q1" \ : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ : "0"(__level)) #define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ - __asm(" pushl %%ebx\n" \ + __asm(" xchgq %%rbx,%q1\n" \ " cpuid\n" \ - " mov %%ebx,%1\n" \ - " popl %%ebx" \ + " xchgq %%rbx,%q1" \ : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ : "0"(__level), "2"(__count)) -#else -#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ - __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ - : "0"(__level)) - -#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ - __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ - : "0"(__level), "2"(__count)) #endif static __inline int __get_cpuid (unsigned int __level, unsigned int *__eax, diff --git a/clang/test/Headers/cpuid.c b/clang/test/Headers/cpuid.c new file mode 100644 index 00000000000..b0ba07af2f2 --- /dev/null +++ b/clang/test/Headers/cpuid.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-64 +// RUN: %clang_cc1 %s -ffreestanding -triple i386 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-32 + +#include <cpuid.h> + +// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm " xchgq %rbx,${1:q}\0A cpuid\0A xchgq %rbx,${1:q}", "={ax},=r,={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}) +// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm " xchgq %rbx,${1:q}\0A cpuid\0A xchgq %rbx,${1:q}", "={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}}) + +// CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}) +// CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", "={ax},={bx},={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}}) + +unsigned eax0, ebx0, ecx0, edx0; +unsigned eax1, ebx1, ecx1, edx1; + +void test_cpuid(unsigned level, unsigned count) { + __cpuid(level, eax1, ebx1, ecx1, edx1); + __cpuid_count(level, count, eax0, ebx0, ecx0, edx0); +} |