Skip to content

Commit 286cefc

Browse files
[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
1 parent e91123f commit 286cefc

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

clang/lib/Headers/cpuid.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,4 +328,10 @@ static __inline int __get_cpuid_count (unsigned int __leaf,
328328
return 1;
329329
}
330330

331+
static __inline void __cpuidex (int __cpu_info[4], int __leaf, int __subleaf)
332+
{
333+
__cpuid_count(__leaf, __subleaf, __cpu_info[0], __cpu_info[1], __cpu_info[2],
334+
__cpu_info[3]);
335+
}
336+
331337
#endif /* __CPUID_H */

clang/test/Headers/cpuid.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@
66

77
// 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]+}})
88
// 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]+}})
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]+}})
910

1011
// CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}})
1112
// 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]+}})
13+
// 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]+}})
1214

1315
unsigned eax0, ebx0, ecx0, edx0;
1416
unsigned eax1, ebx1, ecx1, edx1;
1517

18+
int cpuid_info[4];
19+
1620
void test_cpuid(unsigned level, unsigned count) {
1721
__cpuid(level, eax1, ebx1, ecx1, edx1);
1822
__cpuid_count(level, count, eax0, ebx0, ecx0, edx0);
23+
__cpuidex(cpuid_info, level, count);
1924
}

0 commit comments

Comments
 (0)