[compiler-rt] r344830 - [X86][compiler-rt] Add additional CPUs and features to the cpu detection to match libgcc

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 19 20:49:05 PDT 2018


Author: ctopper
Date: Fri Oct 19 20:49:04 2018
New Revision: 344830

URL: http://llvm.org/viewvc/llvm-project?rev=344830&view=rev
Log:
[X86][compiler-rt] Add additional CPUs and features to the cpu detection to match libgcc

Summary: This patch adds additional features and cpus from libgcc. Unfortunately we've overflowed the existing 32-bits of features so we had to add a new __cpu_features2 variable to hold the additional bits. This matches libgcc as far as I can tell.

Reviewers: echristo

Reviewed By: echristo

Subscribers: dberris, llvm-commits

Differential Revision: https://reviews.llvm.org/D53461

Modified:
    compiler-rt/trunk/lib/builtins/cpu_model.c

Modified: compiler-rt/trunk/lib/builtins/cpu_model.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/cpu_model.c?rev=344830&r1=344829&r2=344830&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/cpu_model.c (original)
+++ compiler-rt/trunk/lib/builtins/cpu_model.c Fri Oct 19 20:49:04 2018
@@ -55,6 +55,9 @@ enum ProcessorTypes {
   AMD_BTVER2,
   AMDFAM17H,
   INTEL_KNM,
+  INTEL_GOLDMONT,
+  INTEL_GOLDMONT_PLUS,
+  INTEL_TREMONT,
   CPU_TYPE_MAX
 };
 
@@ -76,6 +79,8 @@ enum ProcessorSubtypes {
   INTEL_COREI7_SKYLAKE,
   INTEL_COREI7_SKYLAKE_AVX512,
   INTEL_COREI7_CANNONLAKE,
+  INTEL_COREI7_ICELAKE_CLIENT,
+  INTEL_COREI7_ICELAKE_SERVER,
   CPU_SUBTYPE_MAX
 };
 
@@ -110,7 +115,12 @@ enum ProcessorFeatures {
   FEATURE_AVX512IFMA,
   FEATURE_AVX5124VNNIW,
   FEATURE_AVX5124FMAPS,
-  FEATURE_AVX512VPOPCNTDQ
+  FEATURE_AVX512VPOPCNTDQ,
+  FEATURE_AVX512VBMI2,
+  FEATURE_GFNI,
+  FEATURE_VPCLMULQDQ,
+  FEATURE_AVX512VNNI,
+  FEATURE_AVX512BITALG
 };
 
 // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
@@ -364,6 +374,14 @@ getIntelProcessorTypeAndSubtype(unsigned
     case 0x4c: // really airmont
       *Type = INTEL_SILVERMONT;
       break; // "silvermont"
+    // Goldmont:
+    case 0x5c: // Apollo Lake
+    case 0x5f: // Denverton
+      *Type = INTEL_GOLDMONT;
+      break; // "goldmont"
+    case 0x7a:
+      *Type = INTEL_GOLDMONT_PLUS;
+      break;
 
     case 0x57:
       *Type = INTEL_KNL; // knl
@@ -438,35 +456,45 @@ static void getAMDProcessorTypeAndSubtyp
 }
 
 static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
-                                 unsigned *FeaturesOut) {
+                                 unsigned *FeaturesOut,
+                                 unsigned *Features2Out) {
   unsigned Features = 0;
+  unsigned Features2 = 0;
   unsigned EAX, EBX;
 
+#define setFeature(F)              \
+  do {                             \
+    if (F < 32)                    \
+      Features |= 1 << F;          \
+    else if (F < 64)               \
+      Features2 |= 1 << (F - 32);  \
+  } while (0)
+
   if ((EDX >> 15) & 1)
-    Features |= 1 << FEATURE_CMOV;
+    setFeature(FEATURE_CMOV);
   if ((EDX >> 23) & 1)
-    Features |= 1 << FEATURE_MMX;
+    setFeature(FEATURE_MMX);
   if ((EDX >> 25) & 1)
-    Features |= 1 << FEATURE_SSE;
+    setFeature(FEATURE_SSE);
   if ((EDX >> 26) & 1)
-    Features |= 1 << FEATURE_SSE2;
+    setFeature(FEATURE_SSE2);
 
   if ((ECX >> 0) & 1)
-    Features |= 1 << FEATURE_SSE3;
+    setFeature(FEATURE_SSE3);
   if ((ECX >> 1) & 1)
-    Features |= 1 << FEATURE_PCLMUL;
+    setFeature(FEATURE_PCLMUL);
   if ((ECX >> 9) & 1)
-    Features |= 1 << FEATURE_SSSE3;
+    setFeature(FEATURE_SSSE3);
   if ((ECX >> 12) & 1)
-    Features |= 1 << FEATURE_FMA;
+    setFeature(FEATURE_FMA);
   if ((ECX >> 19) & 1)
-    Features |= 1 << FEATURE_SSE4_1;
+    setFeature(FEATURE_SSE4_1);
   if ((ECX >> 20) & 1)
-    Features |= 1 << FEATURE_SSE4_2;
+    setFeature(FEATURE_SSE4_2);
   if ((ECX >> 23) & 1)
-    Features |= 1 << FEATURE_POPCNT;
+    setFeature(FEATURE_POPCNT);
   if ((ECX >> 25) & 1)
-    Features |= 1 << FEATURE_AES;
+    setFeature(FEATURE_AES);
 
   // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
   // indicates that the AVX registers will be saved and restored on context
@@ -477,43 +505,53 @@ static void getAvailableFeatures(unsigne
   bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
 
   if (HasAVX)
-    Features |= 1 << FEATURE_AVX;
+    setFeature(FEATURE_AVX);
 
   bool HasLeaf7 =
       MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
 
   if (HasLeaf7 && ((EBX >> 3) & 1))
-    Features |= 1 << FEATURE_BMI;
+    setFeature(FEATURE_BMI);
   if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
-    Features |= 1 << FEATURE_AVX2;
+    setFeature(FEATURE_AVX2);
   if (HasLeaf7 && ((EBX >> 9) & 1))
-    Features |= 1 << FEATURE_BMI2;
+    setFeature(FEATURE_BMI2);
   if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512F;
+    setFeature(FEATURE_AVX512F);
   if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512DQ;
+    setFeature(FEATURE_AVX512DQ);
   if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512IFMA;
+    setFeature(FEATURE_AVX512IFMA);
   if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512PF;
+    setFeature(FEATURE_AVX512PF);
   if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512ER;
+    setFeature(FEATURE_AVX512ER);
   if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512CD;
+    setFeature(FEATURE_AVX512CD);
   if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512BW;
+    setFeature(FEATURE_AVX512BW);
   if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512VL;
+    setFeature(FEATURE_AVX512VL);
 
   if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512VBMI;
+    setFeature(FEATURE_AVX512VBMI);
+  if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
+    setFeature(FEATURE_AVX512VBMI2);
+  if (HasLeaf7 && ((ECX >> 8) & 1))
+    setFeature(FEATURE_GFNI);
+  if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
+    setFeature(FEATURE_VPCLMULQDQ);
+  if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
+    setFeature(FEATURE_AVX512VNNI);
+  if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
+    setFeature(FEATURE_AVX512BITALG);
   if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX512VPOPCNTDQ;
+    setFeature(FEATURE_AVX512VPOPCNTDQ);
 
   if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX5124VNNIW;
+    setFeature(FEATURE_AVX5124VNNIW);
   if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
-    Features |= 1 << FEATURE_AVX5124FMAPS;
+    setFeature(FEATURE_AVX5124FMAPS);
 
   unsigned MaxExtLevel;
   getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
@@ -521,13 +559,15 @@ static void getAvailableFeatures(unsigne
   bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
                      !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
   if (HasExtLeaf1 && ((ECX >> 6) & 1))
-    Features |= 1 << FEATURE_SSE4_A;
+    setFeature(FEATURE_SSE4_A);
   if (HasExtLeaf1 && ((ECX >> 11) & 1))
-    Features |= 1 << FEATURE_XOP;
+    setFeature(FEATURE_XOP);
   if (HasExtLeaf1 && ((ECX >> 16) & 1))
-    Features |= 1 << FEATURE_FMA4;
+    setFeature(FEATURE_FMA4);
 
   *FeaturesOut = Features;
+  *Features2Out = Features2;
+#undef setFeature
 }
 
 #if defined(HAVE_INIT_PRIORITY)
@@ -548,8 +588,9 @@ struct __processor_model {
   unsigned int __cpu_subtype;
   unsigned int __cpu_features[1];
 } __cpu_model = {0, 0, 0, {0}};
+unsigned int __cpu_features2;
 
-/* A constructor function that is sets __cpu_model and __cpu_features with
+/* A constructor function that is sets __cpu_model and __cpu_features2 with
    the right values.  This needs to run only once.  This constructor is
    given the highest priority and it should run before constructors without
    the priority set.  However, it still runs after ifunc initializers and
@@ -562,6 +603,7 @@ __cpu_indicator_init(void) {
   unsigned Vendor;
   unsigned Model, Family, Brand_id;
   unsigned Features = 0;
+  unsigned Features2 = 0;
 
   /* This function needs to run just once.  */
   if (__cpu_model.__cpu_vendor)
@@ -580,8 +622,9 @@ __cpu_indicator_init(void) {
   Brand_id = EBX & 0xff;
 
   /* Find available features. */
-  getAvailableFeatures(ECX, EDX, MaxLeaf, &Features);
+  getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2);
   __cpu_model.__cpu_features[0] = Features;
+  __cpu_features2 = Features2;
 
   if (Vendor == SIG_INTEL) {
     /* Get CPU type.  */




More information about the llvm-commits mailing list