summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAiden Grossman <agrossman154@yahoo.com>2023-05-17 18:01:37 +0000
committerAiden Grossman <agrossman154@yahoo.com>2023-05-17 19:38:28 +0000
commit286cefcf35d0f55c57184c4219b95e82c96f1420 (patch)
treebbe8b62c7a272302810e602fd9164c8937f68dc3
parente91123fb1b8146b087571d2052a5adbbc9400c9f (diff)
downloadllvm-286cefcf35d0f55c57184c4219b95e82c96f1420.tar.gz
[clang][X86] Add __cpuidex function to cpuid.h
MSVC has a `__cpuidex` function implemented to call the underlying cpuid instruction which accepts a leaf, subleaf, and data array that the output data is written into. This patch adds this functionality into clang under the cpuid.h header. This also makes clang match GCC's behavior. GCC has had `__cpuidex` in its cpuid.h since 2020. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D150646
-rw-r--r--clang/lib/Headers/cpuid.h6
-rw-r--r--clang/test/Headers/cpuid.c5
2 files changed, 11 insertions, 0 deletions
diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h
index 1ad6853a97c9..22260c48c0c4 100644
--- a/clang/lib/Headers/cpuid.h
+++ b/clang/lib/Headers/cpuid.h
@@ -328,4 +328,10 @@ static __inline int __get_cpuid_count (unsigned int __leaf,
return 1;
}
+static __inline void __cpuidex (int __cpu_info[4], int __leaf, int __subleaf)
+{
+ __cpuid_count(__leaf, __subleaf, __cpu_info[0], __cpu_info[1], __cpu_info[2],
+ __cpu_info[3]);
+}
+
#endif /* __CPUID_H */
diff --git a/clang/test/Headers/cpuid.c b/clang/test/Headers/cpuid.c
index 7e485495c106..6ed12eca7a61 100644
--- a/clang/test/Headers/cpuid.c
+++ b/clang/test/Headers/cpuid.c
@@ -6,14 +6,19 @@
// 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-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]+}})
+// 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;
+int cpuid_info[4];
+
void test_cpuid(unsigned level, unsigned count) {
__cpuid(level, eax1, ebx1, ecx1, edx1);
__cpuid_count(level, count, eax0, ebx0, ecx0, edx0);
+ __cpuidex(cpuid_info, level, count);
}