Skip to content

Commit

Permalink
[X86] Add additional CPUs and features to Host.cpp and X86TargetParse…
Browse files Browse the repository at this point in the history
…r.def to match compiler-rt and enable __builtin_cpu_supports/__builtin_cpu_is support in clang

Summary: This matches LLVM to D53461 for compiler-rt.

Reviewers: echristo, erichkeane

Reviewed By: echristo

Subscribers: dberris, llvm-commits

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

llvm-svn: 344831
  • Loading branch information
topperc committed Oct 20, 2018
1 parent 3fe6470 commit 0aca35d
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 69 deletions.
45 changes: 26 additions & 19 deletions llvm/include/llvm/Support/X86TargetParser.def
Expand Up @@ -34,17 +34,20 @@ X86_VENDOR(VENDOR_AMD, "amd")
#ifndef X86_CPU_TYPE
#define X86_CPU_TYPE(ARCHNAME, ENUM)
#endif
X86_CPU_TYPE_COMPAT_WITH_ALIAS("bonnell", INTEL_BONNELL, "bonnell", "atom")
X86_CPU_TYPE_COMPAT ("core2", INTEL_CORE2, "core2")
X86_CPU_TYPE_COMPAT ("nehalem", INTEL_COREI7, "corei7")
X86_CPU_TYPE_COMPAT_WITH_ALIAS("amdfam10", AMDFAM10H, "amdfam10h", "amdfam10")
X86_CPU_TYPE_COMPAT_WITH_ALIAS("bdver1", AMDFAM15H, "amdfam15h", "amdfam15")
X86_CPU_TYPE_COMPAT_WITH_ALIAS("silvermont", INTEL_SILVERMONT, "silvermont", "slm")
X86_CPU_TYPE_COMPAT ("knl", INTEL_KNL, "knl")
X86_CPU_TYPE_COMPAT ("btver1", AMD_BTVER1, "btver1")
X86_CPU_TYPE_COMPAT ("btver2", AMD_BTVER2, "btver2")
X86_CPU_TYPE_COMPAT ("znver1", AMDFAM17H, "amdfam17h")
X86_CPU_TYPE_COMPAT ("knm", INTEL_KNM, "knm")
X86_CPU_TYPE_COMPAT_WITH_ALIAS("bonnell", INTEL_BONNELL, "bonnell", "atom")
X86_CPU_TYPE_COMPAT ("core2", INTEL_CORE2, "core2")
X86_CPU_TYPE_COMPAT ("nehalem", INTEL_COREI7, "corei7")
X86_CPU_TYPE_COMPAT_WITH_ALIAS("amdfam10", AMDFAM10H, "amdfam10h", "amdfam10")
X86_CPU_TYPE_COMPAT_WITH_ALIAS("bdver1", AMDFAM15H, "amdfam15h", "amdfam15")
X86_CPU_TYPE_COMPAT_WITH_ALIAS("silvermont", INTEL_SILVERMONT, "silvermont", "slm")
X86_CPU_TYPE_COMPAT ("knl", INTEL_KNL, "knl")
X86_CPU_TYPE_COMPAT ("btver1", AMD_BTVER1, "btver1")
X86_CPU_TYPE_COMPAT ("btver2", AMD_BTVER2, "btver2")
X86_CPU_TYPE_COMPAT ("znver1", AMDFAM17H, "amdfam17h")
X86_CPU_TYPE_COMPAT ("knm", INTEL_KNM, "knm")
X86_CPU_TYPE_COMPAT ("goldmont", INTEL_GOLDMONT, "goldmont")
X86_CPU_TYPE_COMPAT ("goldmont-plus", INTEL_GOLDMONT_PLUS, "goldmont-plus")
X86_CPU_TYPE_COMPAT ("tremont", INTEL_TREMONT, "tremont")
// Entries below this are not in libgcc/compiler-rt.
X86_CPU_TYPE ("i386", INTEL_i386)
X86_CPU_TYPE ("i486", INTEL_i486)
Expand All @@ -64,9 +67,6 @@ X86_CPU_TYPE ("athlon", AMD_ATHLON)
X86_CPU_TYPE ("athlon-xp", AMD_ATHLON_XP)
X86_CPU_TYPE ("k8", AMD_K8)
X86_CPU_TYPE ("k8-sse3", AMD_K8SSE3)
X86_CPU_TYPE ("goldmont", INTEL_GOLDMONT)
X86_CPU_TYPE ("goldmont-plus", INTEL_GOLDMONT_PLUS)
X86_CPU_TYPE ("tremont", INTEL_TREMONT)
#undef X86_CPU_TYPE_COMPAT_WITH_ALIAS
#undef X86_CPU_TYPE_COMPAT
#undef X86_CPU_TYPE
Expand Down Expand Up @@ -97,6 +97,8 @@ X86_CPU_SUBTYPE_COMPAT("broadwell", INTEL_COREI7_BROADWELL, "broadwell
X86_CPU_SUBTYPE_COMPAT("skylake", INTEL_COREI7_SKYLAKE, "skylake")
X86_CPU_SUBTYPE_COMPAT("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512, "skylake-avx512")
X86_CPU_SUBTYPE_COMPAT("cannonlake", INTEL_COREI7_CANNONLAKE, "cannonlake")
X86_CPU_SUBTYPE_COMPAT("icelake-client", INTEL_COREI7_ICELAKE_CLIENT, "icelake-client")
X86_CPU_SUBTYPE_COMPAT("icelake-server", INTEL_COREI7_ICELAKE_SERVER, "icelake-server")
// Entries below this are not in libgcc/compiler-rt.
X86_CPU_SUBTYPE ("core2", INTEL_CORE2_65)
X86_CPU_SUBTYPE ("penryn", INTEL_CORE2_45)
Expand Down Expand Up @@ -147,11 +149,16 @@ X86_FEATURE_COMPAT(27, FEATURE_AVX512IFMA, "avx512ifma")
X86_FEATURE_COMPAT(28, FEATURE_AVX5124VNNIW, "avx5124vnniw")
X86_FEATURE_COMPAT(29, FEATURE_AVX5124FMAPS, "avx5124fmaps")
X86_FEATURE_COMPAT(30, FEATURE_AVX512VPOPCNTDQ, "avx512vpopcntdq")
X86_FEATURE_COMPAT(31, FEATURE_AVX512VBMI2, "avx512vbmi2")
X86_FEATURE_COMPAT(32, FEATURE_GFNI, "gfni")
X86_FEATURE_COMPAT(33, FEATURE_VPCLMULQDQ, "vpclmulqdq")
X86_FEATURE_COMPAT(34, FEATURE_AVX512VNNI, "avx512vnni")
X86_FEATURE_COMPAT(35, FEATURE_AVX512BITALG, "avx512bitalg")
// Features below here are not in libgcc/compiler-rt.
X86_FEATURE (32, FEATURE_MOVBE)
X86_FEATURE (33, FEATURE_ADX)
X86_FEATURE (34, FEATURE_EM64T)
X86_FEATURE (35, FEATURE_CLFLUSHOPT)
X86_FEATURE (36, FEATURE_SHA)
X86_FEATURE (64, FEATURE_MOVBE)
X86_FEATURE (65, FEATURE_ADX)
X86_FEATURE (66, FEATURE_EM64T)
X86_FEATURE (67, FEATURE_CLFLUSHOPT)
X86_FEATURE (68, FEATURE_SHA)
#undef X86_FEATURE_COMPAT
#undef X86_FEATURE
123 changes: 73 additions & 50 deletions llvm/lib/Support/Host.cpp
Expand Up @@ -511,8 +511,8 @@ static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
static void
getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
unsigned Brand_id, unsigned Features,
unsigned Features2, unsigned *Type,
unsigned *Subtype) {
unsigned Features2, unsigned Features3,
unsigned *Type, unsigned *Subtype) {
if (Brand_id != 0)
return;
switch (Family) {
Expand Down Expand Up @@ -696,16 +696,16 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
break;
}

if (Features2 & (1 << (X86::FEATURE_CLFLUSHOPT - 32))) {
if (Features2 & (1 << (X86::FEATURE_SHA - 32))) {
if (Features3 & (1 << (X86::FEATURE_CLFLUSHOPT - 64))) {
if (Features3 & (1 << (X86::FEATURE_SHA - 64))) {
*Type = X86::INTEL_GOLDMONT;
} else {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_SKYLAKE;
}
break;
}
if (Features2 & (1 << (X86::FEATURE_ADX - 32))) {
if (Features3 & (1 << (X86::FEATURE_ADX - 64))) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_BROADWELL;
break;
Expand All @@ -721,7 +721,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
break;
}
if (Features & (1 << X86::FEATURE_SSE4_2)) {
if (Features2 & (1 << (X86::FEATURE_MOVBE - 32))) {
if (Features3 & (1 << (X86::FEATURE_MOVBE - 64))) {
*Type = X86::INTEL_SILVERMONT;
} else {
*Type = X86::INTEL_COREI7;
Expand All @@ -735,15 +735,15 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
break;
}
if (Features & (1 << X86::FEATURE_SSSE3)) {
if (Features2 & (1 << (X86::FEATURE_MOVBE - 32))) {
if (Features3 & (1 << (X86::FEATURE_MOVBE - 64))) {
*Type = X86::INTEL_BONNELL; // "bonnell"
} else {
*Type = X86::INTEL_CORE2; // "core2"
*Subtype = X86::INTEL_CORE2_65;
}
break;
}
if (Features2 & (1 << (X86::FEATURE_EM64T - 32))) {
if (Features3 & (1 << (X86::FEATURE_EM64T - 64))) {
*Type = X86::INTEL_CORE2; // "core2"
*Subtype = X86::INTEL_CORE2_65;
break;
Expand All @@ -769,7 +769,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}
break;
case 15: {
if (Features2 & (1 << (X86::FEATURE_EM64T - 32))) {
if (Features3 & (1 << (X86::FEATURE_EM64T - 64))) {
*Type = X86::INTEL_NOCONA;
break;
}
Expand Down Expand Up @@ -877,40 +877,51 @@ static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}

static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
unsigned *FeaturesOut,
unsigned *Features2Out) {
unsigned *FeaturesOut, unsigned *Features2Out,
unsigned *Features3Out) {
unsigned Features = 0;
unsigned Features2 = 0;
unsigned Features3 = 0;
unsigned EAX, EBX;

#define setFeature(F) \
do { \
if (F < 32) \
Features |= 1 << F; \
else if (F < 64) \
Features2 |= 1 << (F - 32); \
else if (F < 96) \
Features3 |= 1 << (F - 64); \
} while (0)

if ((EDX >> 15) & 1)
Features |= 1 << X86::FEATURE_CMOV;
setFeature(X86::FEATURE_CMOV);
if ((EDX >> 23) & 1)
Features |= 1 << X86::FEATURE_MMX;
setFeature(X86::FEATURE_MMX);
if ((EDX >> 25) & 1)
Features |= 1 << X86::FEATURE_SSE;
setFeature(X86::FEATURE_SSE);
if ((EDX >> 26) & 1)
Features |= 1 << X86::FEATURE_SSE2;
setFeature(X86::FEATURE_SSE2);

if ((ECX >> 0) & 1)
Features |= 1 << X86::FEATURE_SSE3;
setFeature(X86::FEATURE_SSE3);
if ((ECX >> 1) & 1)
Features |= 1 << X86::FEATURE_PCLMUL;
setFeature(X86::FEATURE_PCLMUL);
if ((ECX >> 9) & 1)
Features |= 1 << X86::FEATURE_SSSE3;
setFeature(X86::FEATURE_SSSE3);
if ((ECX >> 12) & 1)
Features |= 1 << X86::FEATURE_FMA;
setFeature(X86::FEATURE_FMA);
if ((ECX >> 19) & 1)
Features |= 1 << X86::FEATURE_SSE4_1;
setFeature(X86::FEATURE_SSE4_1);
if ((ECX >> 20) & 1)
Features |= 1 << X86::FEATURE_SSE4_2;
setFeature(X86::FEATURE_SSE4_2);
if ((ECX >> 23) & 1)
Features |= 1 << X86::FEATURE_POPCNT;
setFeature(X86::FEATURE_POPCNT);
if ((ECX >> 25) & 1)
Features |= 1 << X86::FEATURE_AES;
setFeature(X86::FEATURE_AES);

if ((ECX >> 22) & 1)
Features2 |= 1 << (X86::FEATURE_MOVBE - 32);
setFeature(X86::FEATURE_MOVBE);

// If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
// indicates that the AVX registers will be saved and restored on context
Expand All @@ -921,67 +932,79 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);

if (HasAVX)
Features |= 1 << X86::FEATURE_AVX;
setFeature(X86::FEATURE_AVX);

bool HasLeaf7 =
MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);

if (HasLeaf7 && ((EBX >> 3) & 1))
Features |= 1 << X86::FEATURE_BMI;
setFeature(X86::FEATURE_BMI);
if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
Features |= 1 << X86::FEATURE_AVX2;
setFeature(X86::FEATURE_AVX2);
if (HasLeaf7 && ((EBX >> 9) & 1))
Features |= 1 << X86::FEATURE_BMI2;
setFeature(X86::FEATURE_BMI2);
if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512F;
setFeature(X86::FEATURE_AVX512F);
if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512DQ;
setFeature(X86::FEATURE_AVX512DQ);
if (HasLeaf7 && ((EBX >> 19) & 1))
Features2 |= 1 << (X86::FEATURE_ADX - 32);
setFeature(X86::FEATURE_ADX);
if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512IFMA;
setFeature(X86::FEATURE_AVX512IFMA);
if (HasLeaf7 && ((EBX >> 23) & 1))
Features2 |= 1 << (X86::FEATURE_CLFLUSHOPT - 32);
setFeature(X86::FEATURE_CLFLUSHOPT);
if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512PF;
setFeature(X86::FEATURE_AVX512PF);
if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512ER;
setFeature(X86::FEATURE_AVX512ER);
if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512CD;
setFeature(X86::FEATURE_AVX512CD);
if (HasLeaf7 && ((EBX >> 29) & 1))
Features2 |= 1 << (X86::FEATURE_SHA - 32);
setFeature(X86::FEATURE_SHA);
if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512BW;
setFeature(X86::FEATURE_AVX512BW);
if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512VL;
setFeature(X86::FEATURE_AVX512VL);

if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512VBMI;
setFeature(X86::FEATURE_AVX512VBMI);
if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
setFeature(X86::FEATURE_AVX512VBMI2);
if (HasLeaf7 && ((ECX >> 8) & 1))
setFeature(X86::FEATURE_GFNI);
if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
setFeature(X86::FEATURE_VPCLMULQDQ);
if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
setFeature(X86::FEATURE_AVX512VNNI);
if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
setFeature(X86::FEATURE_AVX512BITALG);
if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX512VPOPCNTDQ;
setFeature(X86::FEATURE_AVX512VPOPCNTDQ);

if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX5124VNNIW;
setFeature(X86::FEATURE_AVX5124VNNIW);
if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
Features |= 1 << X86::FEATURE_AVX5124FMAPS;
setFeature(X86::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 << X86::FEATURE_SSE4_A;
setFeature(X86::FEATURE_SSE4_A);
if (HasExtLeaf1 && ((ECX >> 11) & 1))
Features |= 1 << X86::FEATURE_XOP;
setFeature(X86::FEATURE_XOP);
if (HasExtLeaf1 && ((ECX >> 16) & 1))
Features |= 1 << X86::FEATURE_FMA4;
setFeature(X86::FEATURE_FMA4);

if (HasExtLeaf1 && ((EDX >> 29) & 1))
Features2 |= 1 << (X86::FEATURE_EM64T - 32);
setFeature(X86::FEATURE_EM64T);

*FeaturesOut = Features;
*Features2Out = Features2;
*Features3Out = Features3;
#undef setFeature
}

StringRef sys::getHostCPUName() {
Expand All @@ -1002,16 +1025,16 @@ StringRef sys::getHostCPUName() {

unsigned Brand_id = EBX & 0xff;
unsigned Family = 0, Model = 0;
unsigned Features = 0, Features2 = 0;
unsigned Features = 0, Features2 = 0, Features3 = 0;
detectX86FamilyModel(EAX, &Family, &Model);
getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2);
getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2, &Features3);

unsigned Type = 0;
unsigned Subtype = 0;

if (Vendor == SIG_INTEL) {
getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features,
Features2, &Type, &Subtype);
Features2, Features3, &Type, &Subtype);
} else if (Vendor == SIG_AMD) {
getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
}
Expand Down

0 comments on commit 0aca35d

Please sign in to comment.