Skip to content

Commit

Permalink
[clang][X86] Add __cpuidex function to cpuid.h
Browse files Browse the repository at this point in the history
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
  • Loading branch information
boomanaiden154 committed May 17, 2023
1 parent e91123f commit 286cefc
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 0 deletions.
6 changes: 6 additions & 0 deletions clang/lib/Headers/cpuid.h
Expand Up @@ -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 */
5 changes: 5 additions & 0 deletions clang/test/Headers/cpuid.c
Expand Up @@ -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);
}

0 comments on commit 286cefc

Please sign in to comment.