#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__
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;
+}