Index: compiler-rt/trunk/lib/builtins/cpu_model.c =================================================================== --- compiler-rt/trunk/lib/builtins/cpu_model.c +++ compiler-rt/trunk/lib/builtins/cpu_model.c @@ -55,6 +55,9 @@ AMD_BTVER2, AMDFAM17H, INTEL_KNM, + INTEL_GOLDMONT, + INTEL_GOLDMONT_PLUS, + INTEL_TREMONT, CPU_TYPE_MAX }; @@ -76,6 +79,8 @@ 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 @@ 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 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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. */