[llvm] r271921 - [cpu-detection] Substantial refactor of Host CPU detection code (x86)

Alina Sbirlea via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 6 11:30:00 PDT 2016


Author: asbirlea
Date: Mon Jun  6 13:29:59 2016
New Revision: 271921

URL: http://llvm.org/viewvc/llvm-project?rev=271921&view=rev
Log:
[cpu-detection] Substantial refactor of Host CPU detection code (x86)

Summary:
Following D20970 (committed as r271726).
This is a substantial refactoring of the host CPU detection code.

There is no functionality change intended, but the changes are extensive.

Definitions of architecture types and subtypes are by no means exhaustive or
perfectly defined, but a fair starting point.
Suggestions for futher improvements are welcome.

Reviewers: llvm-commits

Differential Revision: http://reviews.llvm.org/D20988

Modified:
    llvm/trunk/lib/Support/Host.cpp

Modified: llvm/trunk/lib/Support/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Host.cpp?rev=271921&r1=271920&r2=271921&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Host.cpp (original)
+++ llvm/trunk/lib/Support/Host.cpp Mon Jun  6 13:29:59 2016
@@ -73,6 +73,102 @@ static ssize_t LLVM_ATTRIBUTE_UNUSED rea
     defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) ||            \
     defined(_M_X64)
 
+enum VendorSignatures {
+  SIG_INTEL = 0x756e6547 /* Genu */,
+  SIG_AMD = 0x68747541 /* Auth */
+};
+
+enum ProcessorVendors {
+  VENDOR_INTEL = 1,
+  VENDOR_AMD,
+  VENDOR_OTHER,
+  VENDOR_MAX
+};
+
+enum ProcessorTypes {
+  INTEL_ATOM = 1,
+  INTEL_CORE2,
+  INTEL_COREI7,
+  AMDFAM10H,
+  AMDFAM15H,
+  INTEL_i386,
+  INTEL_i486,
+  INTEL_PENTIUM,
+  INTEL_PENTIUM_PRO,
+  INTEL_PENTIUM_II,
+  INTEL_PENTIUM_III,
+  INTEL_PENTIUM_IV,
+  INTEL_PENTIUM_M,
+  INTEL_CORE_DUO,
+  INTEL_XEONPHI,
+  INTEL_X86_64,
+  INTEL_NOCONA,
+  INTEL_PRESCOTT,
+  AMD_i486,
+  AMDPENTIUM,
+  AMDATHLON,
+  AMDFAM14H,
+  AMDFAM16H,
+  CPU_TYPE_MAX
+};
+
+enum ProcessorSubtypes {
+  INTEL_COREI7_NEHALEM = 1,
+  INTEL_COREI7_WESTMERE,
+  INTEL_COREI7_SANDYBRIDGE,
+  AMDFAM10H_BARCELONA,
+  AMDFAM10H_SHANGHAI,
+  AMDFAM10H_ISTANBUL,
+  AMDFAM15H_BDVER1,
+  AMDFAM15H_BDVER2,
+  INTEL_PENTIUM_MMX,
+  INTEL_CORE2_65,
+  INTEL_CORE2_45,
+  INTEL_COREI7_IVYBRIDGE,
+  INTEL_COREI7_HASWELL,
+  INTEL_COREI7_BROADWELL,
+  INTEL_COREI7_SKYLAKE,
+  INTEL_COREI7_SKYLAKE_AVX512,
+  INTEL_ATOM_BONNELL,
+  INTEL_ATOM_SILVERMONT,
+  INTEL_KNIGHTS_LANDING,
+  AMDPENTIUM_K6,
+  AMDPENTIUM_K62,
+  AMDPENTIUM_K63,
+  AMDPENTIUM_GEODE,
+  AMDATHLON_TBIRD,
+  AMDATHLON_MP,
+  AMDATHLON_XP,
+  AMDATHLON_K8SSE3,
+  AMDATHLON_OPTERON,
+  AMDATHLON_FX,
+  AMDATHLON_64,
+  AMD_BTVER1,
+  AMD_BTVER2,
+  AMDFAM15H_BDVER3,
+  AMDFAM15H_BDVER4,
+  CPU_SUBTYPE_MAX
+};
+
+enum ProcessorFeatures {
+  FEATURE_CMOV = 0,
+  FEATURE_MMX,
+  FEATURE_POPCNT,
+  FEATURE_SSE,
+  FEATURE_SSE2,
+  FEATURE_SSE3,
+  FEATURE_SSSE3,
+  FEATURE_SSE4_1,
+  FEATURE_SSE4_2,
+  FEATURE_AVX,
+  FEATURE_AVX2,
+  FEATURE_AVX512,
+  FEATURE_AVX512SAVE,
+  FEATURE_MOVBE,
+  FEATURE_ADX,
+  FEATURE_EM64T
+};
+
 /// 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 bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
@@ -199,30 +295,424 @@ static void detectX86FamilyModel(unsigne
   }
 }
 
-StringRef sys::getHostCPUName() {
-  unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
-  if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
-    return "generic";
-  unsigned Family = 0;
-  unsigned Model = 0;
-  detectX86FamilyModel(EAX, &Family, &Model);
+static void
+getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,
+                                unsigned int Brand_id, unsigned int Features,
+                                unsigned *Type, unsigned *Subtype) {
+  if (Brand_id != 0)
+    return;
+  switch (Family) {
+  case 3:
+    *Type = INTEL_i386;
+    break;
+  case 4:
+    switch (Model) {
+    case 0: // Intel486 DX processors
+    case 1: // Intel486 DX processors
+    case 2: // Intel486 SX processors
+    case 3: // Intel487 processors, IntelDX2 OverDrive processors,
+            // IntelDX2 processors
+    case 4: // Intel486 SL processor
+    case 5: // IntelSX2 processors
+    case 7: // Write-Back Enhanced IntelDX2 processors
+    case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
+    default:
+      *Type = INTEL_i486;
+      break;
+    }
+  case 5:
+    switch (Model) {
+    case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
+            // Pentium processors (60, 66)
+    case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
+            // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
+            // 150, 166, 200)
+    case 3: // Pentium OverDrive processors for Intel486 processor-based
+            // systems
+      *Type = INTEL_PENTIUM;
+      break;
+    case 4: // Pentium OverDrive processor with MMX technology for Pentium
+            // processor (75, 90, 100, 120, 133), Pentium processor with
+            // MMX technology (166, 200)
+      *Type = INTEL_PENTIUM;
+      *Subtype = INTEL_PENTIUM_MMX;
+      break;
+    default:
+      *Type = INTEL_PENTIUM;
+      break;
+    }
+  case 6:
+    switch (Model) {
+    case 0x01: // Pentium Pro processor
+      *Type = INTEL_PENTIUM_PRO;
+      break;
+    case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
+               // model 03
+    case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
+               // model 05, and Intel Celeron processor, model 05
+    case 0x06: // Celeron processor, model 06
+      *Type = INTEL_PENTIUM_II;
+      break;
+    case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
+               // processor, model 07
+    case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
+               // model 08, and Celeron processor, model 08
+    case 0x0a: // Pentium III Xeon processor, model 0Ah
+    case 0x0b: // Pentium III processor, model 0Bh
+      *Type = INTEL_PENTIUM_III;
+      break;
+    case 0x09: // Intel Pentium M processor, Intel Celeron M processor model 09.
+    case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
+               // 0Dh. All processors are manufactured using the 90 nm process.
+    case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
+               // Integrated Processor with Intel QuickAssist Technology
+      *Type = INTEL_PENTIUM_M;
+      break;
+    case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
+               // 0Eh. All processors are manufactured using the 65 nm process.
+      *Type = INTEL_CORE_DUO;
+      break;   // yonah
+    case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
+               // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
+               // mobile processor, Intel Core 2 Extreme processor, Intel
+               // Pentium Dual-Core processor, Intel Xeon processor, model
+               // 0Fh. All processors are manufactured using the 65 nm process.
+    case 0x16: // Intel Celeron processor model 16h. All processors are
+               // manufactured using the 65 nm process
+      *Type = INTEL_CORE2; // "core2"
+      *Subtype = INTEL_CORE2_65;
+      break;
+    case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
+               // 17h. All processors are manufactured using the 45 nm process.
+               //
+               // 45nm: Penryn , Wolfdale, Yorkfield (XE)
+    case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
+               // the 45 nm process.
+      *Type = INTEL_CORE2; // "penryn"
+      *Subtype = INTEL_CORE2_45;
+      break;
+    case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
+               // processors are manufactured using the 45 nm process.
+    case 0x1e: // Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz.
+               // As found in a Summer 2010 model iMac.
+    case 0x1f:
+    case 0x2e:             // Nehalem EX
+      *Type = INTEL_COREI7; // "nehalem"
+      *Subtype = INTEL_COREI7_NEHALEM;
+      break;
+    case 0x25: // Intel Core i7, laptop version.
+    case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
+               // processors are manufactured using the 32 nm process.
+    case 0x2f: // Westmere EX
+      *Type = INTEL_COREI7; // "westmere"
+      *Subtype = INTEL_COREI7_WESTMERE;
+      break;
+    case 0x2a: // Intel Core i7 processor. All processors are manufactured
+               // using the 32 nm process.
+    case 0x2d:
+      *Type = INTEL_COREI7; //"sandybridge"
+      *Subtype = INTEL_COREI7_SANDYBRIDGE;
+      break;
+    case 0x3a:
+    case 0x3e:             // Ivy Bridge EP
+      *Type = INTEL_COREI7; // "ivybridge"
+      *Subtype = INTEL_COREI7_IVYBRIDGE;
+      break;
+
+    // Haswell:
+    case 0x3c:
+    case 0x3f:
+    case 0x45:
+    case 0x46:
+      *Type = INTEL_COREI7; // "haswell"
+      *Subtype = INTEL_COREI7_HASWELL;
+      break;
+
+    // Broadwell:
+    case 0x3d:
+    case 0x47:
+    case 0x4f:
+    case 0x56:
+      *Type = INTEL_COREI7; // "broadwell"
+      *Subtype = INTEL_COREI7_BROADWELL;
+      break;
+
+    // Skylake:
+    case 0x4e:
+      *Type = INTEL_COREI7; // "skylake-avx512"
+      *Subtype = INTEL_COREI7_SKYLAKE_AVX512;
+      break;
+    case 0x5e:
+      *Type = INTEL_COREI7; // "skylake"
+      *Subtype = INTEL_COREI7_SKYLAKE;
+      break;
+
+    case 0x1c: // Most 45 nm Intel Atom processors
+    case 0x26: // 45 nm Atom Lincroft
+    case 0x27: // 32 nm Atom Medfield
+    case 0x35: // 32 nm Atom Midview
+    case 0x36: // 32 nm Atom Midview
+      *Type = INTEL_ATOM;
+      *Subtype = INTEL_ATOM_BONNELL;
+      break; // "bonnell"
+
+    // Atom Silvermont codes from the Intel software optimization guide.
+    case 0x37:
+    case 0x4a:
+    case 0x4d:
+    case 0x5a:
+    case 0x5d:
+    case 0x4c: // really airmont
+      *Type = INTEL_ATOM;
+      *Subtype = INTEL_ATOM_SILVERMONT;
+      break; // "silvermont"
+
+    case 0x57:
+      *Type = INTEL_XEONPHI; // knl
+      *Subtype = INTEL_KNIGHTS_LANDING;
+      break;
+
+    default: // Unknown family 6 CPU, try to guess.
+      if (Features & (1 << FEATURE_AVX512)) {
+        *Type = INTEL_XEONPHI; // knl
+        *Subtype = INTEL_KNIGHTS_LANDING;
+        break;
+      }
+      if (Features & (1 << FEATURE_ADX)) {
+        *Type = INTEL_COREI7;
+        *Subtype = INTEL_COREI7_BROADWELL;
+        break;
+      }
+      if (Features & (1 << FEATURE_AVX2)) {
+        *Type = INTEL_COREI7;
+        *Subtype = INTEL_COREI7_HASWELL;
+        break;
+      }
+      if (Features & (1 << FEATURE_AVX)) {
+        *Type = INTEL_COREI7;
+        *Subtype = INTEL_COREI7_SANDYBRIDGE;
+        break;
+      }
+      if (Features & (1 << FEATURE_SSE4_2)) {
+        if (Features & (1 << FEATURE_MOVBE)) {
+          *Type = INTEL_ATOM;
+          *Subtype = INTEL_ATOM_SILVERMONT;
+        } else {
+          *Type = INTEL_COREI7;
+          *Subtype = INTEL_COREI7_NEHALEM;
+        }
+        break;
+      }
+      if (Features & (1 << FEATURE_SSE4_1)) {
+        *Type = INTEL_CORE2; // "penryn"
+        *Subtype = INTEL_CORE2_45;
+        break;
+      }
+      if (Features & (1 << FEATURE_SSSE3)) {
+        if (Features & (1 << FEATURE_MOVBE)) {
+          *Type = INTEL_ATOM;
+          *Subtype = INTEL_ATOM_BONNELL; // "bonnell"
+        } else {
+          *Type = INTEL_CORE2; // "core2"
+          *Subtype = INTEL_CORE2_65;
+        }
+        break;
+      }
+      if (Features & (1 << FEATURE_EM64T)) {
+        *Type = INTEL_X86_64;
+        break; // x86-64
+      }
+      if (Features & (1 << FEATURE_SSE2)) {
+        *Type = INTEL_PENTIUM_M;
+        break;
+      }
+      if (Features & (1 << FEATURE_SSE)) {
+        *Type = INTEL_PENTIUM_III;
+        break;
+      }
+      if (Features & (1 << FEATURE_MMX)) {
+        *Type = INTEL_PENTIUM_II;
+        break;
+      }
+      *Type = INTEL_PENTIUM_PRO;
+      break;
+    }
+  case 15: {
+    switch (Model) {
+    case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
+            // model 00h and manufactured using the 0.18 micron process.
+    case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
+            // processor MP, and Intel Celeron processor. All processors are
+            // model 01h and manufactured using the 0.18 micron process.
+    case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
+            // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
+            // processor, and Mobile Intel Celeron processor. All processors
+            // are model 02h and manufactured using the 0.13 micron process.
+      *Type =
+          ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV);
+      break;
+
+    case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
+            // processor. All processors are model 03h and manufactured using
+            // the 90 nm process.
+    case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
+            // Pentium D processor, Intel Xeon processor, Intel Xeon
+            // processor MP, Intel Celeron D processor. All processors are
+            // model 04h and manufactured using the 90 nm process.
+    case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
+            // Extreme Edition, Intel Xeon processor, Intel Xeon processor
+            // MP, Intel Celeron D processor. All processors are model 06h
+            // and manufactured using the 65 nm process.
+      *Type =
+          ((Features & (1 << FEATURE_EM64T)) ? INTEL_NOCONA : INTEL_PRESCOTT);
+      break;
+
+    default:
+      *Type =
+          ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV);
+      break;
+    }
+  }
+  default:
+    break; /*"generic"*/
+  }
+}
+
+static void getAMDProcessorTypeAndSubtype(unsigned int Family,
+                                          unsigned int Model,
+                                          unsigned int 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
+  // from the information returned from CPUID.
+  switch (Family) {
+  case 4:
+    *Type = AMD_i486;
+  case 5:
+    *Type = AMDPENTIUM;
+    switch (Model) {
+    case 6:
+    case 7:
+      *Subtype = AMDPENTIUM_K6;
+      break; // "k6"
+    case 8:
+      *Subtype = AMDPENTIUM_K62;
+      break; // "k6-2"
+    case 9:
+    case 13:
+      *Subtype = AMDPENTIUM_K63;
+      break; // "k6-3"
+    case 10:
+      *Subtype = AMDPENTIUM_GEODE;
+      break; // "geode"
+    default:
+      break;
+    }
+  case 6:
+    *Type = AMDATHLON;
+    switch (Model) {
+    case 4:
+      *Subtype = AMDATHLON_TBIRD;
+      break; // "athlon-tbird"
+    case 6:
+    case 7:
+    case 8:
+      *Subtype = AMDATHLON_MP;
+      break; // "athlon-mp"
+    case 10:
+      *Subtype = AMDATHLON_XP;
+      break; // "athlon-xp"
+    default:
+      break;
+    }
+  case 15:
+    *Type = AMDATHLON;
+    if (Features & (1 << FEATURE_SSE3)) {
+      *Subtype = AMDATHLON_K8SSE3;
+      break; // "k8-sse3"
+    }
+    switch (Model) {
+    case 1:
+      *Subtype = AMDATHLON_OPTERON;
+      break; // "opteron"
+    case 5:
+      *Subtype = AMDATHLON_FX;
+      break; // "athlon-fx"; also opteron
+    default:
+      *Subtype = AMDATHLON_64;
+      break; // "athlon64"
+    }
+  case 16:
+    *Type = AMDFAM10H; // "amdfam10"
+    switch (Model) {
+    case 2:
+      *Subtype = AMDFAM10H_BARCELONA;
+      break;
+    case 4:
+      *Subtype = AMDFAM10H_SHANGHAI;
+      break;
+    case 8:
+      *Subtype = AMDFAM10H_ISTANBUL;
+      break;
+    default:
+      break;
+    }
+  case 20:
+    *Type = AMDFAM14H;
+    *Subtype = AMD_BTVER1;
+    break; // "btver1";
+  case 21:
+    *Type = AMDFAM15H;
+    if (!(Features &
+          (1 << FEATURE_AVX))) { // If no AVX support, provide a sane fallback.
+      *Subtype = AMD_BTVER1;
+      break; // "btver1"
+    }
+    if (Model >= 0x50 && Model <= 0x6f) {
+      *Subtype = AMDFAM15H_BDVER4;
+      break; // "bdver4"; 50h-6Fh: Excavator
+    }
+    if (Model >= 0x30 && Model <= 0x3f) {
+      *Subtype = AMDFAM15H_BDVER3;
+      break; // "bdver3"; 30h-3Fh: Steamroller
+    }
+    if (Model >= 0x10 && Model <= 0x1f) {
+      *Subtype = AMDFAM15H_BDVER2;
+      break; // "bdver2"; 10h-1Fh: Piledriver
+    }
+    if (Model <= 0x0f) {
+      *Subtype = AMDFAM15H_BDVER1;
+      break; // "bdver1"; 00h-0Fh: Bulldozer
+    }
+    break;
+  case 22:
+    *Type = AMDFAM16H;
+    if (!(Features &
+          (1 << FEATURE_AVX))) { // If no AVX support provide a sane fallback.
+      *Subtype = AMD_BTVER1;
+      break; // "btver1";
+    }
+    *Subtype = AMD_BTVER2;
+    break; // "btver2"
+  default:
+    break; // "generic"
+  }
+}
+
+unsigned getAvailableFeatures(unsigned int ECX, unsigned int EDX,
+                              unsigned MaxLeaf) {
+  unsigned Features = 0;
+  unsigned int EAX, EBX;
+  Features |= (((EDX >> 23) & 1) << FEATURE_MMX);
+  Features |= (((EDX >> 25) & 1) << FEATURE_SSE);
+  Features |= (((EDX >> 26) & 1) << FEATURE_SSE2);
+  Features |= (((ECX >> 0) & 1) << FEATURE_SSE3);
+  Features |= (((ECX >> 9) & 1) << FEATURE_SSSE3);
+  Features |= (((ECX >> 19) & 1) << FEATURE_SSE4_1);
+  Features |= (((ECX >> 20) & 1) << FEATURE_SSE4_2);
+  Features |= (((ECX >> 22) & 1) << FEATURE_MOVBE);
 
-  union {
-    unsigned u[3];
-    char c[12];
-  } text;
-
-  unsigned MaxLeaf;
-  getX86CpuIDAndInfo(0, &MaxLeaf, text.u + 0, text.u + 2, text.u + 1);
-
-  bool HasMMX = (EDX >> 23) & 1;
-  bool HasSSE = (EDX >> 25) & 1;
-  bool HasSSE2 = (EDX >> 26) & 1;
-  bool HasSSE3 = (ECX >> 0) & 1;
-  bool HasSSSE3 = (ECX >> 9) & 1;
-  bool HasSSE41 = (ECX >> 19) & 1;
-  bool HasSSE42 = (ECX >> 20) & 1;
-  bool HasMOVBE = (ECX >> 22) & 1;
   // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
   // indicates that the AVX registers will be saved and restored on context
   // switch, then we have full AVX support.
@@ -235,291 +725,190 @@ StringRef sys::getHostCPUName() {
   bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
   bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20);
   bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1);
+  Features |= (HasAVX << FEATURE_AVX);
+  Features |= (HasAVX2 << FEATURE_AVX2);
+  Features |= (HasAVX512 << FEATURE_AVX512);
+  Features |= (HasAVX512Save << FEATURE_AVX512SAVE);
+  Features |= (HasADX << FEATURE_ADX);
 
   getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
-  bool Em64T = (EDX >> 29) & 0x1;
-  bool HasTBM = (ECX >> 21) & 0x1;
+  Features |= (((EDX >> 29) & 0x1) << FEATURE_EM64T);
+  return Features;
+}
 
-  if (memcmp(text.c, "GenuineIntel", 12) == 0) {
-    switch (Family) {
-    case 3:
-      return "i386";
-    case 4:
-      switch (Model) {
-      case 0: // Intel486 DX processors
-      case 1: // Intel486 DX processors
-      case 2: // Intel486 SX processors
-      case 3: // Intel487 processors, IntelDX2 OverDrive processors,
-              // IntelDX2 processors
-      case 4: // Intel486 SL processor
-      case 5: // IntelSX2 processors
-      case 7: // Write-Back Enhanced IntelDX2 processors
-      case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
-      default:
-        return "i486";
-      }
-    case 5:
-      switch (Model) {
-      case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
-              // Pentium processors (60, 66)
-      case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
-              // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
-              // 150, 166, 200)
-      case 3: // Pentium OverDrive processors for Intel486 processor-based
-              // systems
-        return "pentium";
+StringRef sys::getHostCPUName() {
+  unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+  unsigned MaxLeaf, Vendor;
 
-      case 4: // Pentium OverDrive processor with MMX technology for Pentium
-              // processor (75, 90, 100, 120, 133), Pentium processor with
-              // MMX technology (166, 200)
-        return "pentium-mmx";
+  if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX))
+    return "generic";
+  if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
+    return "generic";
 
-      default:
-        return "pentium";
-      }
-    case 6:
-      switch (Model) {
-      case 0x01: // Pentium Pro processor
-        return "pentiumpro";
-
-      case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
-                 // model 03
-      case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
-                 // model 05, and Intel Celeron processor, model 05
-      case 0x06: // Celeron processor, model 06
-        return "pentium2";
-
-      case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
-                 // processor, model 07
-      case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
-                 // model 08, and Celeron processor, model 08
-      case 0x0a: // Pentium III Xeon processor, model 0Ah
-      case 0x0b: // Pentium III processor, model 0Bh
-        return "pentium3";
-
-      case 0x09: // Intel Pentium M processor, Intel Celeron M processor model
-                 // 09.
-      case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
-                 // 0Dh. All processors are manufactured using the 90 nm
-                 // process.
-      case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
-                 // Integrated Processor with Intel QuickAssist Technology
-        return "pentium-m";
-
-      case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
-                 // 0Eh. All processors are manufactured using the 65 nm
-                 // process.
-        return "yonah";
-
-      case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
-                 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
-                 // mobile processor, Intel Core 2 Extreme processor, Intel
-                 // Pentium Dual-Core processor, Intel Xeon processor, model
-                 // 0Fh. All processors are manufactured using the 65 nm
-                 // process.
-      case 0x16: // Intel Celeron processor model 16h. All processors are
-                 // manufactured using the 65 nm process
-        return "core2";
+  unsigned Brand_id = EBX & 0xff;
+  unsigned Family = 0, Model = 0;
+  unsigned Features = 0;
+  detectX86FamilyModel(EAX, &Family, &Model);
+  Features = getAvailableFeatures(ECX, EDX, MaxLeaf);
 
-      case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
-                 // 17h. All processors are manufactured using the 45 nm
-                 // process.
-                 //
-                 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
-      case 0x1d: // Intel Xeon processor MP. All processors are manufactured
-                 // using
-                 // the 45 nm process.
-        return "penryn";
+  unsigned Type;
+  unsigned Subtype;
 
-      case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
-                 // processors are manufactured using the 45 nm process.
-      case 0x1e: // Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz.
-                 // As found in a Summer 2010 model iMac.
-      case 0x2e: // Nehalem EX
+  if (Vendor == SIG_INTEL) {
+    getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features, &Type,
+                                    &Subtype);
+    switch (Type) {
+    case INTEL_i386:
+      return "i386";
+    case INTEL_i486:
+      return "i486";
+    case INTEL_PENTIUM:
+      if (Subtype == INTEL_PENTIUM_MMX)
+        return "pentium-mmx";
+      return "pentium";
+    case INTEL_PENTIUM_PRO:
+      return "pentiumpro";
+    case INTEL_PENTIUM_II:
+      return "pentium2";
+    case INTEL_PENTIUM_III:
+      return "pentium3";
+    case INTEL_PENTIUM_IV:
+      return "pentium4";
+    case INTEL_PENTIUM_M:
+      return "pentium-m";
+    case INTEL_CORE_DUO:
+      return "yonah";
+    case INTEL_CORE2:
+      switch (Subtype) {
+      case INTEL_CORE2_65:
+        return "core2";
+      case INTEL_CORE2_45:
+        return "penryn";
+      default:
+        return "core2";
+      }
+    case INTEL_COREI7:
+      switch (Subtype) {
+      case INTEL_COREI7_NEHALEM:
         return "nehalem";
-      case 0x25: // Intel Core i7, laptop version.
-      case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
-                 // processors are manufactured using the 32 nm process.
-      case 0x2f: // Westmere EX
+      case INTEL_COREI7_WESTMERE:
         return "westmere";
-
-      case 0x2a: // Intel Core i7 processor. All processors are manufactured
-                 // using the 32 nm process.
-      case 0x2d:
+      case INTEL_COREI7_SANDYBRIDGE:
         return "sandybridge";
-
-      case 0x3a:
-      case 0x3e: // Ivy Bridge EP
+      case INTEL_COREI7_IVYBRIDGE:
         return "ivybridge";
-
-      // Haswell:
-      case 0x3c:
-      case 0x3f:
-      case 0x45:
-      case 0x46:
+      case INTEL_COREI7_HASWELL:
         return "haswell";
-
-      // Broadwell:
-      case 0x3d:
-      case 0x47:
-      case 0x4f:
-      case 0x56:
+      case INTEL_COREI7_BROADWELL:
         return "broadwell";
-
-      // Skylake:
-      case 0x4e:
-        return "skylake-avx512";
-      case 0x5e:
+      case INTEL_COREI7_SKYLAKE:
         return "skylake";
-
-      case 0x1c: // Most 45 nm Intel Atom processors
-      case 0x26: // 45 nm Atom Lincroft
-      case 0x27: // 32 nm Atom Medfield
-      case 0x35: // 32 nm Atom Midview
-      case 0x36: // 32 nm Atom Midview
+      case INTEL_COREI7_SKYLAKE_AVX512:
+        return "skylake-avx512";
+      default:
+        return "corei7";
+      }
+    case INTEL_ATOM:
+      switch (Subtype) {
+      case INTEL_ATOM_BONNELL:
         return "bonnell";
-
-      // Atom Silvermont codes from the Intel software optimization guide.
-      case 0x37:
-      case 0x4a:
-      case 0x4d:
-      case 0x5a:
-      case 0x5d:
-      case 0x4c: // really airmont
+      case INTEL_ATOM_SILVERMONT:
         return "silvermont";
-
-      case 0x57:
-        return "knl";
-
-      default: // Unknown family 6 CPU, try to guess.
-        if (HasAVX512)
-          return "knl";
-        if (HasADX)
-          return "broadwell";
-        if (HasAVX2)
-          return "haswell";
-        if (HasAVX)
-          return "sandybridge";
-        if (HasSSE42)
-          return HasMOVBE ? "silvermont" : "nehalem";
-        if (HasSSE41)
-          return "penryn";
-        if (HasSSSE3)
-          return HasMOVBE ? "bonnell" : "core2";
-        if (Em64T)
-          return "x86-64";
-        if (HasSSE2)
-          return "pentium-m";
-        if (HasSSE)
-          return "pentium3";
-        if (HasMMX)
-          return "pentium2";
-        return "pentiumpro";
-      }
-    case 15: {
-      switch (Model) {
-      case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
-              // model 00h and manufactured using the 0.18 micron process.
-      case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
-              // processor MP, and Intel Celeron processor. All processors are
-              // model 01h and manufactured using the 0.18 micron process.
-      case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
-              // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
-              // processor, and Mobile Intel Celeron processor. All processors
-              // are model 02h and manufactured using the 0.13 micron process.
-        return (Em64T) ? "x86-64" : "pentium4";
-
-      case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
-              // processor. All processors are model 03h and manufactured using
-              // the 90 nm process.
-      case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
-              // Pentium D processor, Intel Xeon processor, Intel Xeon
-              // processor MP, Intel Celeron D processor. All processors are
-              // model 04h and manufactured using the 90 nm process.
-      case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
-              // Extreme Edition, Intel Xeon processor, Intel Xeon processor
-              // MP, Intel Celeron D processor. All processors are model 06h
-              // and manufactured using the 65 nm process.
-        return (Em64T) ? "nocona" : "prescott";
-
       default:
-        return (Em64T) ? "x86-64" : "pentium4";
+        return "atom";
       }
-    }
-
+    case INTEL_XEONPHI:
+      return "knl"; /*update for more variants added*/
+    case INTEL_X86_64:
+      return "x86-64";
+    case INTEL_NOCONA:
+      return "nocona";
+    case INTEL_PRESCOTT:
+      return "prescott";
     default:
       return "generic";
     }
-  } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
-    // FIXME: this poorly matches the generated SubtargetFeatureKV table.  There
-    // appears to be no way to generate the wide variety of AMD-specific targets
-    // from the information returned from CPUID.
-    switch (Family) {
-    case 4:
+  } else if (Vendor == SIG_AMD) {
+    getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
+    switch (Type) {
+    case AMD_i486:
       return "i486";
-    case 5:
-      switch (Model) {
-      case 6:
-      case 7:
+    case AMDPENTIUM:
+      switch (Subtype) {
+      case AMDPENTIUM_K6:
         return "k6";
-      case 8:
+      case AMDPENTIUM_K62:
         return "k6-2";
-      case 9:
-      case 13:
+      case AMDPENTIUM_K63:
         return "k6-3";
-      case 10:
+      case AMDPENTIUM_GEODE:
         return "geode";
       default:
         return "pentium";
       }
-    case 6:
-      switch (Model) {
-      case 4:
+    case AMDATHLON:
+      switch (Subtype) {
+      case AMDATHLON_TBIRD:
         return "athlon-tbird";
-      case 6:
-      case 7:
-      case 8:
+      case AMDATHLON_MP:
         return "athlon-mp";
-      case 10:
+      case AMDATHLON_XP:
         return "athlon-xp";
+      case AMDATHLON_K8SSE3:
+        return "k8-sse3";
+      case AMDATHLON_OPTERON:
+        return "opteron";
+      case AMDATHLON_FX:
+        return "athlon-fx";
+      case AMDATHLON_64:
+        return "athlon64";
       default:
         return "athlon";
       }
-    case 15:
-      if (HasSSE3)
-        return "k8-sse3";
-      switch (Model) {
-      case 1:
-        return "opteron";
-      case 5:
-        return "athlon-fx"; // also opteron
+    case AMDFAM10H:
+      switch (Subtype) {
+      case AMDFAM10H_BARCELONA:
+        return "amdfam10-barcelona";
+      case AMDFAM10H_SHANGHAI:
+        return "amdfam10-shanghai";
+      case AMDFAM10H_ISTANBUL:
+        return "amdfam10-istanbul";
       default:
-        return "athlon64";
+        return "amdfam10";
       }
-    case 16:
-      return "amdfam10";
-    case 20:
+    case AMDFAM14H:
       return "btver1";
-    case 21:
-      if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
+    case AMDFAM15H:
+      switch (Subtype) {
+      case AMDFAM15H_BDVER1:
+        return "bdver1";
+      case AMDFAM15H_BDVER2:
+        return "bdver2";
+      case AMDFAM15H_BDVER3:
+        return "bdver3";
+      case AMDFAM15H_BDVER4:
+        return "bdver4";
+      case AMD_BTVER1:
         return "btver1";
-      if (Model >= 0x50)
-        return "bdver4"; // 50h-6Fh: Excavator
-      if (Model >= 0x30)
-        return "bdver3"; // 30h-3Fh: Steamroller
-      if (Model >= 0x10 || HasTBM)
-        return "bdver2"; // 10h-1Fh: Piledriver
-      return "bdver1";   // 00h-0Fh: Bulldozer
-    case 22:
-      if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
+      default:
+        return "amdfam15";
+      }
+    case AMDFAM16H:
+      switch (Subtype) {
+      case AMD_BTVER1:
         return "btver1";
-      return "btver2";
+      case AMD_BTVER2:
+        return "btver2";
+      default:
+        return "amdfam16";
+      }
     default:
       return "generic";
     }
   }
   return "generic";
 }
+
 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
 StringRef sys::getHostCPUName() {
   host_basic_info_data_t hostInfo;




More information about the llvm-commits mailing list