forked from OSchip/llvm-project
[X86] Add __get_cpuid_count to cpuid.h. Update __get_cpuid to check the maximum level support before accessing the leaf. Rename level to leaf everywhere.
This matches gcc behavior. llvm-svn: 307506
This commit is contained in:
parent
f2d571c8ac
commit
f6e8408a11
|
@ -153,38 +153,31 @@
|
|||
#define bit_ENH_MOVSB 0x00000200
|
||||
|
||||
#if __i386__
|
||||
#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \
|
||||
#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \
|
||||
__asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \
|
||||
: "0"(__level))
|
||||
: "0"(__leaf))
|
||||
|
||||
#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \
|
||||
#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \
|
||||
__asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \
|
||||
: "0"(__level), "2"(__count))
|
||||
: "0"(__leaf), "2"(__count))
|
||||
#else
|
||||
/* x86-64 uses %rbx as the base register, so preserve it. */
|
||||
#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \
|
||||
#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) \
|
||||
: "0"(__level))
|
||||
: "0"(__leaf))
|
||||
|
||||
#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \
|
||||
#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) \
|
||||
: "0"(__level), "2"(__count))
|
||||
: "0"(__leaf), "2"(__count))
|
||||
#endif
|
||||
|
||||
static __inline int __get_cpuid (unsigned int __level, unsigned int *__eax,
|
||||
unsigned int *__ebx, unsigned int *__ecx,
|
||||
unsigned int *__edx) {
|
||||
__cpuid(__level, *__eax, *__ebx, *__ecx, *__edx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline int __get_cpuid_max (unsigned int __level, unsigned int *__sig)
|
||||
static __inline int __get_cpuid_max (unsigned int __leaf, unsigned int *__sig)
|
||||
{
|
||||
unsigned int __eax, __ebx, __ecx, __edx;
|
||||
#if __i386__
|
||||
|
@ -208,8 +201,35 @@ static __inline int __get_cpuid_max (unsigned int __level, unsigned int *__sig)
|
|||
return 0;
|
||||
#endif
|
||||
|
||||
__cpuid(__level, __eax, __ebx, __ecx, __edx);
|
||||
__cpuid(__leaf, __eax, __ebx, __ecx, __edx);
|
||||
if (__sig)
|
||||
*__sig = __ebx;
|
||||
return __eax;
|
||||
}
|
||||
|
||||
static __inline int __get_cpuid (unsigned int __leaf, unsigned int *__eax,
|
||||
unsigned int *__ebx, unsigned int *__ecx,
|
||||
unsigned int *__edx)
|
||||
{
|
||||
unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, 0);
|
||||
|
||||
if (__max_leaf == 0 || __max_leaf < __leaf)
|
||||
return 0;
|
||||
|
||||
__cpuid(__leaf, *__eax, *__ebx, *__ecx, *__edx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline int __get_cpuid_count (unsigned int __leaf,
|
||||
unsigned int __subleaf,
|
||||
unsigned int *__eax, unsigned int *__ebx,
|
||||
unsigned int *__ecx, unsigned int *__edx)
|
||||
{
|
||||
unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, 0);
|
||||
|
||||
if (__max_leaf == 0 || __max_leaf < __leaf)
|
||||
return 0;
|
||||
|
||||
__cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue