about summary refs log tree commit diff
path: root/sysdeps/x86/cpu-tunables.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-06-29 16:36:08 -0700
committerH.J. Lu <hjl.tools@gmail.com>2020-07-13 06:05:16 -0700
commit107e6a3c2212ba7a3a4ec7cae8d82d73f7c95d0b (patch)
treeb23f1c5ba166bd28f519fa36f225a31407b45270 /sysdeps/x86/cpu-tunables.c
parent10b01bd4529336bffc2c398ce43a171ed94aacc7 (diff)
downloadglibc-107e6a3c2212ba7a3a4ec7cae8d82d73f7c95d0b.tar.gz
glibc-107e6a3c2212ba7a3a4ec7cae8d82d73f7c95d0b.tar.xz
glibc-107e6a3c2212ba7a3a4ec7cae8d82d73f7c95d0b.zip
x86: Support usable check for all CPU features
Support usable check for all CPU features with the following changes:

1. Change struct cpu_features to

struct cpuid_features
{
  struct cpuid_registers cpuid;
  struct cpuid_registers usable;
};

struct cpu_features
{
  struct cpu_features_basic basic;
  struct cpuid_features features[COMMON_CPUID_INDEX_MAX];
  unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX];
...
};

so that there is a usable bit for each cpuid bit.
2. After the cpuid bits have been initialized, copy the known bits to the
usable bits.  EAX/EBX from INDEX_1 and EAX from INDEX_7 aren't used for
CPU feature detection.
3. Clear the usable bits which require OS support.
4. If the feature is supported by OS, copy its cpuid bit to its usable
bit.
5. Replace HAS_CPU_FEATURE and CPU_FEATURES_CPU_P with CPU_FEATURE_USABLE
and CPU_FEATURE_USABLE_P to check if a feature is usable.
6. Add DEPR_FPU_CS_DS for INDEX_7_EBX_13.
7. Unset MPX feature since it has been deprecated.

The results are

1. If the feature is known and doesn't requre OS support, its usable bit
is copied from the cpuid bit.
2. Otherwise, its usable bit is copied from the cpuid bit only if the
feature is known to supported by OS.
3. CPU_FEATURE_USABLE/CPU_FEATURE_USABLE_P are used to check if the
feature can be used.
4. HAS_CPU_FEATURE/CPU_FEATURE_CPU_P are used to check if CPU supports
the feature.
Diffstat (limited to 'sysdeps/x86/cpu-tunables.c')
-rw-r--r--sysdeps/x86/cpu-tunables.c168
1 files changed, 62 insertions, 106 deletions
diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
index 666ec571f2..588bbf9448 100644
--- a/sysdeps/x86/cpu-tunables.c
+++ b/sysdeps/x86/cpu-tunables.c
@@ -43,66 +43,45 @@ extern __typeof (memcmp) DEFAULT_MEMCMP;
   _Static_assert (sizeof (#name) - 1 == len, #name " != " #len);	\
   if (!DEFAULT_MEMCMP (f, #name, len))					\
     {									\
-      cpu_features->cpuid[index_cpu_##name].reg_##name			\
-	&= ~bit_cpu_##name;						\
+      CPU_FEATURE_UNSET (cpu_features, name)				\
       break;								\
     }
 
-/* Disable an ARCH feature NAME.  We don't enable an ARCH feature which
-   isn't available.  */
-# define CHECK_GLIBC_IFUNC_ARCH_OFF(f, cpu_features, name, len)		\
+/* Disable a preferred feature NAME.  We don't enable a preferred feature
+   which isn't available.  */
+# define CHECK_GLIBC_IFUNC_PREFERRED_OFF(f, cpu_features, name, len)	\
   _Static_assert (sizeof (#name) - 1 == len, #name " != " #len);	\
   if (!DEFAULT_MEMCMP (f, #name, len))					\
     {									\
-      cpu_features->feature_##name[index_arch_##name]			\
+      cpu_features->preferred[index_arch_##name]			\
 	&= ~bit_arch_##name;						\
       break;								\
     }
 
-/* Enable/disable an ARCH feature NAME.  */
-# define CHECK_GLIBC_IFUNC_ARCH_BOTH(f, cpu_features, name, disable,	\
-				    len)				\
+/* Enable/disable a preferred feature NAME.  */
+# define CHECK_GLIBC_IFUNC_PREFERRED_BOTH(f, cpu_features, name,	\
+					  disable, len)			\
   _Static_assert (sizeof (#name) - 1 == len, #name " != " #len);	\
   if (!DEFAULT_MEMCMP (f, #name, len))					\
     {									\
       if (disable)							\
-	cpu_features->feature_##name[index_arch_##name]			\
-	  &= ~bit_arch_##name;						\
+	cpu_features->preferred[index_arch_##name] &= ~bit_arch_##name;	\
       else								\
-	cpu_features->feature_##name[index_arch_##name]			\
-	  |= bit_arch_##name;						\
+	cpu_features->preferred[index_arch_##name] |= bit_arch_##name;	\
       break;								\
     }
 
-/* Enable/disable an ARCH feature NAME.  Enable an ARCH feature only
-   if the ARCH feature NEED is also enabled.  */
-# define CHECK_GLIBC_IFUNC_ARCH_NEED_ARCH_BOTH(f, cpu_features, name,	\
+/* Enable/disable a preferred feature NAME.  Enable a preferred feature
+   only if the feature NEED is usable.  */
+# define CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH(f, cpu_features, name,	\
 					       need, disable, len)	\
   _Static_assert (sizeof (#name) - 1 == len, #name " != " #len);	\
   if (!DEFAULT_MEMCMP (f, #name, len))					\
     {									\
       if (disable)							\
-	cpu_features->feature_##name[index_arch_##name]			\
-	  &= ~bit_arch_##name;						\
-      else if (CPU_FEATURES_ARCH_P (cpu_features, need))		\
-	cpu_features->feature_##name[index_arch_##name]			\
-	  |= bit_arch_##name;						\
-      break;								\
-    }
-
-/* Enable/disable an ARCH feature NAME.  Enable an ARCH feature only
-   if the CPU feature NEED is also enabled.  */
-# define CHECK_GLIBC_IFUNC_ARCH_NEED_CPU_BOTH(f, cpu_features, name,	\
-					      need, disable, len)	\
-  _Static_assert (sizeof (#name) - 1 == len, #name " != " #len);	\
-  if (!DEFAULT_MEMCMP (f, #name, len))					\
-    {									\
-      if (disable)							\
-	cpu_features->feature_##name[index_arch_##name]			\
-	  &= ~bit_arch_##name;						\
-      else if (CPU_FEATURES_CPU_P (cpu_features, need))			\
-	cpu_features->feature_##name[index_arch_##name]			\
-	  |= bit_arch_##name;						\
+	cpu_features->preferred[index_arch_##name] &= ~bit_arch_##name;	\
+      else if (CPU_FEATURE_USABLE_P (cpu_features, need))		\
+	cpu_features->preferred[index_arch_##name] |= bit_arch_##name;	\
       break;								\
     }
 
@@ -178,8 +157,8 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, ERMS, 4);
 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, FMA4, 4);
 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, SSE2, 4);
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features, I586, 4);
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features, I686, 4);
+	      CHECK_GLIBC_IFUNC_PREFERRED_OFF (n, cpu_features, I586, 4);
+	      CHECK_GLIBC_IFUNC_PREFERRED_OFF (n, cpu_features, I686, 4);
 	    }
 	  break;
 	case 5:
@@ -197,6 +176,13 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, POPCNT, 6);
 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, SSE4_1, 6);
 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, SSE4_2, 6);
+	      if (!DEFAULT_MEMCMP (n, "XSAVEC", 6))
+		{
+		  /* Update xsave_state_size to XSAVE state size.  */
+		  cpu_features->xsave_state_size
+		    = cpu_features->xsave_state_full_size;
+		  CPU_FEATURE_UNSET (cpu_features, XSAVEC);
+		}
 	    }
 	  break;
 	case 7:
@@ -216,115 +202,85 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, AVX512PF, 8);
 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, AVX512VL, 8);
 	    }
-	  CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features, Slow_BSF,
-				       disable, 8);
-	  break;
-	case 10:
-	  if (disable)
-	    {
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features, AVX_Usable,
-					  10);
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features, FMA_Usable,
-					  10);
-	    }
+	  CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features, Slow_BSF,
+					    disable, 8);
 	  break;
 	case 11:
-	  if (disable)
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features, AVX2_Usable,
-					  11);
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features, FMA4_Usable,
-					  11);
-	    }
-	  CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features, Prefer_ERMS,
-				       disable, 11);
-	  CHECK_GLIBC_IFUNC_ARCH_NEED_CPU_BOTH (n, cpu_features,
-						Slow_SSE4_2, SSE4_2,
+	      CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
+						Prefer_ERMS,
 						disable, 11);
-	  CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features, Prefer_FSRM,
-				       disable, 11);
-	  break;
-	case 13:
-	  if (disable)
-	    {
-	      /* Update xsave_state_size to XSAVE state size.  */
-	      cpu_features->xsave_state_size
-		= cpu_features->xsave_state_full_size;
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features,
-					  XSAVEC_Usable, 13);
-	    }
-	  break;
-	case 14:
-	  if (disable)
-	    {
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features,
-					  AVX512F_Usable, 14);
+	      CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
+						Prefer_FSRM,
+						disable, 11);
+	      CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH (n, cpu_features,
+						     Slow_SSE4_2,
+						     SSE4_2,
+						     disable, 11);
 	    }
 	  break;
 	case 15:
-	  if (disable)
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features,
-					  AVX512DQ_Usable, 15);
+	      CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
+						Fast_Rep_String,
+						disable, 15);
 	    }
-	  CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features, Fast_Rep_String,
-				       disable, 15);
 	  break;
 	case 16:
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_NEED_ARCH_BOTH
-		(n, cpu_features, Prefer_No_AVX512, AVX512F_Usable,
+	      CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
+		(n, cpu_features, Prefer_No_AVX512, AVX512F,
 		 disable, 16);
 	    }
 	  break;
 	case 18:
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features,
-					   Fast_Copy_Backward, disable,
-					   18);
+	      CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
+						Fast_Copy_Backward,
+						disable, 18);
 	    }
 	  break;
 	case 19:
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features,
-					   Fast_Unaligned_Load, disable,
-					   19);
-	      CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features,
-					   Fast_Unaligned_Copy, disable,
-					   19);
+	      CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
+						Fast_Unaligned_Load,
+						disable, 19);
+	      CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
+						Fast_Unaligned_Copy,
+						disable, 19);
 	    }
 	  break;
 	case 20:
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_NEED_ARCH_BOTH
-		(n, cpu_features, Prefer_No_VZEROUPPER, AVX_Usable,
-		 disable, 20);
+	      CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
+		(n, cpu_features, Prefer_No_VZEROUPPER, AVX, disable,
+		 20);
 	    }
 	  break;
 	case 21:
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features,
-					   Prefer_MAP_32BIT_EXEC, disable,
-					   21);
+	      CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
+						Prefer_MAP_32BIT_EXEC,
+						disable, 21);
 	    }
 	  break;
 	case 23:
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_NEED_ARCH_BOTH
-		(n, cpu_features, AVX_Fast_Unaligned_Load, AVX_Usable,
+	      CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
+		(n, cpu_features, AVX_Fast_Unaligned_Load, AVX,
 		 disable, 23);
 	    }
 	  break;
 	case 24:
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_NEED_ARCH_BOTH
-		(n, cpu_features, MathVec_Prefer_No_AVX512,
-		 AVX512F_Usable, disable, 24);
+	      CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
+		(n, cpu_features, MathVec_Prefer_No_AVX512, AVX512F,
+		 disable, 24);
 	    }
 	  break;
 	case 26:
 	    {
-	      CHECK_GLIBC_IFUNC_ARCH_NEED_CPU_BOTH
+	      CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
 		(n, cpu_features, Prefer_PMINUB_for_stringop, SSE2,
 		 disable, 26);
 	    }