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) {
*Type = X86::INTEL_i486;
break;
case 5:
- if (Features & (1 << X86::FEATURE_MMX)) {
+ if (testFeature(X86::FEATURE_MMX)) {
*Type = X86::INTEL_PENTIUM_MMX;
break;
}
// 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"
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;
}
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;
}
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"
}
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;
}
}
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;
}
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.
}
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"
}