diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -218,8 +218,6 @@ StringRef Name, llvm::SmallVectorImpl &Features) const override; - StringRef getCPUSpecificTuneName(StringRef Name) const override; - std::optional getCPUCacheLineSize() const override; bool validateAsmConstraint(const char *&Name, diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -1159,43 +1159,19 @@ } bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const { - return llvm::StringSwitch(Name) -#define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, true) -#define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, true) -#include "llvm/TargetParser/X86TargetParser.def" - .Default(false); -} - -static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) { - return llvm::StringSwitch(Name) -#define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, NAME) -#include "llvm/TargetParser/X86TargetParser.def" - .Default(Name); + return llvm::X86::validateCPUSpecificCPUDispatch(Name); } char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const { - return llvm::StringSwitch(CPUSpecificCPUDispatchNameDealias(Name)) -#define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, MANGLING) -#include "llvm/TargetParser/X86TargetParser.def" - .Default(0); + return llvm::X86::getCPUDispatchMangling(Name); } void X86TargetInfo::getCPUSpecificCPUDispatchFeatures( StringRef Name, llvm::SmallVectorImpl &Features) const { - StringRef WholeList = - llvm::StringSwitch(CPUSpecificCPUDispatchNameDealias(Name)) -#define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, FEATURES) -#include "llvm/TargetParser/X86TargetParser.def" - .Default(""); - WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); -} - -StringRef X86TargetInfo::getCPUSpecificTuneName(StringRef Name) const { - return llvm::StringSwitch(Name) -#define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, TUNE_NAME) -#define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, TUNE_NAME) -#include "llvm/TargetParser/X86TargetParser.def" - .Default(""); + SmallVector TargetCPUFeatures; + llvm::X86::getFeaturesForCPU(Name, TargetCPUFeatures, true); + for (auto &F : TargetCPUFeatures) + Features.push_back(F); } // We can't use a generic validation scheme for the cpus accepted here diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2269,8 +2269,7 @@ if (SD) { // Apply the given CPU name as the 'tune-cpu' so that the optimizer can // favor this processor. - TuneCPU = getTarget().getCPUSpecificTuneName( - SD->getCPUName(GD.getMultiVersionIndex())->getName()); + TuneCPU = SD->getCPUName(GD.getMultiVersionIndex())->getName(); } } else { // Otherwise just add the existing target cpu and target features to the diff --git a/clang/test/CodeGen/attr-cpuspecific-avx-abi.c b/clang/test/CodeGen/attr-cpuspecific-avx-abi.c --- a/clang/test/CodeGen/attr-cpuspecific-avx-abi.c +++ b/clang/test/CodeGen/attr-cpuspecific-avx-abi.c @@ -24,5 +24,5 @@ // CHECK: attributes #[[A]] = {{.*}}"target-features"="+avx,+crc32,+cx8,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" // CHECK-SAME: "tune-cpu"="generic" -// CHECK: attributes #[[V]] = {{.*}}"target-features"="+avx,+avx2,+bmi,+cmov,+crc32,+cx8,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" -// CHECK-SAME: "tune-cpu"="haswell" +// CHECK: attributes #[[V]] = {{.*}}"target-features"="+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" +// CHECK-SAME: "tune-cpu"="core_4th_gen_avx" diff --git a/clang/test/CodeGen/attr-cpuspecific.c b/clang/test/CodeGen/attr-cpuspecific.c --- a/clang/test/CodeGen/attr-cpuspecific.c +++ b/clang/test/CodeGen/attr-cpuspecific.c @@ -339,9 +339,9 @@ ATTR(cpu_specific(knl)) void OrderDispatchUsageSpecific(void) {} -// CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+crc32,+cx8,+f16c,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" +// CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" // CHECK-SAME: "tune-cpu"="ivybridge" -// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+cmov,+crc32,+cx8,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" +// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" // CHECK-SAME: "tune-cpu"="knl" -// CHECK: attributes #[[O]] = {{.*}}"target-features"="+cmov,+cx8,+mmx,+movbe,+sse,+sse2,+sse3,+ssse3,+x87" +// CHECK: attributes #[[O]] = {{.*}}"target-features"="+cx16,+cx8,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87" // CHECK-SAME: "tune-cpu"="atom" diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.h b/llvm/include/llvm/TargetParser/X86TargetParser.h --- a/llvm/include/llvm/TargetParser/X86TargetParser.h +++ b/llvm/include/llvm/TargetParser/X86TargetParser.h @@ -155,13 +155,17 @@ ProcessorFeatures getKeyFeature(CPUKind Kind); /// Fill in the features that \p CPU supports into \p Features. -void getFeaturesForCPU(StringRef CPU, SmallVectorImpl &Features); +/// "+" will be append in front of each feature if IfNeedPlus is true. +void getFeaturesForCPU(StringRef CPU, SmallVectorImpl &Features, + bool IfNeedPlus = false); /// Set or clear entries in \p Features that are implied to be enabled/disabled /// by the provided \p Feature. void updateImpliedFeatures(StringRef Feature, bool Enabled, StringMap &Features); +char getCPUDispatchMangling(StringRef Name); +bool validateCPUSpecificCPUDispatch(StringRef Name); uint64_t getCpuSupportsMask(ArrayRef FeatureStrs); unsigned getFeaturePriority(ProcessorFeatures Feat); diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.def b/llvm/include/llvm/TargetParser/X86TargetParser.def --- a/llvm/include/llvm/TargetParser/X86TargetParser.def +++ b/llvm/include/llvm/TargetParser/X86TargetParser.def @@ -235,49 +235,3 @@ X86_FEATURE (LVI_LOAD_HARDENING, "lvi-load-hardening") #undef X86_FEATURE_COMPAT #undef X86_FEATURE - -#ifndef CPU_SPECIFIC -#define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) -#endif - -#ifndef CPU_SPECIFIC_ALIAS -#define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) -#endif - -CPU_SPECIFIC("generic", "generic", 'A', "") -CPU_SPECIFIC("pentium", "pentium", 'B', "") -CPU_SPECIFIC("pentium_pro", "pentiumpro", 'C', "+cmov") -CPU_SPECIFIC("pentium_mmx", "pentium-mmx", 'D', "+mmx") -CPU_SPECIFIC("pentium_ii", "pentium2", 'E', "+cmov,+mmx") -CPU_SPECIFIC("pentium_iii", "pentium3", 'H', "+cmov,+mmx,+sse") -CPU_SPECIFIC_ALIAS("pentium_iii_no_xmm_regs", "pentium3", "pentium_iii") -CPU_SPECIFIC("pentium_4", "pentium4", 'J', "+cmov,+mmx,+sse,+sse2") -CPU_SPECIFIC("pentium_m", "pentium-m", 'K', "+cmov,+mmx,+sse,+sse2") -CPU_SPECIFIC("pentium_4_sse3", "prescott", 'L', "+cmov,+mmx,+sse,+sse2,+sse3") -CPU_SPECIFIC("core_2_duo_ssse3", "core2", 'M', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3") -CPU_SPECIFIC("core_2_duo_sse4_1", "penryn", 'N', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1") -CPU_SPECIFIC("atom", "atom", 'O', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+movbe") -CPU_SPECIFIC("atom_sse4_2", "silvermont", 'c', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt") -CPU_SPECIFIC("core_i7_sse4_2", "nehalem", 'P', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt") -CPU_SPECIFIC("core_aes_pclmulqdq", "westmere", 'Q', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt") -CPU_SPECIFIC("atom_sse4_2_movbe", "silvermont", 'd', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt") -CPU_SPECIFIC("goldmont", "goldmont", 'i', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt") -CPU_SPECIFIC("sandybridge", "sandybridge", 'R', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt,+avx") -CPU_SPECIFIC_ALIAS("core_2nd_gen_avx", "sandybridge", "sandybridge") -CPU_SPECIFIC("ivybridge", "ivybridge", 'S', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt,+f16c,+avx") -CPU_SPECIFIC_ALIAS("core_3rd_gen_avx", "ivybridge", "ivybridge") -CPU_SPECIFIC("haswell", "haswell", 'V', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2") -CPU_SPECIFIC_ALIAS("core_4th_gen_avx", "haswell", "haswell") -CPU_SPECIFIC("core_4th_gen_avx_tsx", "haswell", 'W', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2") -CPU_SPECIFIC("broadwell", "broadwell", 'X', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx") -CPU_SPECIFIC_ALIAS("core_5th_gen_avx", "broadwell", "broadwell") -CPU_SPECIFIC("core_5th_gen_avx_tsx", "broadwell", 'Y', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx") -CPU_SPECIFIC("knl", "knl", 'Z', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512f,+adx,+avx512er,+avx512pf,+avx512cd") -CPU_SPECIFIC_ALIAS("mic_avx512", "knl", "knl") -CPU_SPECIFIC("skylake", "skylake", 'b', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx,+mpx") -CPU_SPECIFIC( "skylake_avx512", "skylake-avx512", 'a', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512dq,+avx512f,+adx,+avx512cd,+avx512bw,+avx512vl,+clwb") -CPU_SPECIFIC("cannonlake", "cannonlake", 'e', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512dq,+avx512f,+adx,+avx512ifma,+avx512cd,+avx512bw,+avx512vl,+avx512vbmi") -CPU_SPECIFIC("knm", "knm", 'j', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512f,+adx,+avx512er,+avx512pf,+avx512cd,+avx5124fmaps,+avx5124vnniw,+avx512vpopcntdq") - -#undef CPU_SPECIFIC_ALIAS -#undef CPU_SPECIFIC diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -1467,20 +1467,22 @@ [TuningSlowUAMem16, TuningInsertVZEROUPPER]>; def : Proc<"pentium", [FeatureX87, FeatureCX8], [TuningSlowUAMem16, TuningInsertVZEROUPPER]>; -def : Proc<"pentium-mmx", [FeatureX87, FeatureCX8, FeatureMMX], - [TuningSlowUAMem16, TuningInsertVZEROUPPER]>; - +foreach P = ["pentium-mmx", "pentium_mmx"] in { + def : Proc; +} def : Proc<"i686", [FeatureX87, FeatureCX8, FeatureCMOV], [TuningSlowUAMem16, TuningInsertVZEROUPPER]>; -def : Proc<"pentiumpro", [FeatureX87, FeatureCX8, FeatureCMOV, - FeatureNOPL], - [TuningSlowUAMem16, TuningInsertVZEROUPPER]>; - -def : Proc<"pentium2", [FeatureX87, FeatureCX8, FeatureMMX, FeatureCMOV, - FeatureFXSR, FeatureNOPL], - [TuningSlowUAMem16, TuningInsertVZEROUPPER]>; - -foreach P = ["pentium3", "pentium3m"] in { +foreach P = ["pentiumpro", "pentium_pro"] in { + def : Proc; +} +foreach P = ["pentium2", "pentium_ii"] in { + def : Proc; +} +foreach P = ["pentium3", "pentium3m", "pentium_iii_no_xmm_regs", "pentium_iii"] in { def : Proc; @@ -1496,12 +1498,14 @@ // measure to avoid performance surprises, in case clang's default cpu // changes slightly. -def : ProcModel<"pentium-m", GenericPostRAModel, +foreach P = ["pentium_m", "pentium-m"] in { +def : ProcModel; +} -foreach P = ["pentium4", "pentium4m"] in { +foreach P = ["pentium4", "pentium4m", "pentium_4"] in { def : ProcModel; // NetBurst. -def : ProcModel<"prescott", GenericPostRAModel, - [FeatureX87, FeatureCX8, FeatureMMX, FeatureSSE3, - FeatureFXSR, FeatureNOPL, FeatureCMOV], - [TuningSlowUAMem16, TuningInsertVZEROUPPER]>; +foreach P = ["prescott", "pentium_4_sse3"] in { + def : ProcModel; +} def : ProcModel<"nocona", GenericPostRAModel, [ FeatureX87, FeatureCX8, @@ -1540,7 +1546,8 @@ ]>; // Intel Core 2 Solo/Duo. -def : ProcModel<"core2", SandyBridgeModel, [ +foreach P = ["core2", "core_2_duo_ssse3"] in { +def : ProcModel; -def : ProcModel<"penryn", SandyBridgeModel, [ +} +foreach P = ["penryn", "core_2_duo_sse4_1"] in { +def : ProcModel; +} // Atom CPUs. foreach P = ["bonnell", "atom"] in { @@ -1581,15 +1591,19 @@ ProcessorFeatures.AtomTuning>; } -foreach P = ["silvermont", "slm"] in { +foreach P = ["silvermont", "slm", "atom_sse4_2"] in { def : ProcModel; } +def : ProcModel<"atom_sse4_2_movbe", SLMModel, ProcessorFeatures.GLMFeatures, + ProcessorFeatures.SLMTuning>; def : ProcModel<"goldmont", SLMModel, ProcessorFeatures.GLMFeatures, ProcessorFeatures.GLMTuning>; -def : ProcModel<"goldmont-plus", SLMModel, ProcessorFeatures.GLPFeatures, - ProcessorFeatures.GLPTuning>; +foreach P = ["goldmont_plus", "goldmont-plus"] in { + def : ProcModel; +} def : ProcModel<"tremont", SLMModel, ProcessorFeatures.TRMFeatures, ProcessorFeatures.TRMTuning>; def : ProcModel<"sierraforest", AlderlakePModel, ProcessorFeatures.SRFFeatures, @@ -1598,43 +1612,49 @@ ProcessorFeatures.TRMTuning>; // "Arrandale" along with corei3 and corei5 -foreach P = ["nehalem", "corei7"] in { +foreach P = ["nehalem", "corei7", "core_i7_sse4_2"] in { def : ProcModel; } // Westmere is the corei3/i5/i7 path from nehalem to sandybridge -def : ProcModel<"westmere", SandyBridgeModel, ProcessorFeatures.WSMFeatures, - ProcessorFeatures.WSMTuning>; +foreach P = ["westmere", "core_aes_pclmulqdq"] in { + def : ProcModel; +} -foreach P = ["sandybridge", "corei7-avx"] in { +foreach P = ["sandybridge", "corei7-avx", "core_2nd_gen_avx"] in { def : ProcModel; } -foreach P = ["ivybridge", "core-avx-i"] in { +foreach P = ["ivybridge", "core-avx-i", "core_3rd_gen_avx"] in { def : ProcModel; } -foreach P = ["haswell", "core-avx2"] in { +foreach P = ["haswell", "core-avx2", "core_4th_gen_avx", "core_4th_gen_avx_tsx"] in { def : ProcModel; } -def : ProcModel<"broadwell", BroadwellModel, ProcessorFeatures.BDWFeatures, - ProcessorFeatures.BDWTuning>; +foreach P = ["broadwell", "core_5th_gen_avx", "core_5th_gen_avx_tsx"] in { + def : ProcModel; +} def : ProcModel<"skylake", SkylakeClientModel, ProcessorFeatures.SKLFeatures, ProcessorFeatures.SKLTuning>; // FIXME: define KNL scheduler model -def : ProcModel<"knl", HaswellModel, ProcessorFeatures.KNLFeatures, - ProcessorFeatures.KNLTuning>; +foreach P = ["knl", "mic_avx512"] in { + def : ProcModel; +} def : ProcModel<"knm", HaswellModel, ProcessorFeatures.KNMFeatures, ProcessorFeatures.KNLTuning>; -foreach P = ["skylake-avx512", "skx"] in { +foreach P = ["skylake-avx512", "skx", "skylake_avx512"] in { def : ProcModel; } @@ -1645,12 +1665,16 @@ ProcessorFeatures.CPXFeatures, ProcessorFeatures.CPXTuning>; def : ProcModel<"cannonlake", SkylakeServerModel, ProcessorFeatures.CNLFeatures, ProcessorFeatures.CNLTuning>; -def : ProcModel<"icelake-client", IceLakeModel, +foreach P = ["icelake-client", "icelake_client"] in { +def : ProcModel; +} def : ProcModel<"rocketlake", IceLakeModel, ProcessorFeatures.ICLFeatures, ProcessorFeatures.ICLTuning>; -def : ProcModel<"icelake-server", IceLakeModel, +foreach P = ["icelake-server", "icelake_server"] in { +def : ProcModel; +} def : ProcModel<"tigerlake", IceLakeModel, ProcessorFeatures.TGLFeatures, ProcessorFeatures.TGLTuning>; def : ProcModel<"sapphirerapids", SkylakeServerModel, diff --git a/llvm/lib/TargetParser/X86TargetParser.cpp b/llvm/lib/TargetParser/X86TargetParser.cpp --- a/llvm/lib/TargetParser/X86TargetParser.cpp +++ b/llvm/lib/TargetParser/X86TargetParser.cpp @@ -107,6 +107,8 @@ X86::CPUKind Kind; unsigned KeyFeature; FeatureBitset Features; + char Mangling; + bool OnlyForCPUDispatchSpecific; }; struct FeatureInfo { @@ -307,148 +309,175 @@ FeatureSHSTK; constexpr ProcInfo Processors[] = { - // Empty processor. Include X87 and CMPXCHG8 for backwards compatibility. - { {""}, CK_None, ~0U, FeatureX87 | FeatureCMPXCHG8B }, + // Empty processor. Include X87 and CMPXCHG8 for backwards compatibility. + { {""}, CK_None, ~0U, FeatureX87 | FeatureCMPXCHG8B, '\0', false }, + { {"generic"}, CK_None, ~0U, FeatureX87 | FeatureCMPXCHG8B | Feature64BIT, 'A', true }, // i386-generation processors. - { {"i386"}, CK_i386, ~0U, FeatureX87 }, + { {"i386"}, CK_i386, ~0U, FeatureX87, '\0', false }, // i486-generation processors. - { {"i486"}, CK_i486, ~0U, FeatureX87 }, - { {"winchip-c6"}, CK_WinChipC6, ~0U, FeaturesPentiumMMX }, - { {"winchip2"}, CK_WinChip2, ~0U, FeaturesPentiumMMX | Feature3DNOW }, - { {"c3"}, CK_C3, ~0U, FeaturesPentiumMMX | Feature3DNOW }, + { {"i486"}, CK_i486, ~0U, FeatureX87, '\0', false }, + { {"winchip-c6"}, CK_WinChipC6, ~0U, FeaturesPentiumMMX, '\0', false }, + { {"winchip2"}, CK_WinChip2, ~0U, FeaturesPentiumMMX | Feature3DNOW, '\0', false }, + { {"c3"}, CK_C3, ~0U, FeaturesPentiumMMX | Feature3DNOW, '\0', false }, // i586-generation processors, P5 microarchitecture based. - { {"i586"}, CK_i586, ~0U, FeatureX87 | FeatureCMPXCHG8B }, - { {"pentium"}, CK_Pentium, ~0U, FeatureX87 | FeatureCMPXCHG8B }, - { {"pentium-mmx"}, CK_PentiumMMX, ~0U, FeaturesPentiumMMX }, + { {"i586"}, CK_i586, ~0U, FeatureX87 | FeatureCMPXCHG8B, '\0', false }, + { {"pentium"}, CK_Pentium, ~0U, FeatureX87 | FeatureCMPXCHG8B, 'B', false }, + { {"pentium-mmx"}, CK_PentiumMMX, ~0U, FeaturesPentiumMMX, 'D', false }, + { {"pentium_mmx"}, CK_PentiumMMX, ~0U, FeaturesPentiumMMX, 'D', true }, // i686-generation processors, P6 / Pentium M microarchitecture based. - { {"pentiumpro"}, CK_PentiumPro, ~0U, FeatureX87 | FeatureCMPXCHG8B }, - { {"i686"}, CK_i686, ~0U, FeatureX87 | FeatureCMPXCHG8B }, - { {"pentium2"}, CK_Pentium2, ~0U, FeaturesPentium2 }, - { {"pentium3"}, CK_Pentium3, ~0U, FeaturesPentium3 }, - { {"pentium3m"}, CK_Pentium3, ~0U, FeaturesPentium3 }, - { {"pentium-m"}, CK_PentiumM, ~0U, FeaturesPentium4 }, - { {"c3-2"}, CK_C3_2, ~0U, FeaturesPentium3 }, - { {"yonah"}, CK_Yonah, ~0U, FeaturesPrescott }, + { {"pentiumpro"}, CK_PentiumPro, ~0U, FeatureX87 | FeatureCMPXCHG8B, 'C', false }, + { {"pentium_pro"}, CK_PentiumPro, ~0U, FeatureX87 | FeatureCMPXCHG8B, 'C', true }, + { {"i686"}, CK_i686, ~0U, FeatureX87 | FeatureCMPXCHG8B, '\0', false }, + { {"pentium2"}, CK_Pentium2, ~0U, FeaturesPentium2, 'E', false }, + { {"pentium_ii"}, CK_Pentium2, ~0U, FeaturesPentium2, 'E', true }, + { {"pentium3"}, CK_Pentium3, ~0U, FeaturesPentium3, 'H', false }, + { {"pentium3m"}, CK_Pentium3, ~0U, FeaturesPentium3, 'H', false }, + { {"pentium_iii"}, CK_Pentium3, ~0U, FeaturesPentium3, 'H', true }, + { {"pentium_iii_no_xmm_regs"}, CK_Pentium3, ~0U, FeaturesPentium3, 'H', true }, + { {"pentium-m"}, CK_PentiumM, ~0U, FeaturesPentium4, 'K', false }, + { {"pentium_m"}, CK_PentiumM, ~0U, FeaturesPentium4, 'K', true }, + { {"c3-2"}, CK_C3_2, ~0U, FeaturesPentium3, '\0', false }, + { {"yonah"}, CK_Yonah, ~0U, FeaturesPrescott, 'L', false }, // Netburst microarchitecture based processors. - { {"pentium4"}, CK_Pentium4, ~0U, FeaturesPentium4 }, - { {"pentium4m"}, CK_Pentium4, ~0U, FeaturesPentium4 }, - { {"prescott"}, CK_Prescott, ~0U, FeaturesPrescott }, - { {"nocona"}, CK_Nocona, ~0U, FeaturesNocona }, + { {"pentium4"}, CK_Pentium4, ~0U, FeaturesPentium4, 'J', false }, + { {"pentium4m"}, CK_Pentium4, ~0U, FeaturesPentium4, 'J', false }, + { {"pentium_4"}, CK_Pentium4, ~0U, FeaturesPentium4, 'J', true }, + { {"pentium_4_sse3"}, CK_Prescott, ~0U, FeaturesPrescott, 'L', true }, + { {"prescott"}, CK_Prescott, ~0U, FeaturesPrescott, 'L', false }, + { {"nocona"}, CK_Nocona, ~0U, FeaturesNocona, 'L', false }, // Core microarchitecture based processors. - { {"core2"}, CK_Core2, FEATURE_SSSE3, FeaturesCore2 }, - { {"penryn"}, CK_Penryn, ~0U, FeaturesPenryn }, + { {"core2"}, CK_Core2, FEATURE_SSSE3, FeaturesCore2, 'M', false }, + { {"core_2_duo_ssse3"}, CK_Core2, ~0U, FeaturesCore2, 'N', true }, + { {"penryn"}, CK_Penryn, ~0U, FeaturesPenryn, 'N', false }, + { {"core_2_duo_sse4_1"}, CK_Penryn, ~0U, FeaturesPenryn, 'N', true }, // Atom processors - { {"bonnell"}, CK_Bonnell, FEATURE_SSSE3, FeaturesBonnell }, - { {"atom"}, CK_Bonnell, FEATURE_SSSE3, FeaturesBonnell }, - { {"silvermont"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont }, - { {"slm"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont }, - { {"goldmont"}, CK_Goldmont, FEATURE_SSE4_2, FeaturesGoldmont }, - { {"goldmont-plus"}, CK_GoldmontPlus, FEATURE_SSE4_2, FeaturesGoldmontPlus }, - { {"tremont"}, CK_Tremont, FEATURE_SSE4_2, FeaturesTremont }, + { {"bonnell"}, CK_Bonnell, FEATURE_SSSE3, FeaturesBonnell, 'a', false }, + { {"atom"}, CK_Bonnell, FEATURE_SSSE3, FeaturesBonnell, 'O', false }, + { {"silvermont"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont, 'c', false }, + { {"slm"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont, 'c', false }, + { {"atom_sse4_2"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont, 'c', true }, + { {"atom_sse4_2_movbe"}, CK_Goldmont, FEATURE_SSE4_2, FeaturesGoldmont, 'c', true }, + { {"goldmont"}, CK_Goldmont, FEATURE_SSE4_2, FeaturesGoldmont, 'i', false }, + { {"goldmont-plus"}, CK_GoldmontPlus, FEATURE_SSE4_2, FeaturesGoldmontPlus, 'd', false }, + { {"goldmont_plus"}, CK_GoldmontPlus, FEATURE_SSE4_2, FeaturesGoldmontPlus, 'd', true }, + { {"tremont"}, CK_Tremont, FEATURE_SSE4_2, FeaturesTremont, 'd', false }, // Nehalem microarchitecture based processors. - { {"nehalem"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem }, - { {"corei7"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem }, + { {"nehalem"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem, 'P', false }, + { {"core_i7_sse4_2"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem, 'P', true }, + { {"corei7"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem, 'P', false }, // Westmere microarchitecture based processors. - { {"westmere"}, CK_Westmere, FEATURE_PCLMUL, FeaturesWestmere }, + { {"westmere"}, CK_Westmere, FEATURE_PCLMUL, FeaturesWestmere, 'Q', false }, + { {"core_aes_pclmulqdq"}, CK_Westmere, FEATURE_PCLMUL, FeaturesWestmere, 'Q', true }, // Sandy Bridge microarchitecture based processors. - { {"sandybridge"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge }, - { {"corei7-avx"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge }, + { {"sandybridge"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge, 'R', false }, + { {"core_2nd_gen_avx"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge, 'R', true }, + { {"corei7-avx"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge, 'R', false }, // Ivy Bridge microarchitecture based processors. - { {"ivybridge"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge }, - { {"core-avx-i"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge }, + { {"ivybridge"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge, 'S', false }, + { {"core_3rd_gen_avx"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge, 'S', true }, + { {"core-avx-i"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge, 'S', false }, // Haswell microarchitecture based processors. - { {"haswell"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell }, - { {"core-avx2"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell }, + { {"haswell"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell, 'V', false }, + { {"core-avx2"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell, 'V', false }, + { {"core_4th_gen_avx"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell, 'V', true }, + { {"core_4th_gen_avx_tsx"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell, 'V', true }, // Broadwell microarchitecture based processors. - { {"broadwell"}, CK_Broadwell, FEATURE_AVX2, FeaturesBroadwell }, + { {"broadwell"}, CK_Broadwell, FEATURE_AVX2, FeaturesBroadwell, 'X', false }, + { {"core_5th_gen_avx"}, CK_Broadwell, FEATURE_AVX2, FeaturesBroadwell, 'X', true }, + { {"core_5th_gen_avx_tsx"}, CK_Broadwell, FEATURE_AVX2, FeaturesBroadwell, 'X', true }, // Skylake client microarchitecture based processors. - { {"skylake"}, CK_SkylakeClient, FEATURE_AVX2, FeaturesSkylakeClient }, + { {"skylake"}, CK_SkylakeClient, FEATURE_AVX2, FeaturesSkylakeClient, 'b', false }, // Skylake server microarchitecture based processors. - { {"skylake-avx512"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer }, - { {"skx"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer }, + { {"skylake-avx512"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer, 'a', false }, + { {"skx"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer, 'a', false }, + { {"skylake_avx512"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer, 'a', true }, // Cascadelake Server microarchitecture based processors. - { {"cascadelake"}, CK_Cascadelake, FEATURE_AVX512VNNI, FeaturesCascadeLake }, + { {"cascadelake"}, CK_Cascadelake, FEATURE_AVX512VNNI, FeaturesCascadeLake, 'o', false }, // Cooperlake Server microarchitecture based processors. - { {"cooperlake"}, CK_Cooperlake, FEATURE_AVX512BF16, FeaturesCooperLake }, + { {"cooperlake"}, CK_Cooperlake, FEATURE_AVX512BF16, FeaturesCooperLake, 'o', false }, // Cannonlake client microarchitecture based processors. - { {"cannonlake"}, CK_Cannonlake, FEATURE_AVX512VBMI, FeaturesCannonlake }, + { {"cannonlake"}, CK_Cannonlake, FEATURE_AVX512VBMI, FeaturesCannonlake, 'e', false }, // Icelake client microarchitecture based processors. - { {"icelake-client"}, CK_IcelakeClient, FEATURE_AVX512VBMI2, FeaturesICLClient }, + { {"icelake-client"}, CK_IcelakeClient, FEATURE_AVX512VBMI2, FeaturesICLClient, 'k', false }, + { {"icelake_client"}, CK_IcelakeClient, FEATURE_AVX512VBMI2, FeaturesICLClient, 'k', true }, // Rocketlake microarchitecture based processors. - { {"rocketlake"}, CK_Rocketlake, FEATURE_AVX512VBMI2, FeaturesRocketlake }, + { {"rocketlake"}, CK_Rocketlake, FEATURE_AVX512VBMI2, FeaturesRocketlake, 'k', false }, // Icelake server microarchitecture based processors. - { {"icelake-server"}, CK_IcelakeServer, FEATURE_AVX512VBMI2, FeaturesICLServer }, + { {"icelake-server"}, CK_IcelakeServer, FEATURE_AVX512VBMI2, FeaturesICLServer, 'k', false }, + { {"icelake_server"}, CK_IcelakeServer, FEATURE_AVX512VBMI2, FeaturesICLServer, 'k', true }, // Tigerlake microarchitecture based processors. - { {"tigerlake"}, CK_Tigerlake, FEATURE_AVX512VP2INTERSECT, FeaturesTigerlake }, + { {"tigerlake"}, CK_Tigerlake, FEATURE_AVX512VP2INTERSECT, FeaturesTigerlake, 'l', false }, // Sapphire Rapids microarchitecture based processors. - { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512BF16, FeaturesSapphireRapids }, + { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512BF16, FeaturesSapphireRapids, 'n', false }, // Alderlake microarchitecture based processors. - { {"alderlake"}, CK_Alderlake, FEATURE_AVX2, FeaturesAlderlake }, + { {"alderlake"}, CK_Alderlake, FEATURE_AVX2, FeaturesAlderlake, 'p', false }, // Raptorlake microarchitecture based processors. - { {"raptorlake"}, CK_Raptorlake, FEATURE_AVX2, FeaturesAlderlake }, + { {"raptorlake"}, CK_Raptorlake, FEATURE_AVX2, FeaturesAlderlake, 'p', false }, // Meteorlake microarchitecture based processors. - { {"meteorlake"}, CK_Meteorlake, FEATURE_AVX2, FeaturesAlderlake }, + { {"meteorlake"}, CK_Meteorlake, FEATURE_AVX2, FeaturesAlderlake, 'p', false }, // Sierraforest microarchitecture based processors. - { {"sierraforest"}, CK_Sierraforest, FEATURE_AVX2, FeaturesSierraforest }, + { {"sierraforest"}, CK_Sierraforest, FEATURE_AVX2, FeaturesSierraforest, 'p', false }, // Grandridge microarchitecture based processors. - { {"grandridge"}, CK_Grandridge, FEATURE_AVX2, FeaturesGrandridge }, + { {"grandridge"}, CK_Grandridge, FEATURE_AVX2, FeaturesGrandridge, 'p', false }, // Granite Rapids microarchitecture based processors. - { {"graniterapids"}, CK_Graniterapids, FEATURE_AVX512BF16, FeaturesGraniteRapids }, + { {"graniterapids"}, CK_Graniterapids, FEATURE_AVX512BF16, FeaturesGraniteRapids, 'n', false }, // Emerald Rapids microarchitecture based processors. - { {"emeraldrapids"}, CK_Emeraldrapids, FEATURE_AVX512BF16, FeaturesSapphireRapids }, + { {"emeraldrapids"}, CK_Emeraldrapids, FEATURE_AVX512BF16, FeaturesSapphireRapids, 'n', false }, // Knights Landing processor. - { {"knl"}, CK_KNL, FEATURE_AVX512F, FeaturesKNL }, + { {"knl"}, CK_KNL, FEATURE_AVX512F, FeaturesKNL, 'Z', false }, + { {"mic_avx512"}, CK_KNL, FEATURE_AVX512F, FeaturesKNL, 'Z', true }, // Knights Mill processor. - { {"knm"}, CK_KNM, FEATURE_AVX5124FMAPS, FeaturesKNM }, + { {"knm"}, CK_KNM, FEATURE_AVX5124FMAPS, FeaturesKNM, 'j', false }, // Lakemont microarchitecture based processors. - { {"lakemont"}, CK_Lakemont, ~0U, FeatureCMPXCHG8B }, + { {"lakemont"}, CK_Lakemont, ~0U, FeatureCMPXCHG8B, '\0', false }, // K6 architecture processors. - { {"k6"}, CK_K6, ~0U, FeaturesK6 }, - { {"k6-2"}, CK_K6_2, ~0U, FeaturesK6 | Feature3DNOW }, - { {"k6-3"}, CK_K6_3, ~0U, FeaturesK6 | Feature3DNOW }, + { {"k6"}, CK_K6, ~0U, FeaturesK6, '\0', false }, + { {"k6-2"}, CK_K6_2, ~0U, FeaturesK6 | Feature3DNOW, '\0', false }, + { {"k6-3"}, CK_K6_3, ~0U, FeaturesK6 | Feature3DNOW, '\0', false }, // K7 architecture processors. - { {"athlon"}, CK_Athlon, ~0U, FeaturesAthlon }, - { {"athlon-tbird"}, CK_Athlon, ~0U, FeaturesAthlon }, - { {"athlon-xp"}, CK_AthlonXP, ~0U, FeaturesAthlonXP }, - { {"athlon-mp"}, CK_AthlonXP, ~0U, FeaturesAthlonXP }, - { {"athlon-4"}, CK_AthlonXP, ~0U, FeaturesAthlonXP }, + { {"athlon"}, CK_Athlon, ~0U, FeaturesAthlon, '\0', false }, + { {"athlon-tbird"}, CK_Athlon, ~0U, FeaturesAthlon, '\0', false }, + { {"athlon-xp"}, CK_AthlonXP, ~0U, FeaturesAthlonXP, '\0', false }, + { {"athlon-mp"}, CK_AthlonXP, ~0U, FeaturesAthlonXP, '\0', false }, + { {"athlon-4"}, CK_AthlonXP, ~0U, FeaturesAthlonXP, '\0', false }, // K8 architecture processors. - { {"k8"}, CK_K8, ~0U, FeaturesK8 }, - { {"athlon64"}, CK_K8, ~0U, FeaturesK8 }, - { {"athlon-fx"}, CK_K8, ~0U, FeaturesK8 }, - { {"opteron"}, CK_K8, ~0U, FeaturesK8 }, - { {"k8-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3 }, - { {"athlon64-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3 }, - { {"opteron-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3 }, - { {"amdfam10"}, CK_AMDFAM10, FEATURE_SSE4_A, FeaturesAMDFAM10 }, - { {"barcelona"}, CK_AMDFAM10, FEATURE_SSE4_A, FeaturesAMDFAM10 }, + { {"k8"}, CK_K8, ~0U, FeaturesK8, '\0', false }, + { {"athlon64"}, CK_K8, ~0U, FeaturesK8, '\0', false }, + { {"athlon-fx"}, CK_K8, ~0U, FeaturesK8, '\0', false }, + { {"opteron"}, CK_K8, ~0U, FeaturesK8, '\0', false }, + { {"k8-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3, '\0', false }, + { {"athlon64-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3, '\0', false }, + { {"opteron-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3, '\0', false }, + { {"amdfam10"}, CK_AMDFAM10, FEATURE_SSE4_A, FeaturesAMDFAM10, '\0', false }, + { {"barcelona"}, CK_AMDFAM10, FEATURE_SSE4_A, FeaturesAMDFAM10, '\0', false }, // Bobcat architecture processors. - { {"btver1"}, CK_BTVER1, FEATURE_SSE4_A, FeaturesBTVER1 }, - { {"btver2"}, CK_BTVER2, FEATURE_BMI, FeaturesBTVER2 }, + { {"btver1"}, CK_BTVER1, FEATURE_SSE4_A, FeaturesBTVER1, '\0', false }, + { {"btver2"}, CK_BTVER2, FEATURE_BMI, FeaturesBTVER2, '\0', false }, // Bulldozer architecture processors. - { {"bdver1"}, CK_BDVER1, FEATURE_XOP, FeaturesBDVER1 }, - { {"bdver2"}, CK_BDVER2, FEATURE_FMA, FeaturesBDVER2 }, - { {"bdver3"}, CK_BDVER3, FEATURE_FMA, FeaturesBDVER3 }, - { {"bdver4"}, CK_BDVER4, FEATURE_AVX2, FeaturesBDVER4 }, + { {"bdver1"}, CK_BDVER1, FEATURE_XOP, FeaturesBDVER1, '\0', false }, + { {"bdver2"}, CK_BDVER2, FEATURE_FMA, FeaturesBDVER2, '\0', false }, + { {"bdver3"}, CK_BDVER3, FEATURE_FMA, FeaturesBDVER3, '\0', false }, + { {"bdver4"}, CK_BDVER4, FEATURE_AVX2, FeaturesBDVER4, '\0', false }, // Zen architecture processors. - { {"znver1"}, CK_ZNVER1, FEATURE_AVX2, FeaturesZNVER1 }, - { {"znver2"}, CK_ZNVER2, FEATURE_AVX2, FeaturesZNVER2 }, - { {"znver3"}, CK_ZNVER3, FEATURE_AVX2, FeaturesZNVER3 }, - { {"znver4"}, CK_ZNVER4, FEATURE_AVX512VBMI2, FeaturesZNVER4 }, + { {"znver1"}, CK_ZNVER1, FEATURE_AVX2, FeaturesZNVER1, '\0', false }, + { {"znver2"}, CK_ZNVER2, FEATURE_AVX2, FeaturesZNVER2, '\0', false }, + { {"znver3"}, CK_ZNVER3, FEATURE_AVX2, FeaturesZNVER3, '\0', false }, + { {"znver4"}, CK_ZNVER4, FEATURE_AVX512VBMI2, FeaturesZNVER4, '\0', false }, // Generic 64-bit processor. - { {"x86-64"}, CK_x86_64, ~0U, FeaturesX86_64 }, - { {"x86-64-v2"}, CK_x86_64_v2, ~0U, FeaturesX86_64_V2 }, - { {"x86-64-v3"}, CK_x86_64_v3, ~0U, FeaturesX86_64_V3 }, - { {"x86-64-v4"}, CK_x86_64_v4, ~0U, FeaturesX86_64_V4 }, + { {"x86-64"}, CK_x86_64, ~0U, FeaturesX86_64, '\0', false }, + { {"x86-64-v2"}, CK_x86_64_v2, ~0U, FeaturesX86_64_V2, '\0', false }, + { {"x86-64-v3"}, CK_x86_64_v3, ~0U, FeaturesX86_64_V3, '\0', false }, + { {"x86-64-v4"}, CK_x86_64_v4, ~0U, FeaturesX86_64_V4, '\0', false }, // Geode processors. - { {"geode"}, CK_Geode, ~0U, FeaturesGeode }, + { {"geode"}, CK_Geode, ~0U, FeaturesGeode, '\0', false }, }; constexpr const char *NoTuneList[] = {"x86-64-v2", "x86-64-v3", "x86-64-v4"}; X86::CPUKind llvm::X86::parseArchX86(StringRef CPU, bool Only64Bit) { for (const auto &P : Processors) - if (P.Name == CPU && (P.Features[FEATURE_64BIT] || !Only64Bit)) + if (!P.OnlyForCPUDispatchSpecific && P.Name == CPU && + (P.Features[FEATURE_64BIT] || !Only64Bit)) return P.Kind; return CK_None; @@ -463,14 +492,16 @@ void llvm::X86::fillValidCPUArchList(SmallVectorImpl &Values, bool Only64Bit) { for (const auto &P : Processors) - if (!P.Name.empty() && (P.Features[FEATURE_64BIT] || !Only64Bit)) + if (!P.OnlyForCPUDispatchSpecific && !P.Name.empty() && + (P.Features[FEATURE_64BIT] || !Only64Bit)) Values.emplace_back(P.Name); } void llvm::X86::fillValidTuneCPUList(SmallVectorImpl &Values, bool Only64Bit) { for (const ProcInfo &P : Processors) - if (!P.Name.empty() && (P.Features[FEATURE_64BIT] || !Only64Bit) && + if (!P.OnlyForCPUDispatchSpecific && !P.Name.empty() && + (P.Features[FEATURE_64BIT] || !Only64Bit) && !llvm::is_contained(NoTuneList, P.Name)) Values.emplace_back(P.Name); } @@ -630,8 +661,14 @@ #include "llvm/TargetParser/X86TargetParser.def" }; +constexpr FeatureInfo FeatureInfos_WithPLUS[X86::CPU_FEATURE_MAX] = { +#define X86_FEATURE(ENUM, STR) {{"+" STR}, ImpliedFeatures##ENUM}, +#include "llvm/TargetParser/X86TargetParser.def" +}; + void llvm::X86::getFeaturesForCPU(StringRef CPU, - SmallVectorImpl &EnabledFeatures) { + SmallVectorImpl &EnabledFeatures, + bool IfNeedPlus) { auto I = llvm::find_if(Processors, [&](const ProcInfo &P) { return P.Name == CPU; }); assert(I != std::end(Processors) && "Processor not found!"); @@ -644,8 +681,11 @@ // Add the string version of all set bits. for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i) - if (Bits[i] && !FeatureInfos[i].Name.empty()) - EnabledFeatures.push_back(FeatureInfos[i].Name); + if (Bits[i] && !FeatureInfos[i].Name.empty() && + !FeatureInfos_WithPLUS[i].Name.empty()){ + EnabledFeatures.push_back(IfNeedPlus ? FeatureInfos_WithPLUS[i].Name + : FeatureInfos[i].Name); + } } // For each feature that is (transitively) implied by this feature, set it. @@ -703,6 +743,20 @@ Features[FeatureInfos[i].Name] = Enabled; } +char llvm::X86::getCPUDispatchMangling(StringRef CPU) { + auto I = llvm::find_if(Processors, + [&](const ProcInfo &P) { return P.Name == CPU; }); + assert(I != std::end(Processors) && "Processor not found!"); + assert(I->Mangling != '\0' && "Processor dooesn't support function multiversion!"); + return I->Mangling; +} + +bool llvm::X86::validateCPUSpecificCPUDispatch(StringRef Name) { + auto I = llvm::find_if(Processors, + [&](const ProcInfo &P) { return P.Name == Name; }); + return I != std::end(Processors); +} + uint64_t llvm::X86::getCpuSupportsMask(ArrayRef FeatureStrs) { // Processor features and mapping to processor feature value. uint64_t FeaturesMask = 0; diff --git a/llvm/test/CodeGen/X86/cpus-intel.ll b/llvm/test/CodeGen/X86/cpus-intel.ll --- a/llvm/test/CodeGen/X86/cpus-intel.ll +++ b/llvm/test/CodeGen/X86/cpus-intel.ll @@ -6,16 +6,24 @@ ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=i586 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium-mmx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium_mmx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=i686 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentiumpro 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium_pro 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium2 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium_ii 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium3 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium3m 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium_iii 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium_iii_no_xmm_regs 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium_m 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium-m 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium4 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium4m 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium_4 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=yonah 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=prescott 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=pentium_4_sse3 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=lakemont 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=raptorlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=i686-unknown-unknown -mcpu=meteorlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty @@ -26,26 +34,39 @@ ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=nocona 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core2 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_2_duo_ssse3 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=penryn 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_2_duo_sse4_1 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=nehalem 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=corei7 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_i7_sse4_2 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=westmere 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_aes_pclmulqdq 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_5th_gen_avx_tsx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=sandybridge 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=corei7-avx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_2nd_gen_avx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=ivybridge 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core-avx-i 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_3rd_gen_avx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=haswell 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core-avx2 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_4th_gen_avx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_4th_gen_avx_tsx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=broadwell 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=core_5th_gen_avx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=skylake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=skylake-avx512 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=skx 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=skylake_avx512 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=cascadelake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=cooperlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=cannonlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=icelake-client 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=icelake_client 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=rocketlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=icelake-server 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=icelake_server 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=tigerlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=sapphirerapids 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=alderlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty @@ -53,16 +74,20 @@ ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=bonnell 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=silvermont 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=slm 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=atom_sse4_2 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=goldmont 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=goldmont-plus 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=goldmont_plus 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=tremont 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=knl 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=mic_avx512 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=knm 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=raptorlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=meteorlake 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=sierraforest 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=grandridge 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty ; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=graniterapids 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty +; RUN: llc < %s -o /dev/null -mtriple=x86_64-unknown-unknown -mcpu=atom_sse4_2_movbe 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ERROR --allow-empty define void @foo() { ret void