[compiler-rt] r307558 - [X86] Resync cpu_model.c with llvm's Host.cpp in preparation for making it compatible with newer gcc.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 10 10:30:20 PDT 2017


Author: ctopper
Date: Mon Jul 10 10:30:20 2017
New Revision: 307558

URL: http://llvm.org/viewvc/llvm-project?rev=307558&view=rev
Log:
[X86] Resync cpu_model.c with llvm's Host.cpp in preparation for making it compatible with newer gcc.

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=307558&r1=307557&r2=307558&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/cpu_model.c (original)
+++ compiler-rt/trunk/lib/builtins/cpu_model.c Mon Jul 10 10:30:20 2017
@@ -67,6 +67,7 @@ enum ProcessorTypes {
   AMDATHLON,
   AMDFAM14H,
   AMDFAM16H,
+  AMDFAM17H,
   CPU_TYPE_MAX
 };
 
@@ -105,6 +106,7 @@ enum ProcessorSubtypes {
   AMD_BTVER2,
   AMDFAM15H_BDVER3,
   AMDFAM15H_BDVER4,
+  AMDFAM17H_ZNVER1,
   CPU_SUBTYPE_MAX
 };
 
@@ -164,11 +166,12 @@ static bool isCpuIdSupported() {
 
 /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
 /// the specified arguments.  If we can't run cpuid on the host, return true.
-static void getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
+static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
                                unsigned *rECX, unsigned *rEDX) {
+#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
 #if defined(__GNUC__) || defined(__clang__)
 #if defined(__x86_64__)
-  // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
+  // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
   __asm__("movq\t%%rbx, %%rsi\n\t"
           "cpuid\n\t"
           "xchgq\t%%rbx, %%rsi\n\t"
@@ -193,17 +196,20 @@ static void getX86CpuIDAndInfo(unsigned
   *rEBX = registers[1];
   *rECX = registers[2];
   *rEDX = registers[3];
+#endif
+  return false;
 #else
-  assert(0 && "This method is defined only for GNUC, Clang or MSVC.");
+  return true;
 #endif
 }
 
 /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
 /// the 4 values in the specified arguments.  If we can't run cpuid on the host,
 /// return true.
-static void getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
+static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
                                  unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
                                  unsigned *rEDX) {
+#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
 #if defined(__x86_64__) || defined(_M_X64)
 #if defined(__GNUC__) || defined(__clang__)
   // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
@@ -220,8 +226,6 @@ static void getX86CpuIDAndInfoEx(unsigne
   *rEBX = registers[1];
   *rECX = registers[2];
   *rEDX = registers[3];
-#else
-  assert(0 && "This method is defined only for GNUC, Clang or MSVC.");
 #endif
 #elif defined(__i386__) || defined(_M_IX86)
 #if defined(__GNUC__) || defined(__clang__)
@@ -244,12 +248,14 @@ static void getX86CpuIDAndInfoEx(unsigne
       mov   esi,rEDX
       mov   dword ptr [esi],edx
   }
-#else
-  assert(0 && "This method is defined only for GNUC, Clang or MSVC.");
 #endif
 #else
   assert(0 && "This method is defined only for x86.");
 #endif
+  return false;
+#else
+  return true;
+#endif
 }
 
 // Read control register 0 (XCR0). Used to detect features such as AVX.
@@ -283,10 +289,10 @@ static void detectX86FamilyModel(unsigne
   }
 }
 
-static void getIntelProcessorTypeAndSubtype(unsigned int Family,
-                                            unsigned int Model,
-                                            unsigned int Brand_id,
-                                            unsigned int Features,
+static void getIntelProcessorTypeAndSubtype(unsigned Family,
+                                            unsigned Model,
+                                            unsigned Brand_id,
+                                            unsigned Features,
                                             unsigned *Type, unsigned *Subtype) {
   if (Brand_id != 0)
     return;
@@ -427,15 +433,20 @@ static void getIntelProcessorTypeAndSubt
       break;
 
     // Skylake:
-    case 0x4e:
-      *Type = INTEL_COREI7; // "skylake-avx512"
-      *Subtype = INTEL_COREI7_SKYLAKE_AVX512;
-      break;
-    case 0x5e:
+    case 0x4e: // Skylake mobile
+    case 0x5e: // Skylake desktop
+    case 0x8e: // Kaby Lake mobile
+    case 0x9e: // Kaby Lake desktop
       *Type = INTEL_COREI7; // "skylake"
       *Subtype = INTEL_COREI7_SKYLAKE;
       break;
 
+    // Skylake Xeon:
+    case 0x55:
+      *Type = INTEL_COREI7; // "skylake"
+      *Subtype = INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512"
+      break;
+
     case 0x1c: // Most 45 nm Intel Atom processors
     case 0x26: // 45 nm Atom Lincroft
     case 0x27: // 32 nm Atom Medfield
@@ -567,9 +578,8 @@ static void getIntelProcessorTypeAndSubt
   }
 }
 
-static void getAMDProcessorTypeAndSubtype(unsigned int Family,
-                                          unsigned int Model,
-                                          unsigned int Features, unsigned *Type,
+static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
+                                          unsigned Features, unsigned *Type,
                                           unsigned *Subtype) {
   // FIXME: this poorly matches the generated SubtargetFeatureKV table.  There
   // appears to be no way to generate the wide variety of AMD-specific targets
@@ -683,15 +693,23 @@ static void getAMDProcessorTypeAndSubtyp
     }
     *Subtype = AMD_BTVER2;
     break; // "btver2"
+  case 23:
+    *Type = AMDFAM17H;
+    if (Features & (1 << FEATURE_ADX)) {
+      *Subtype = AMDFAM17H_ZNVER1;
+      break; // "znver1"
+    }
+    *Subtype =  AMD_BTVER1;
+    break;
   default:
     break; // "generic"
   }
 }
 
-static unsigned getAvailableFeatures(unsigned int ECX, unsigned int EDX,
+static unsigned getAvailableFeatures(unsigned ECX, unsigned EDX,
                                      unsigned MaxLeaf) {
   unsigned Features = 0;
-  unsigned int EAX, EBX;
+  unsigned EAX, EBX;
   Features |= (((EDX >> 23) & 1) << FEATURE_MMX);
   Features |= (((EDX >> 25) & 1) << FEATURE_SSE);
   Features |= (((EDX >> 26) & 1) << FEATURE_SSE2);
@@ -708,8 +726,7 @@ static unsigned getAvailableFeatures(uns
   bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
                 ((EAX & 0x6) == 0x6);
   bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
-  bool HasLeaf7 = MaxLeaf >= 0x7;
-  getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
+  bool HasLeaf7 = MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
   bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
   bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20);
   bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1);
@@ -719,8 +736,14 @@ static unsigned getAvailableFeatures(uns
   Features |= (HasAVX512Save << FEATURE_AVX512SAVE);
   Features |= (HasADX << FEATURE_ADX);
 
-  getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
-  Features |= (((EDX >> 29) & 0x1) << FEATURE_EM64T);
+  unsigned MaxExtLevel;
+  getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
+
+  bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
+                     !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
+  if (HasExtLeaf1)
+    Features |= (((EDX >> 29) & 0x1) << FEATURE_EM64T);
+
   return Features;
 }
 
@@ -751,11 +774,11 @@ struct __processor_model {
 
 int CONSTRUCTOR_ATTRIBUTE
 __cpu_indicator_init(void) {
-  unsigned int EAX, EBX, ECX, EDX;
-  unsigned int MaxLeaf = 5;
-  unsigned int Vendor;
-  unsigned int Model, Family, Brand_id;
-  unsigned int Features = 0;
+  unsigned EAX, EBX, ECX, EDX;
+  unsigned MaxLeaf = 5;
+  unsigned Vendor;
+  unsigned Model, Family, Brand_id;
+  unsigned Features = 0;
 
   /* This function needs to run just once.  */
   if (__cpu_model.__cpu_vendor)
@@ -765,9 +788,7 @@ __cpu_indicator_init(void) {
     return -1;
 
   /* Assume cpuid insn present. Run in level 0 to get vendor id. */
-  getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX);
-
-  if (MaxLeaf < 1) {
+  if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1) {
     __cpu_model.__cpu_vendor = VENDOR_OTHER;
     return -1;
   }




More information about the llvm-commits mailing list