diff options
Diffstat (limited to 'lib/Support/Host.cpp')
| -rw-r--r-- | lib/Support/Host.cpp | 405 | 
1 files changed, 207 insertions, 198 deletions
diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index 232efe648b03..9f22f89b3c9e 100644 --- a/lib/Support/Host.cpp +++ b/lib/Support/Host.cpp @@ -281,11 +281,17 @@ enum ProcessorVendors {  };  enum ProcessorTypes { -  INTEL_ATOM = 1, +  INTEL_BONNELL = 1,    INTEL_CORE2,    INTEL_COREI7,    AMDFAM10H,    AMDFAM15H, +  INTEL_SILVERMONT, +  INTEL_KNL, +  AMD_BTVER1, +  AMD_BTVER2, +  AMDFAM17H, +  // Entries below this are not in libgcc/compiler-rt.    INTEL_i386,    INTEL_i486,    INTEL_PENTIUM, @@ -295,16 +301,13 @@ enum ProcessorTypes {    INTEL_PENTIUM_IV,    INTEL_PENTIUM_M,    INTEL_CORE_DUO, -  INTEL_XEONPHI,    INTEL_X86_64,    INTEL_NOCONA,    INTEL_PRESCOTT,    AMD_i486,    AMDPENTIUM,    AMDATHLON, -  AMDFAM14H, -  AMDFAM16H, -  AMDFAM17H, +  INTEL_GOLDMONT,    CPU_TYPE_MAX  }; @@ -317,34 +320,26 @@ enum ProcessorSubtypes {    AMDFAM10H_ISTANBUL,    AMDFAM15H_BDVER1,    AMDFAM15H_BDVER2, -  INTEL_PENTIUM_MMX, -  INTEL_CORE2_65, -  INTEL_CORE2_45, +  AMDFAM15H_BDVER3, +  AMDFAM15H_BDVER4, +  AMDFAM17H_ZNVER1,    INTEL_COREI7_IVYBRIDGE,    INTEL_COREI7_HASWELL,    INTEL_COREI7_BROADWELL,    INTEL_COREI7_SKYLAKE,    INTEL_COREI7_SKYLAKE_AVX512, -  INTEL_ATOM_BONNELL, -  INTEL_ATOM_SILVERMONT, -  INTEL_ATOM_GOLDMONT, -  INTEL_KNIGHTS_LANDING, +  // Entries below this are not in libgcc/compiler-rt. +  INTEL_PENTIUM_MMX, +  INTEL_CORE2_65, +  INTEL_CORE2_45,    AMDPENTIUM_K6,    AMDPENTIUM_K62,    AMDPENTIUM_K63,    AMDPENTIUM_GEODE, -  AMDATHLON_TBIRD, -  AMDATHLON_MP, +  AMDATHLON_CLASSIC,    AMDATHLON_XP, +  AMDATHLON_K8,    AMDATHLON_K8SSE3, -  AMDATHLON_OPTERON, -  AMDATHLON_FX, -  AMDATHLON_64, -  AMD_BTVER1, -  AMD_BTVER2, -  AMDFAM15H_BDVER3, -  AMDFAM15H_BDVER4, -  AMDFAM17H_ZNVER1,    CPU_SUBTYPE_MAX  }; @@ -360,9 +355,28 @@ enum ProcessorFeatures {    FEATURE_SSE4_2,    FEATURE_AVX,    FEATURE_AVX2, -  FEATURE_AVX512, -  FEATURE_AVX512SAVE, -  FEATURE_MOVBE, +  FEATURE_SSE4_A, +  FEATURE_FMA4, +  FEATURE_XOP, +  FEATURE_FMA, +  FEATURE_AVX512F, +  FEATURE_BMI, +  FEATURE_BMI2, +  FEATURE_AES, +  FEATURE_PCLMUL, +  FEATURE_AVX512VL, +  FEATURE_AVX512BW, +  FEATURE_AVX512DQ, +  FEATURE_AVX512CD, +  FEATURE_AVX512ER, +  FEATURE_AVX512PF, +  FEATURE_AVX512VBMI, +  FEATURE_AVX512IFMA, +  FEATURE_AVX5124VNNIW, +  FEATURE_AVX5124FMAPS, +  FEATURE_AVX512VPOPCNTDQ, +  // Only one bit free left in the first 32 features. +  FEATURE_MOVBE = 32,    FEATURE_ADX,    FEATURE_EM64T  }; @@ -406,7 +420,6 @@ static bool isCpuIdSupported() {  /// the specified arguments.  If we can't run cpuid on the host, return true.  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. Preserve it manually. @@ -416,14 +429,16 @@ static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,            "xchgq\t%%rbx, %%rsi\n\t"            : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)            : "a"(value)); +  return false;  #elif defined(__i386__)    __asm__("movl\t%%ebx, %%esi\n\t"            "cpuid\n\t"            "xchgl\t%%ebx, %%esi\n\t"            : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)            : "a"(value)); +  return false;  #else -  assert(0 && "This method is defined only for x86."); +  return true;  #endif  #elif defined(_MSC_VER)    // The MSVC intrinsic is portable across x86 and x64. @@ -433,7 +448,6 @@ static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,    *rEBX = registers[1];    *rECX = registers[2];    *rEDX = registers[3]; -#endif    return false;  #else    return true; @@ -446,16 +460,16 @@ static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,  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. Preseve it manually. +  // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.    // FIXME: should we save this for Clang?    __asm__("movq\t%%rbx, %%rsi\n\t"            "cpuid\n\t"            "xchgq\t%%rbx, %%rsi\n\t"            : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)            : "a"(value), "c"(subleaf)); +  return false;  #elif defined(_MSC_VER)    int registers[4];    __cpuidex(registers, value, subleaf); @@ -463,6 +477,9 @@ static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,    *rEBX = registers[1];    *rECX = registers[2];    *rEDX = registers[3]; +  return false; +#else +  return true;  #endif  #elif defined(__i386__) || defined(_M_IX86)  #if defined(__GNUC__) || defined(__clang__) @@ -471,6 +488,7 @@ static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,            "xchgl\t%%ebx, %%esi\n\t"            : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)            : "a"(value), "c"(subleaf)); +  return false;  #elif defined(_MSC_VER)    __asm {        mov   eax,value @@ -485,16 +503,16 @@ static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,        mov   esi,rEDX        mov   dword ptr [esi],edx    } -#endif +  return false;  #else -  assert(0 && "This method is defined only for x86."); +  return true;  #endif -  return false;  #else    return true;  #endif  } +// Read control register 0 (XCR0). Used to detect features such as AVX.  static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {  #if defined(__GNUC__) || defined(__clang__)    // Check xgetbv; this uses a .byte sequence instead of the instruction @@ -526,9 +544,10 @@ static void detectX86FamilyModel(unsigned EAX, unsigned *Family,  }  static void -getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model, -                                unsigned int Brand_id, unsigned int Features, -                                unsigned *Type, unsigned *Subtype) { +getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, +                                unsigned Brand_id, unsigned Features, +                                unsigned Features2, unsigned *Type, +                                unsigned *Subtype) {    if (Brand_id != 0)      return;    switch (Family) { @@ -681,12 +700,7 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,      // Skylake Xeon:      case 0x55:        *Type = INTEL_COREI7; -      // Check that we really have AVX512 -      if (Features & (1 << FEATURE_AVX512)) { -        *Subtype = INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512" -      } else { -        *Subtype = INTEL_COREI7_SKYLAKE; // "skylake" -      } +      *Subtype = INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512"        break;      case 0x1c: // Most 45 nm Intel Atom processors @@ -694,8 +708,7 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,      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; +      *Type = INTEL_BONNELL;        break; // "bonnell"      // Atom Silvermont codes from the Intel software optimization guide. @@ -705,27 +718,23 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,      case 0x5a:      case 0x5d:      case 0x4c: // really airmont -      *Type = INTEL_ATOM; -      *Subtype = INTEL_ATOM_SILVERMONT; +      *Type = INTEL_SILVERMONT;        break; // "silvermont"      // Goldmont:      case 0x5c:      case 0x5f: -      *Type = INTEL_ATOM; -      *Subtype = INTEL_ATOM_GOLDMONT; +      *Type = INTEL_GOLDMONT;        break; // "goldmont"      case 0x57: -      *Type = INTEL_XEONPHI; // knl -      *Subtype = INTEL_KNIGHTS_LANDING; +      *Type = INTEL_KNL; // knl        break;      default: // Unknown family 6 CPU, try to guess. -      if (Features & (1 << FEATURE_AVX512)) { -        *Type = INTEL_XEONPHI; // knl -        *Subtype = INTEL_KNIGHTS_LANDING; +      if (Features & (1 << FEATURE_AVX512F)) { +        *Type = INTEL_KNL; // knl          break;        } -      if (Features & (1 << FEATURE_ADX)) { +      if (Features2 & (1 << (FEATURE_ADX - 32))) {          *Type = INTEL_COREI7;          *Subtype = INTEL_COREI7_BROADWELL;          break; @@ -741,9 +750,8 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,          break;        }        if (Features & (1 << FEATURE_SSE4_2)) { -        if (Features & (1 << FEATURE_MOVBE)) { -          *Type = INTEL_ATOM; -          *Subtype = INTEL_ATOM_SILVERMONT; +        if (Features2 & (1 << (FEATURE_MOVBE - 32))) { +          *Type = INTEL_SILVERMONT;          } else {            *Type = INTEL_COREI7;            *Subtype = INTEL_COREI7_NEHALEM; @@ -756,16 +764,15 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,          break;        }        if (Features & (1 << FEATURE_SSSE3)) { -        if (Features & (1 << FEATURE_MOVBE)) { -          *Type = INTEL_ATOM; -          *Subtype = INTEL_ATOM_BONNELL; // "bonnell" +        if (Features2 & (1 << (FEATURE_MOVBE - 32))) { +          *Type = INTEL_BONNELL; // "bonnell"          } else {            *Type = INTEL_CORE2; // "core2"            *Subtype = INTEL_CORE2_65;          }          break;        } -      if (Features & (1 << FEATURE_EM64T)) { +      if (Features2 & (1 << (FEATURE_EM64T - 32))) {          *Type = INTEL_X86_64;          break; // x86-64        } @@ -796,8 +803,8 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,              // 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); +      *Type = ((Features2 & (1 << (FEATURE_EM64T - 32))) ? INTEL_X86_64 +                                                         : INTEL_PENTIUM_IV);        break;      case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D @@ -811,13 +818,13 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,              // 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); +      *Type = ((Features2 & (1 << (FEATURE_EM64T - 32))) ? INTEL_NOCONA +                                                         : INTEL_PRESCOTT);        break;      default: -      *Type = -          ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV); +      *Type = ((Features2 & (1 << (FEATURE_EM64T - 32))) ? INTEL_X86_64 +                                                         : INTEL_PENTIUM_IV);        break;      }      break; @@ -827,10 +834,8 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,    }  } -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 @@ -860,38 +865,20 @@ static void getAMDProcessorTypeAndSubtype(unsigned int Family,      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: +    if (Features & (1 << FEATURE_SSE)) {        *Subtype = AMDATHLON_XP;        break; // "athlon-xp"      } -    break; +    *Subtype = AMDATHLON_CLASSIC; +    break; // "athlon"    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" -    } -    break; +    *Subtype = AMDATHLON_K8; +    break; // "k8"    case 16:      *Type = AMDFAM10H; // "amdfam10"      switch (Model) { @@ -907,19 +894,13 @@ static void getAMDProcessorTypeAndSubtype(unsigned int Family,      }      break;    case 20: -    *Type = AMDFAM14H; -    *Subtype = AMD_BTVER1; +    *Type = 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) { +    if (Model >= 0x60 && Model <= 0x7f) {        *Subtype = AMDFAM15H_BDVER4; -      break; // "bdver4"; 50h-6Fh: Excavator +      break; // "bdver4"; 60h-7Fh: Excavator      }      if (Model >= 0x30 && Model <= 0x3f) {        *Subtype = AMDFAM15H_BDVER3; @@ -935,39 +916,52 @@ static void getAMDProcessorTypeAndSubtype(unsigned int Family,      }      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; +    *Type = AMD_BTVER2;      break; // "btver2"    case 23:      *Type = AMDFAM17H; -    if (Features & (1 << FEATURE_ADX)) { -      *Subtype = AMDFAM17H_ZNVER1; -      break; // "znver1" -    } -    *Subtype =  AMD_BTVER1; +    *Subtype = AMDFAM17H_ZNVER1;      break;    default:      break; // "generic"    }  } -static unsigned getAvailableFeatures(unsigned int ECX, unsigned int EDX, -                                     unsigned MaxLeaf) { +static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, +                                 unsigned *FeaturesOut, +                                 unsigned *Features2Out) {    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); +  unsigned Features2 = 0; +  unsigned EAX, EBX; + +  if ((EDX >> 15) & 1) +    Features |= 1 << FEATURE_CMOV; +  if ((EDX >> 23) & 1) +    Features |= 1 << FEATURE_MMX; +  if ((EDX >> 25) & 1) +    Features |= 1 << FEATURE_SSE; +  if ((EDX >> 26) & 1) +    Features |= 1 << FEATURE_SSE2; + +  if ((ECX >> 0) & 1) +    Features |= 1 << FEATURE_SSE3; +  if ((ECX >> 1) & 1) +    Features |= 1 << FEATURE_PCLMUL; +  if ((ECX >> 9) & 1) +    Features |= 1 << FEATURE_SSSE3; +  if ((ECX >> 12) & 1) +    Features |= 1 << FEATURE_FMA; +  if ((ECX >> 19) & 1) +    Features |= 1 << FEATURE_SSE4_1; +  if ((ECX >> 20) & 1) +    Features |= 1 << FEATURE_SSE4_2; +  if ((ECX >> 23) & 1) +    Features |= 1 << FEATURE_POPCNT; +  if ((ECX >> 25) & 1) +    Features |= 1 << FEATURE_AES; + +  if ((ECX >> 22) & 1) +    Features2 |= 1 << (FEATURE_MOVBE - 32);    // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV    // indicates that the AVX registers will be saved and restored on context @@ -976,20 +970,65 @@ static unsigned getAvailableFeatures(unsigned int ECX, unsigned int EDX,    bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&                  ((EAX & 0x6) == 0x6);    bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0); + +  if (HasAVX) +    Features |= 1 << FEATURE_AVX; +    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); -  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); -  Features |= (((EDX >> 29) & 0x1) << FEATURE_EM64T); -  return Features; + +  if (HasLeaf7 && ((EBX >> 3) & 1)) +    Features |= 1 << FEATURE_BMI; +  if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX) +    Features |= 1 << FEATURE_AVX2; +  if (HasLeaf7 && ((EBX >> 9) & 1)) +    Features |= 1 << FEATURE_BMI2; +  if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512F; +  if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512DQ; +  if (HasLeaf7 && ((EBX >> 19) & 1)) +    Features2 |= 1 << (FEATURE_ADX - 32); +  if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512IFMA; +  if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512PF; +  if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512ER; +  if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512CD; +  if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512BW; +  if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512VL; + +  if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512VBMI; +  if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX512VPOPCNTDQ; + +  if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX5124VNNIW; +  if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save) +    Features |= 1 << FEATURE_AVX5124FMAPS; + +  unsigned MaxExtLevel; +  getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); + +  bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && +                     !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); +  if (HasExtLeaf1 && ((ECX >> 6) & 1)) +    Features |= 1 << FEATURE_SSE4_A; +  if (HasExtLeaf1 && ((ECX >> 11) & 1)) +    Features |= 1 << FEATURE_XOP; +  if (HasExtLeaf1 && ((ECX >> 16) & 1)) +    Features |= 1 << FEATURE_FMA4; + +  if (HasExtLeaf1 && ((EDX >> 29) & 1)) +    Features2 |= 1 << (FEATURE_EM64T - 32); + +  *FeaturesOut  = Features; +  *Features2Out = Features2;  }  StringRef sys::getHostCPUName() { @@ -1004,23 +1043,22 @@ StringRef sys::getHostCPUName() {    if(!isCpuIdSupported())      return "generic";  #endif -  if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX)) -    return "generic"; -  if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX)) +  if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1)      return "generic"; +  getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);    unsigned Brand_id = EBX & 0xff;    unsigned Family = 0, Model = 0; -  unsigned Features = 0; +  unsigned Features = 0, Features2 = 0;    detectX86FamilyModel(EAX, &Family, &Model); -  Features = getAvailableFeatures(ECX, EDX, MaxLeaf); +  getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2);    unsigned Type;    unsigned Subtype;    if (Vendor == SIG_INTEL) { -    getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features, &Type, -                                    &Subtype); +    getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features, +                                    Features2, &Type, &Subtype);      switch (Type) {      case INTEL_i386:        return "i386"; @@ -1049,7 +1087,7 @@ StringRef sys::getHostCPUName() {        case INTEL_CORE2_45:          return "penryn";        default: -        return "core2"; +        llvm_unreachable("Unexpected subtype!");        }      case INTEL_COREI7:        switch (Subtype) { @@ -1070,21 +1108,16 @@ StringRef sys::getHostCPUName() {        case INTEL_COREI7_SKYLAKE_AVX512:          return "skylake-avx512";        default: -        return "corei7"; +        llvm_unreachable("Unexpected subtype!");        } -    case INTEL_ATOM: -      switch (Subtype) { -      case INTEL_ATOM_BONNELL: -        return "bonnell"; -      case INTEL_ATOM_GOLDMONT: -        return "goldmont"; -      case INTEL_ATOM_SILVERMONT: -        return "silvermont"; -      default: -        return "atom"; -      } -    case INTEL_XEONPHI: -      return "knl"; /*update for more variants added*/ +    case INTEL_BONNELL: +      return "bonnell"; +    case INTEL_SILVERMONT: +      return "silvermont"; +    case INTEL_GOLDMONT: +      return "goldmont"; +    case INTEL_KNL: +      return "knl";      case INTEL_X86_64:        return "x86-64";      case INTEL_NOCONA: @@ -1092,7 +1125,7 @@ StringRef sys::getHostCPUName() {      case INTEL_PRESCOTT:        return "prescott";      default: -      return "generic"; +      break;      }    } else if (Vendor == SIG_AMD) {      getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype); @@ -1114,31 +1147,24 @@ StringRef sys::getHostCPUName() {        }      case AMDATHLON:        switch (Subtype) { -      case AMDATHLON_TBIRD: -        return "athlon-tbird"; -      case AMDATHLON_MP: -        return "athlon-mp"; +      case AMDATHLON_CLASSIC: +        return "athlon";        case AMDATHLON_XP:          return "athlon-xp"; +      case AMDATHLON_K8: +        return "k8";        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"; +        llvm_unreachable("Unexpected subtype!");        }      case AMDFAM10H: -      if(Subtype == AMDFAM10H_BARCELONA) -        return "barcelona";        return "amdfam10"; -    case AMDFAM14H: +    case AMD_BTVER1:        return "btver1";      case AMDFAM15H:        switch (Subtype) { +      default: // There are gaps in the subtype detection.        case AMDFAM15H_BDVER1:          return "bdver1";        case AMDFAM15H_BDVER2: @@ -1147,31 +1173,13 @@ StringRef sys::getHostCPUName() {          return "bdver3";        case AMDFAM15H_BDVER4:          return "bdver4"; -      case AMD_BTVER1: -        return "btver1"; -      default: -        return "amdfam15"; -      } -    case AMDFAM16H: -      switch (Subtype) { -      case AMD_BTVER1: -        return "btver1"; -      case AMD_BTVER2: -        return "btver2"; -      default: -        return "amdfam16";        } +    case AMD_BTVER2: +      return "btver2";      case AMDFAM17H: -      switch (Subtype) { -      case AMD_BTVER1: -        return "btver1"; -      case AMDFAM17H_ZNVER1: -        return "znver1"; -      default: -        return "amdfam17"; -      } +      return "znver1";      default: -      return "generic"; +      break;      }    }    return "generic"; @@ -1494,7 +1502,8 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }  #endif  std::string sys::getProcessTriple() { -  Triple PT(Triple::normalize(LLVM_HOST_TRIPLE)); +  std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE); +  Triple PT(Triple::normalize(TargetTripleString));    if (sizeof(void *) == 8 && PT.isArch32Bit())      PT = PT.get64BitArchVariant();  | 
