diff mbox

[i386,testsuite] : Check all supported __builtin_cpu_supports options

Message ID CAFULd4YwFV0SYMunry3TZHDwv7E0qDicq=+tm+uB1EC6N5MTpg@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Jan. 12, 2017, 5:32 p.m. UTC
Hello!

Attached patch checks all supported __builtin_cpu_supports options.
Additionally, it adds a couple of comments and moves some code to
prevent future mistakes.

2017-01-12  Uros Bizjak  <ubizjak@gmail.com>

    * gcc.target/i386/builtin_target.c (check_features): Check all
    supported __builtin_cpu_supports options.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
diff mbox

Patch

Index: gcc/config/i386/cpuid.h
===================================================================
--- gcc/config/i386/cpuid.h	(revision 244369)
+++ gcc/config/i386/cpuid.h	(working copy)
@@ -47,7 +47,7 @@ 
 #define bit_SSE		(1 << 25)
 #define bit_SSE2	(1 << 26)
 
-/* Extended Features */
+/* Extended Features (%eax == 0x80000001) */
 /* %ecx */
 #define bit_LAHF_LM	(1 << 0)
 #define bit_ABM		(1 << 5)
@@ -54,7 +54,6 @@ 
 #define bit_SSE4a	(1 << 6)
 #define bit_PRFCHW	(1 << 8)
 #define bit_XOP         (1 << 11)
-#define bit_AVX512VPOPCNTDQ	(1 << 14)
 #define bit_LWP 	(1 << 15)
 #define bit_FMA4        (1 << 16)
 #define bit_TBM         (1 << 21)
@@ -61,14 +60,12 @@ 
 #define bit_MWAITX      (1 << 29)
 
 /* %edx */
-#define bit_AVX5124VNNIW (1 << 2)
-#define bit_AVX5124FMAPS (1 << 3)
 #define bit_MMXEXT	(1 << 22)
 #define bit_LM		(1 << 29)
 #define bit_3DNOWP	(1 << 30)
 #define bit_3DNOW	(1 << 31)
 
-/* %ebx.  */
+/* %ebx  */
 #define bit_CLZERO	(1 << 0)
 
 /* Extended Features (%eax == 7) */
@@ -100,7 +97,12 @@ 
 #define bit_AVX512VBMI	(1 << 1)
 #define bit_PKU	(1 << 3)
 #define bit_OSPKE	(1 << 4)
+#define bit_AVX512VPOPCNTDQ	(1 << 14)
 
+/* %edx */
+#define bit_AVX5124VNNIW (1 << 2)
+#define bit_AVX5124FMAPS (1 << 3)
+
 /* XFEATURE_ENABLED_MASK register bits (%eax == 13, %ecx == 0) */
 #define bit_BNDREGS     (1 << 3)
 #define bit_BNDCSR      (1 << 4)
Index: gcc/testsuite/gcc.target/i386/builtin_target.c
===================================================================
--- gcc/testsuite/gcc.target/i386/builtin_target.c	(revision 244369)
+++ gcc/testsuite/gcc.target/i386/builtin_target.c	(working copy)
@@ -163,6 +163,9 @@ 
 check_features (unsigned int ecx, unsigned int edx,
 		int max_cpuid_level)
 {
+  unsigned int eax, ebx;
+  unsigned int ext_level;
+
   if (edx & bit_CMOV)
     assert (__builtin_cpu_supports ("cmov"));
   if (edx & bit_MMX)
@@ -187,18 +190,27 @@ 
     assert (__builtin_cpu_supports ("sse4.2"));
   if (ecx & bit_AVX)
     assert (__builtin_cpu_supports ("avx"));
+  if (ecx & bit_FMA)
+    assert (__builtin_cpu_supports ("fma"));
 
   /* Get advanced features at level 7 (eax = 7, ecx = 0).  */
   if (max_cpuid_level >= 7)
     {
-      unsigned int eax, ebx, ecx, edx;
       __cpuid_count (7, 0, eax, ebx, ecx, edx);
+      if (ebx & bit_BMI)
+	assert (__builtin_cpu_supports ("bmi"));
       if (ebx & bit_AVX2)
 	assert (__builtin_cpu_supports ("avx2"));
+      if (ebx & bit_BMI2)
+	assert (__builtin_cpu_supports ("bmi2"));
       if (ebx & bit_AVX512F)
 	assert (__builtin_cpu_supports ("avx512f"));
       if (ebx & bit_AVX512VL)
 	assert (__builtin_cpu_supports ("avx512vl"));
+      if (ebx & bit_AVX512BW)
+	assert (__builtin_cpu_supports ("avx512bw"));
+      if (ebx & bit_AVX512DQ)
+	assert (__builtin_cpu_supports ("avx512dq"));
       if (ebx & bit_AVX512CD)
 	assert (__builtin_cpu_supports ("avx512cd"));
       if (ebx & bit_AVX512PF)
@@ -205,21 +217,32 @@ 
 	assert (__builtin_cpu_supports ("avx512pf"));
       if (ebx & bit_AVX512ER)
 	assert (__builtin_cpu_supports ("avx512er"));
-      if (ebx & bit_AVX512BW)
-	assert (__builtin_cpu_supports ("avx512bw"));
-      if (ebx & bit_AVX512DQ)
-	assert (__builtin_cpu_supports ("avx512dq"));
-      if (ecx & bit_AVX512IFMA)
+      if (ebx & bit_AVX512IFMA)
 	assert (__builtin_cpu_supports ("avx512ifma"));
       if (ecx & bit_AVX512VBMI)
 	assert (__builtin_cpu_supports ("avx512vbmi"));
+      if (ecx & bit_AVX512VPOPCNTDQ)
+	assert (__builtin_cpu_supports ("avx512vpopcntdq"));
       if (edx & bit_AVX5124VNNIW)
 	assert (__builtin_cpu_supports ("avx5124vnniw"));
       if (edx & bit_AVX5124FMAPS)
 	assert (__builtin_cpu_supports ("avx5124fmaps"));
-      if (ecx & bit_AVX512VPOPCNTDQ)
-	assert (__builtin_cpu_supports ("avx512vpopcntdq"));
     }
+
+  /* Check cpuid level of extended features.  */
+  __cpuid (0x80000000, ext_level, ebx, ecx, edx);
+
+  if (ext_level >= 0x80000001)
+    {
+      __cpuid (0x80000001, eax, ebx, ecx, edx);
+
+      if (ecx & bit_SSE4a)
+	assert (__builtin_cpu_supports ("sse4a"));
+      if (ecx & bit_FMA4)
+	assert (__builtin_cpu_supports ("fma4"));
+      if (ecx & bit_XOP)
+	assert (__builtin_cpu_supports ("xop"));
+    }
 }
 
 static int __attribute__ ((noinline))
Index: libgcc/config/i386/cpuinfo.c
===================================================================
--- libgcc/config/i386/cpuinfo.c	(revision 244369)
+++ libgcc/config/i386/cpuinfo.c	(working copy)
@@ -215,6 +215,9 @@ 
 get_available_features (unsigned int ecx, unsigned int edx,
 			int max_cpuid_level)
 {
+  unsigned int eax, ebx;
+  unsigned int ext_level;
+
   unsigned int features = 0;
 
   if (edx & bit_CMOV)
@@ -247,7 +250,6 @@ 
   /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
   if (max_cpuid_level >= 7)
     {
-      unsigned int eax, ebx, ecx, edx;
       __cpuid_count (7, 0, eax, ebx, ecx, edx);
       if (ebx & bit_BMI)
         features |= (1 << FEATURE_BMI);
@@ -273,20 +275,18 @@ 
 	features |= (1 << FEATURE_AVX512IFMA);
       if (ecx & bit_AVX512VBMI)
 	features |= (1 << FEATURE_AVX512VBMI);
+      if (ecx & bit_AVX512VPOPCNTDQ)
+	features |= (1 << FEATURE_AVX512VPOPCNTDQ);
       if (edx & bit_AVX5124VNNIW)
 	features |= (1 << FEATURE_AVX5124VNNIW);
       if (edx & bit_AVX5124FMAPS)
 	features |= (1 << FEATURE_AVX5124FMAPS);
-      if (ecx & bit_AVX512VPOPCNTDQ)
-	features |= (1 << FEATURE_AVX512VPOPCNTDQ);
     }
 
-  unsigned int ext_level;
-  unsigned int eax, ebx;
   /* Check cpuid level of extended features.  */
   __cpuid (0x80000000, ext_level, ebx, ecx, edx);
 
-  if (ext_level > 0x80000000)
+  if (ext_level >= 0x80000001)
     {
       __cpuid (0x80000001, eax, ebx, ecx, edx);