[X86] Add a helper lambda to getIntelProcessorTypeAndSubtype to select feature bits from the correct 32-bit feature variable.

We have three 32 bit variables containing feature bits. But our
enum is a flat 96 bit space. So we need to pick which of the
variables to use based on the bit value. We used to do this
manually by mentioning the correct variable and subtracting an
offset from the enum. But this is error prone.
This commit is contained in:
Craig Topper 2020-06-11 21:14:45 -07:00
parent 999307323a
commit 0ce9bf6eed
1 changed files with 46 additions and 30 deletions

View File

@ -585,6 +585,16 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
unsigned Brand_id, unsigned Features,
unsigned Features2, unsigned Features3,
unsigned *Type, unsigned *Subtype) {
auto testFeature = [&](unsigned F) {
if (F < 32)
return (Features & (1U << (F & 0x1f))) != 0;
if (F < 64)
return (Features2 & (1U << ((F - 32) & 0x1f))) != 0;
if (F < 96)
return (Features3 & (1U << ((F - 64) & 0x1f))) != 0;
llvm_unreachable("Unexpected FeatureBit");
};
if (Brand_id != 0)
return;
switch (Family) {
@ -595,7 +605,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
*Type = X86::INTEL_i486;
break;
case 5:
if (Features & (1 << X86::FEATURE_MMX)) {
if (testFeature(X86::FEATURE_MMX)) {
*Type = X86::INTEL_PENTIUM_MMX;
break;
}
@ -711,9 +721,9 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
// Skylake Xeon:
case 0x55:
*Type = X86::INTEL_COREI7;
if (Features2 & (1 << (X86::FEATURE_AVX512BF16 - 32)))
if (testFeature(X86::FEATURE_AVX512BF16))
*Subtype = X86::INTEL_COREI7_COOPERLAKE; // "cooperlake"
else if (Features2 & (1 << (X86::FEATURE_AVX512VNNI - 32)))
else if (testFeature(X86::FEATURE_AVX512VNNI))
*Subtype = X86::INTEL_COREI7_CASCADELAKE; // "cascadelake"
else
*Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512"
@ -777,50 +787,50 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
break;
default: // Unknown family 6 CPU, try to guess.
// TODO detect tigerlake host
if (Features2 & (1 << (X86::FEATURE_AVX512VP2INTERSECT - 32))) {
// TODO detect tigerlake host from model
if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_TIGERLAKE;
break;
}
if (Features & (1 << X86::FEATURE_AVX512VBMI2)) {
if (testFeature(X86::FEATURE_AVX512VBMI2)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT;
break;
}
if (Features & (1 << X86::FEATURE_AVX512VBMI)) {
if (testFeature(X86::FEATURE_AVX512VBMI)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_CANNONLAKE;
break;
}
if (Features2 & (1 << (X86::FEATURE_AVX512BF16 - 32))) {
if (testFeature(X86::FEATURE_AVX512BF16)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_COOPERLAKE;
break;
}
if (Features2 & (1 << (X86::FEATURE_AVX512VNNI - 32))) {
if (testFeature(X86::FEATURE_AVX512VNNI)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_CASCADELAKE;
break;
}
if (Features & (1 << X86::FEATURE_AVX512VL)) {
if (testFeature(X86::FEATURE_AVX512VL)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
break;
}
if (Features & (1 << X86::FEATURE_AVX512ER)) {
if (testFeature(X86::FEATURE_AVX512ER)) {
*Type = X86::INTEL_KNL; // knl
break;
}
if (Features3 & (1 << (X86::FEATURE_CLFLUSHOPT - 64))) {
if (Features3 & (1 << (X86::FEATURE_SHA - 64))) {
if (testFeature(X86::FEATURE_CLFLUSHOPT)) {
if (testFeature(X86::FEATURE_SHA)) {
*Type = X86::INTEL_GOLDMONT;
} else {
*Type = X86::INTEL_COREI7;
@ -828,23 +838,23 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}
break;
}
if (Features3 & (1 << (X86::FEATURE_ADX - 64))) {
if (testFeature(X86::FEATURE_ADX)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_BROADWELL;
break;
}
if (Features & (1 << X86::FEATURE_AVX2)) {
if (testFeature(X86::FEATURE_AVX2)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_HASWELL;
break;
}
if (Features & (1 << X86::FEATURE_AVX)) {
if (testFeature(X86::FEATURE_AVX)) {
*Type = X86::INTEL_COREI7;
*Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
break;
}
if (Features & (1 << X86::FEATURE_SSE4_2)) {
if (Features3 & (1 << (X86::FEATURE_MOVBE - 64))) {
if (testFeature(X86::FEATURE_SSE4_2)) {
if (testFeature(X86::FEATURE_MOVBE)) {
*Type = X86::INTEL_SILVERMONT;
} else {
*Type = X86::INTEL_COREI7;
@ -852,13 +862,13 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}
break;
}
if (Features & (1 << X86::FEATURE_SSE4_1)) {
if (testFeature(X86::FEATURE_SSE4_1)) {
*Type = X86::INTEL_CORE2; // "penryn"
*Subtype = X86::INTEL_CORE2_45;
break;
}
if (Features & (1 << X86::FEATURE_SSSE3)) {
if (Features3 & (1 << (X86::FEATURE_MOVBE - 64))) {
if (testFeature(X86::FEATURE_SSSE3)) {
if (testFeature(X86::FEATURE_MOVBE)) {
*Type = X86::INTEL_BONNELL; // "bonnell"
} else {
*Type = X86::INTEL_CORE2; // "core2"
@ -866,24 +876,24 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}
break;
}
if (Features3 & (1 << (X86::FEATURE_EM64T - 64))) {
if (testFeature(X86::FEATURE_EM64T)) {
*Type = X86::INTEL_CORE2; // "core2"
*Subtype = X86::INTEL_CORE2_65;
break;
}
if (Features & (1 << X86::FEATURE_SSE3)) {
if (testFeature(X86::FEATURE_SSE3)) {
*Type = X86::INTEL_CORE_DUO;
break;
}
if (Features & (1 << X86::FEATURE_SSE2)) {
if (testFeature(X86::FEATURE_SSE2)) {
*Type = X86::INTEL_PENTIUM_M;
break;
}
if (Features & (1 << X86::FEATURE_SSE)) {
if (testFeature(X86::FEATURE_SSE)) {
*Type = X86::INTEL_PENTIUM_III;
break;
}
if (Features & (1 << X86::FEATURE_MMX)) {
if (testFeature(X86::FEATURE_MMX)) {
*Type = X86::INTEL_PENTIUM_II;
break;
}
@ -892,11 +902,11 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}
break;
case 15: {
if (Features3 & (1 << (X86::FEATURE_EM64T - 64))) {
if (testFeature(X86::FEATURE_EM64T)) {
*Type = X86::INTEL_NOCONA;
break;
}
if (Features & (1 << X86::FEATURE_SSE3)) {
if (testFeature(X86::FEATURE_SSE3)) {
*Type = X86::INTEL_PRESCOTT;
break;
}
@ -911,6 +921,12 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
unsigned Features, unsigned *Type,
unsigned *Subtype) {
auto testFeature = [&](unsigned F) {
if (F < 32)
return (Features & (1U << (F & 0x1f))) != 0;
llvm_unreachable("Unexpected FeatureBit");
};
// 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.
@ -938,14 +954,14 @@ static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
}
break;
case 6:
if (Features & (1 << X86::FEATURE_SSE)) {
if (testFeature(X86::FEATURE_SSE)) {
*Type = X86::AMD_ATHLON_XP;
break; // "athlon-xp"
}
*Type = X86::AMD_ATHLON;
break; // "athlon"
case 15:
if (Features & (1 << X86::FEATURE_SSE3)) {
if (testFeature(X86::FEATURE_SSE3)) {
*Type = X86::AMD_K8SSE3;
break; // "k8-sse3"
}