]> granicus.if.org Git - clang/commitdiff
[X86] Add __get_cpuid_count to cpuid.h. Update __get_cpuid to check the maximum level...
authorCraig Topper <craig.topper@intel.com>
Sun, 9 Jul 2017 17:43:10 +0000 (17:43 +0000)
committerCraig Topper <craig.topper@intel.com>
Sun, 9 Jul 2017 17:43:10 +0000 (17:43 +0000)
This matches gcc behavior.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307506 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/cpuid.h

index 400dcfacd552cbd1bf6e2fdccf1890281021fe10..41eefffe999c221a36867400ad2a2320edcfc88d 100644 (file)
 #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;
+}