From 547a8bc2365d9f1dc7bce52580a3ab64d69c80ed Mon Sep 17 00:00:00 2001 From: Alcaro Date: Tue, 25 Feb 2025 10:55:26 +0100 Subject: [PATCH] [clang][x86] Support -masm=intel in cpuid.h (#127331) Fixes #127271 Testing mostly done in Compiler Explorer https://godbolt.org/z/q1h3ohxr7 --- clang/lib/Headers/cpuid.h | 46 ++++++++++++++++++++------------------ clang/test/Headers/cpuid.c | 6 ++--- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index 2601aa5724f05..52addb7bfa856 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -267,18 +267,18 @@ : "0"(__leaf), "2"(__count)) #else /* x86-64 uses %rbx as the base register, so preserve it. */ -#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \ - __asm(" xchgq %%rbx,%q1\n" \ - " cpuid\n" \ - " xchgq %%rbx,%q1" \ - : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ +#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \ + __asm(" xchg{q|} {%%|}rbx,%q1\n" \ + " cpuid\n" \ + " xchg{q|} {%%|}rbx,%q1" \ + : "=a"(__eax), "=r"(__ebx), "=c"(__ecx), "=d"(__edx) \ : "0"(__leaf)) -#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \ - __asm(" xchgq %%rbx,%q1\n" \ - " cpuid\n" \ - " xchgq %%rbx,%q1" \ - : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ +#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \ + __asm(" xchg{q|} {%%|}rbx,%q1\n" \ + " cpuid\n" \ + " xchg{q|} {%%|}rbx,%q1" \ + : "=a"(__eax), "=r"(__ebx), "=c"(__ecx), "=d"(__edx) \ : "0"(__leaf), "2"(__count)) #endif @@ -289,20 +289,22 @@ static __inline unsigned int __get_cpuid_max (unsigned int __leaf, #ifdef __i386__ int __cpuid_supported; - __asm(" pushfl\n" - " popl %%eax\n" - " movl %%eax,%%ecx\n" - " xorl $0x00200000,%%eax\n" - " pushl %%eax\n" - " popfl\n" - " pushfl\n" - " popl %%eax\n" - " movl $0,%0\n" - " cmpl %%eax,%%ecx\n" + __asm(" pushf{l|d}\n" + " pop{l|} {%%|}eax\n" + " mov{l|} {%%eax,%%ecx|ecx,eax}\n" + " xor{l|} {$0x00200000,%%eax|eax,0x00200000}\n" + " push{l|} {%%|}eax\n" + " popf{l|d}\n" + " pushf{l|d}\n" + " pop{l|} {%%|}eax\n" + " mov{l|} {$0,%0|%0,0}\n" + " cmp{l|} {%%eax,%%ecx|ecx,eax}\n" " je 1f\n" - " movl $1,%0\n" + " mov{l|} {$1,%0|%0,1}\n" "1:" - : "=r" (__cpuid_supported) : : "eax", "ecx"); + : "=r"(__cpuid_supported) + : + : "eax", "ecx"); if (!__cpuid_supported) return 0; #endif diff --git a/clang/test/Headers/cpuid.c b/clang/test/Headers/cpuid.c index 6ed12eca7a61d..1c4f29dc52938 100644 --- a/clang/test/Headers/cpuid.c +++ b/clang/test/Headers/cpuid.c @@ -4,9 +4,9 @@ #include #include // Make sure multiple inclusion protection works. -// 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-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-64: {{.*}} call { i32, i32, i32, i32 } asm " xchg$(q$|$) $(%$|$)rbx,${1:q}\0A cpuid\0A xchg$(q$|$) $(%$|$)rbx,${1:q}", "={ax},=r,={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}) +// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm " xchg$(q$|$) $(%$|$)rbx,${1:q}\0A cpuid\0A xchg$(q$|$) $(%$|$)rbx,${1:q}", "={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}}) +// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm " xchg$(q$|$) $(%$|$)rbx,${1:q}\0A cpuid\0A xchg$(q$|$) $(%$|$)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]+}})