| 1 | //===-- X86TargetParser - Parser for X86 features ---------------*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file implements a target parser to recognise X86 hardware features. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #include "llvm/TargetParser/X86TargetParser.h" |
| 14 | #include "llvm/ADT/Bitset.h" |
| 15 | #include "llvm/ADT/StringSwitch.h" |
| 16 | #include <numeric> |
| 17 | |
| 18 | using namespace llvm; |
| 19 | using namespace llvm::X86; |
| 20 | |
| 21 | namespace { |
| 22 | |
| 23 | using FeatureBitset = Bitset<X86::CPU_FEATURE_MAX>; |
| 24 | |
| 25 | struct ProcInfo { |
| 26 | StringLiteral Name; |
| 27 | X86::CPUKind Kind; |
| 28 | unsigned KeyFeature; |
| 29 | FeatureBitset Features; |
| 30 | char Mangling; |
| 31 | bool OnlyForCPUDispatchSpecific; |
| 32 | }; |
| 33 | |
| 34 | struct FeatureInfo { |
| 35 | StringLiteral NameWithPlus; |
| 36 | FeatureBitset ImpliedFeatures; |
| 37 | |
| 38 | StringRef getName(bool WithPlus = false) const { |
| 39 | assert(NameWithPlus[0] == '+' && "Expected string to start with '+'" ); |
| 40 | if (WithPlus) |
| 41 | return NameWithPlus; |
| 42 | return NameWithPlus.drop_front(); |
| 43 | } |
| 44 | }; |
| 45 | |
| 46 | } // end anonymous namespace |
| 47 | |
| 48 | #define X86_FEATURE(ENUM, STRING) \ |
| 49 | constexpr FeatureBitset Feature##ENUM = {X86::FEATURE_##ENUM}; |
| 50 | #include "llvm/TargetParser/X86TargetParser.def" |
| 51 | |
| 52 | // Pentium with MMX. |
| 53 | constexpr FeatureBitset FeaturesPentiumMMX = |
| 54 | FeatureX87 | FeatureCMPXCHG8B | FeatureMMX; |
| 55 | |
| 56 | // Pentium 2 and 3. |
| 57 | constexpr FeatureBitset FeaturesPentium2 = |
| 58 | FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | FeatureFXSR | FeatureCMOV; |
| 59 | constexpr FeatureBitset FeaturesPentium3 = FeaturesPentium2 | FeatureSSE; |
| 60 | |
| 61 | // Pentium 4 CPUs |
| 62 | constexpr FeatureBitset FeaturesPentium4 = FeaturesPentium3 | FeatureSSE2; |
| 63 | constexpr FeatureBitset FeaturesPrescott = FeaturesPentium4 | FeatureSSE3; |
| 64 | constexpr FeatureBitset FeaturesNocona = |
| 65 | FeaturesPrescott | Feature64BIT | FeatureCMPXCHG16B; |
| 66 | |
| 67 | // Basic 64-bit capable CPU. |
| 68 | constexpr FeatureBitset FeaturesX86_64 = FeaturesPentium4 | Feature64BIT; |
| 69 | constexpr FeatureBitset FeaturesX86_64_V2 = FeaturesX86_64 | FeatureSAHF | |
| 70 | FeaturePOPCNT | FeatureCRC32 | |
| 71 | FeatureSSE4_2 | FeatureCMPXCHG16B; |
| 72 | constexpr FeatureBitset FeaturesX86_64_V3 = |
| 73 | FeaturesX86_64_V2 | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureF16C | |
| 74 | FeatureFMA | FeatureLZCNT | FeatureMOVBE | FeatureXSAVE; |
| 75 | constexpr FeatureBitset FeaturesX86_64_V4 = FeaturesX86_64_V3 | FeatureEVEX512 | |
| 76 | FeatureAVX512BW | FeatureAVX512CD | |
| 77 | FeatureAVX512DQ | FeatureAVX512VL; |
| 78 | |
| 79 | // Intel Core CPUs |
| 80 | constexpr FeatureBitset FeaturesCore2 = |
| 81 | FeaturesNocona | FeatureSAHF | FeatureSSSE3; |
| 82 | constexpr FeatureBitset FeaturesPenryn = FeaturesCore2 | FeatureSSE4_1; |
| 83 | constexpr FeatureBitset FeaturesNehalem = |
| 84 | FeaturesPenryn | FeaturePOPCNT | FeatureCRC32 | FeatureSSE4_2; |
| 85 | constexpr FeatureBitset FeaturesWestmere = FeaturesNehalem | FeaturePCLMUL; |
| 86 | constexpr FeatureBitset FeaturesSandyBridge = |
| 87 | FeaturesWestmere | FeatureAVX | FeatureXSAVE | FeatureXSAVEOPT; |
| 88 | constexpr FeatureBitset FeaturesIvyBridge = |
| 89 | FeaturesSandyBridge | FeatureF16C | FeatureFSGSBASE | FeatureRDRND; |
| 90 | constexpr FeatureBitset FeaturesHaswell = |
| 91 | FeaturesIvyBridge | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureFMA | |
| 92 | FeatureINVPCID | FeatureLZCNT | FeatureMOVBE; |
| 93 | constexpr FeatureBitset FeaturesBroadwell = |
| 94 | FeaturesHaswell | FeatureADX | FeaturePRFCHW | FeatureRDSEED; |
| 95 | |
| 96 | // Intel Knights Landing and Knights Mill |
| 97 | // Knights Landing has feature parity with Broadwell. |
| 98 | constexpr FeatureBitset FeaturesKNL = FeaturesBroadwell | FeatureAES | |
| 99 | FeatureAVX512F | FeatureEVEX512 | |
| 100 | FeatureAVX512CD; |
| 101 | constexpr FeatureBitset FeaturesKNM = FeaturesKNL | FeatureAVX512VPOPCNTDQ; |
| 102 | |
| 103 | // Intel Skylake processors. |
| 104 | constexpr FeatureBitset FeaturesSkylakeClient = |
| 105 | FeaturesBroadwell | FeatureAES | FeatureCLFLUSHOPT | FeatureXSAVEC | |
| 106 | FeatureXSAVES | FeatureSGX; |
| 107 | // SkylakeServer inherits all SkylakeClient features except SGX. |
| 108 | // FIXME: That doesn't match gcc. |
| 109 | constexpr FeatureBitset FeaturesSkylakeServer = |
| 110 | (FeaturesSkylakeClient & ~FeatureSGX) | FeatureAVX512F | FeatureEVEX512 | |
| 111 | FeatureAVX512CD | FeatureAVX512DQ | FeatureAVX512BW | FeatureAVX512VL | |
| 112 | FeatureCLWB | FeaturePKU; |
| 113 | constexpr FeatureBitset FeaturesCascadeLake = |
| 114 | FeaturesSkylakeServer | FeatureAVX512VNNI; |
| 115 | constexpr FeatureBitset FeaturesCooperLake = |
| 116 | FeaturesCascadeLake | FeatureAVX512BF16; |
| 117 | |
| 118 | // Intel 10nm processors. |
| 119 | constexpr FeatureBitset FeaturesCannonlake = |
| 120 | FeaturesSkylakeClient | FeatureAVX512F | FeatureEVEX512 | FeatureAVX512CD | |
| 121 | FeatureAVX512DQ | FeatureAVX512BW | FeatureAVX512VL | FeatureAVX512IFMA | |
| 122 | FeatureAVX512VBMI | FeaturePKU | FeatureSHA; |
| 123 | constexpr FeatureBitset FeaturesICLClient = |
| 124 | FeaturesCannonlake | FeatureAVX512BITALG | FeatureAVX512VBMI2 | |
| 125 | FeatureAVX512VNNI | FeatureAVX512VPOPCNTDQ | FeatureGFNI | FeatureRDPID | |
| 126 | FeatureVAES | FeatureVPCLMULQDQ; |
| 127 | constexpr FeatureBitset FeaturesRocketlake = FeaturesICLClient & ~FeatureSGX; |
| 128 | constexpr FeatureBitset FeaturesICLServer = |
| 129 | FeaturesICLClient | FeatureCLWB | FeaturePCONFIG | FeatureWBNOINVD; |
| 130 | constexpr FeatureBitset FeaturesTigerlake = |
| 131 | FeaturesICLClient | FeatureAVX512VP2INTERSECT | FeatureMOVDIR64B | |
| 132 | FeatureCLWB | FeatureMOVDIRI | FeatureSHSTK | FeatureKL | FeatureWIDEKL; |
| 133 | constexpr FeatureBitset FeaturesSapphireRapids = |
| 134 | FeaturesICLServer | FeatureAMX_BF16 | FeatureAMX_INT8 | FeatureAMX_TILE | |
| 135 | FeatureAVX512BF16 | FeatureAVX512FP16 | FeatureAVXVNNI | FeatureCLDEMOTE | |
| 136 | FeatureENQCMD | FeatureMOVDIR64B | FeatureMOVDIRI | FeaturePTWRITE | |
| 137 | FeatureSERIALIZE | FeatureSHSTK | FeatureTSXLDTRK | FeatureUINTR | |
| 138 | FeatureWAITPKG | FeatureAVX512DQ | FeatureAVX512VL; |
| 139 | constexpr FeatureBitset FeaturesGraniteRapids = |
| 140 | FeaturesSapphireRapids | FeatureAMX_FP16 | FeaturePREFETCHI; |
| 141 | constexpr FeatureBitset FeaturesDiamondRapids = |
| 142 | FeaturesGraniteRapids | FeatureAMX_COMPLEX | FeatureAVX10_2_512 | |
| 143 | FeatureCMPCCXADD | FeatureAVXIFMA | FeatureAVXNECONVERT | |
| 144 | FeatureAVXVNNIINT8 | FeatureAVXVNNIINT16 | FeatureSHA512 | FeatureSM3 | |
| 145 | FeatureSM4 | FeatureEGPR | FeatureZU | FeatureCCMP | FeaturePush2Pop2 | |
| 146 | FeaturePPX | FeatureNDD | FeatureNF | FeatureCF | FeatureMOVRS | |
| 147 | FeatureAMX_MOVRS | FeatureAMX_AVX512 | FeatureAMX_FP8 | FeatureAMX_TF32 | |
| 148 | FeatureAMX_TRANSPOSE | FeatureUSERMSR; |
| 149 | |
| 150 | // Intel Atom processors. |
| 151 | // Bonnell has feature parity with Core2 and adds MOVBE. |
| 152 | constexpr FeatureBitset FeaturesBonnell = FeaturesCore2 | FeatureMOVBE; |
| 153 | // Silvermont has parity with Westmere and Bonnell plus PRFCHW and RDRND. |
| 154 | constexpr FeatureBitset FeaturesSilvermont = |
| 155 | FeaturesBonnell | FeaturesWestmere | FeaturePRFCHW | FeatureRDRND; |
| 156 | constexpr FeatureBitset FeaturesGoldmont = |
| 157 | FeaturesSilvermont | FeatureAES | FeatureCLFLUSHOPT | FeatureFSGSBASE | |
| 158 | FeatureRDSEED | FeatureSHA | FeatureXSAVE | FeatureXSAVEC | |
| 159 | FeatureXSAVEOPT | FeatureXSAVES; |
| 160 | constexpr FeatureBitset FeaturesGoldmontPlus = |
| 161 | FeaturesGoldmont | FeaturePTWRITE | FeatureRDPID | FeatureSGX; |
| 162 | constexpr FeatureBitset FeaturesTremont = |
| 163 | FeaturesGoldmontPlus | FeatureCLWB | FeatureGFNI; |
| 164 | constexpr FeatureBitset FeaturesAlderlake = |
| 165 | FeaturesTremont | FeatureADX | FeatureBMI | FeatureBMI2 | FeatureF16C | |
| 166 | FeatureFMA | FeatureINVPCID | FeatureLZCNT | FeaturePCONFIG | FeaturePKU | |
| 167 | FeatureSERIALIZE | FeatureSHSTK | FeatureVAES | FeatureVPCLMULQDQ | |
| 168 | FeatureMOVDIR64B | FeatureMOVDIRI | FeatureWAITPKG | FeatureAVXVNNI | |
| 169 | FeatureHRESET | FeatureWIDEKL; |
| 170 | constexpr FeatureBitset FeaturesArrowlake = |
| 171 | FeaturesAlderlake | FeatureCMPCCXADD | FeatureAVXIFMA | FeatureUINTR | |
| 172 | FeatureENQCMD | FeatureAVXNECONVERT | FeatureAVXVNNIINT8; |
| 173 | constexpr FeatureBitset FeaturesSierraforest = |
| 174 | FeaturesArrowlake | FeatureCLDEMOTE; |
| 175 | constexpr FeatureBitset FeaturesArrowlakeS = |
| 176 | FeaturesArrowlake | FeatureAVXVNNIINT16 | FeatureSHA512 | FeatureSM3 | |
| 177 | FeatureSM4; |
| 178 | constexpr FeatureBitset FeaturesPantherlake = |
| 179 | FeaturesArrowlakeS | FeaturePREFETCHI; |
| 180 | constexpr FeatureBitset FeaturesClearwaterforest = |
| 181 | FeaturesSierraforest | FeatureAVXVNNIINT16 | FeatureSHA512 | FeatureSM3 | |
| 182 | FeatureSM4 | FeaturePREFETCHI | FeatureUSERMSR; |
| 183 | |
| 184 | // Geode Processor. |
| 185 | constexpr FeatureBitset FeaturesGeode = |
| 186 | FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | FeaturePRFCHW; |
| 187 | |
| 188 | // K6 processor. |
| 189 | constexpr FeatureBitset FeaturesK6 = FeatureX87 | FeatureCMPXCHG8B | FeatureMMX; |
| 190 | |
| 191 | // K7 and K8 architecture processors. |
| 192 | constexpr FeatureBitset FeaturesAthlon = |
| 193 | FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | FeaturePRFCHW; |
| 194 | constexpr FeatureBitset FeaturesAthlonXP = |
| 195 | FeaturesAthlon | FeatureFXSR | FeatureSSE; |
| 196 | constexpr FeatureBitset FeaturesK8 = |
| 197 | FeaturesAthlonXP | FeatureSSE2 | Feature64BIT; |
| 198 | constexpr FeatureBitset FeaturesK8SSE3 = FeaturesK8 | FeatureSSE3; |
| 199 | constexpr FeatureBitset FeaturesAMDFAM10 = |
| 200 | FeaturesK8SSE3 | FeatureCMPXCHG16B | FeatureLZCNT | FeaturePOPCNT | |
| 201 | FeaturePRFCHW | FeatureSAHF | FeatureSSE4_A; |
| 202 | |
| 203 | // Bobcat architecture processors. |
| 204 | constexpr FeatureBitset FeaturesBTVER1 = |
| 205 | FeatureX87 | FeatureCMPXCHG8B | FeatureCMPXCHG16B | Feature64BIT | |
| 206 | FeatureFXSR | FeatureLZCNT | FeatureMMX | FeaturePOPCNT | FeaturePRFCHW | |
| 207 | FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_A | |
| 208 | FeatureSAHF; |
| 209 | constexpr FeatureBitset FeaturesBTVER2 = |
| 210 | FeaturesBTVER1 | FeatureAES | FeatureAVX | FeatureBMI | FeatureCRC32 | |
| 211 | FeatureF16C | FeatureMOVBE | FeaturePCLMUL | FeatureXSAVE | FeatureXSAVEOPT; |
| 212 | |
| 213 | // AMD Bulldozer architecture processors. |
| 214 | constexpr FeatureBitset FeaturesBDVER1 = |
| 215 | FeatureX87 | FeatureAES | FeatureAVX | FeatureCMPXCHG8B | |
| 216 | FeatureCMPXCHG16B | FeatureCRC32 | Feature64BIT | FeatureFMA4 | |
| 217 | FeatureFXSR | FeatureLWP | FeatureLZCNT | FeatureMMX | FeaturePCLMUL | |
| 218 | FeaturePOPCNT | FeaturePRFCHW | FeatureSAHF | FeatureSSE | FeatureSSE2 | |
| 219 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 | FeatureSSE4_2 | FeatureSSE4_A | |
| 220 | FeatureXOP | FeatureXSAVE; |
| 221 | constexpr FeatureBitset FeaturesBDVER2 = |
| 222 | FeaturesBDVER1 | FeatureBMI | FeatureFMA | FeatureF16C | FeatureTBM; |
| 223 | constexpr FeatureBitset FeaturesBDVER3 = |
| 224 | FeaturesBDVER2 | FeatureFSGSBASE | FeatureXSAVEOPT; |
| 225 | constexpr FeatureBitset FeaturesBDVER4 = FeaturesBDVER3 | FeatureAVX2 | |
| 226 | FeatureBMI2 | FeatureMOVBE | |
| 227 | FeatureMWAITX | FeatureRDRND; |
| 228 | |
| 229 | // AMD Zen architecture processors. |
| 230 | constexpr FeatureBitset FeaturesZNVER1 = |
| 231 | FeatureX87 | FeatureADX | FeatureAES | FeatureAVX | FeatureAVX2 | |
| 232 | FeatureBMI | FeatureBMI2 | FeatureCLFLUSHOPT | FeatureCLZERO | |
| 233 | FeatureCMPXCHG8B | FeatureCMPXCHG16B | FeatureCRC32 | Feature64BIT | |
| 234 | FeatureF16C | FeatureFMA | FeatureFSGSBASE | FeatureFXSR | FeatureLZCNT | |
| 235 | FeatureMMX | FeatureMOVBE | FeatureMWAITX | FeaturePCLMUL | FeaturePOPCNT | |
| 236 | FeaturePRFCHW | FeatureRDRND | FeatureRDSEED | FeatureSAHF | FeatureSHA | |
| 237 | FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 | |
| 238 | FeatureSSE4_2 | FeatureSSE4_A | FeatureXSAVE | FeatureXSAVEC | |
| 239 | FeatureXSAVEOPT | FeatureXSAVES; |
| 240 | constexpr FeatureBitset FeaturesZNVER2 = FeaturesZNVER1 | FeatureCLWB | |
| 241 | FeatureRDPID | FeatureRDPRU | |
| 242 | FeatureWBNOINVD; |
| 243 | static constexpr FeatureBitset FeaturesZNVER3 = FeaturesZNVER2 | |
| 244 | FeatureINVPCID | FeaturePKU | |
| 245 | FeatureVAES | FeatureVPCLMULQDQ; |
| 246 | static constexpr FeatureBitset FeaturesZNVER4 = |
| 247 | FeaturesZNVER3 | FeatureAVX512F | FeatureEVEX512 | FeatureAVX512CD | |
| 248 | FeatureAVX512DQ | FeatureAVX512BW | FeatureAVX512VL | FeatureAVX512IFMA | |
| 249 | FeatureAVX512VBMI | FeatureAVX512VBMI2 | FeatureAVX512VNNI | |
| 250 | FeatureAVX512BITALG | FeatureAVX512VPOPCNTDQ | FeatureAVX512BF16 | |
| 251 | FeatureGFNI | FeatureSHSTK; |
| 252 | |
| 253 | static constexpr FeatureBitset FeaturesZNVER5 = |
| 254 | FeaturesZNVER4 | FeatureAVXVNNI | FeatureMOVDIRI | FeatureMOVDIR64B | |
| 255 | FeatureAVX512VP2INTERSECT | FeaturePREFETCHI | FeatureAVXVNNI; |
| 256 | |
| 257 | // D151696 tranplanted Mangling and OnlyForCPUDispatchSpecific from |
| 258 | // X86TargetParser.def to here. They are assigned by following ways: |
| 259 | // 1. Copy the mangling from the original CPU_SPEICIFC MACROs. If no, assign |
| 260 | // to '\0' by default, which means not support cpu_specific/dispatch feature. |
| 261 | // 2. set OnlyForCPUDispatchSpecific as true if this cpu name was not |
| 262 | // listed here before, which means it doesn't support -march, -mtune and so on. |
| 263 | // FIXME: Remove OnlyForCPUDispatchSpecific after all CPUs here support both |
| 264 | // cpu_dispatch/specific() feature and -march, -mtune, and so on. |
| 265 | // clang-format off |
| 266 | constexpr ProcInfo Processors[] = { |
| 267 | // Empty processor. Include X87 and CMPXCHG8 for backwards compatibility. |
| 268 | { .Name: {"" }, .Kind: CK_None, .KeyFeature: ~0U, .Features: FeatureX87 | FeatureCMPXCHG8B, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 269 | { .Name: {"generic" }, .Kind: CK_None, .KeyFeature: ~0U, .Features: FeatureX87 | FeatureCMPXCHG8B | Feature64BIT, .Mangling: 'A', .OnlyForCPUDispatchSpecific: true }, |
| 270 | // i386-generation processors. |
| 271 | { .Name: {"i386" }, .Kind: CK_i386, .KeyFeature: ~0U, .Features: FeatureX87, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 272 | // i486-generation processors. |
| 273 | { .Name: {"i486" }, .Kind: CK_i486, .KeyFeature: ~0U, .Features: FeatureX87, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 274 | { .Name: {"winchip-c6" }, .Kind: CK_WinChipC6, .KeyFeature: ~0U, .Features: FeaturesPentiumMMX, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 275 | { .Name: {"winchip2" }, .Kind: CK_WinChip2, .KeyFeature: ~0U, .Features: FeaturesPentiumMMX | FeaturePRFCHW, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 276 | { .Name: {"c3" }, .Kind: CK_C3, .KeyFeature: ~0U, .Features: FeaturesPentiumMMX | FeaturePRFCHW, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 277 | // i586-generation processors, P5 microarchitecture based. |
| 278 | { .Name: {"i586" }, .Kind: CK_i586, .KeyFeature: ~0U, .Features: FeatureX87 | FeatureCMPXCHG8B, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 279 | { .Name: {"pentium" }, .Kind: CK_Pentium, .KeyFeature: ~0U, .Features: FeatureX87 | FeatureCMPXCHG8B, .Mangling: 'B', .OnlyForCPUDispatchSpecific: false }, |
| 280 | { .Name: {"pentium-mmx" }, .Kind: CK_PentiumMMX, .KeyFeature: ~0U, .Features: FeaturesPentiumMMX, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 281 | { .Name: {"pentium_mmx" }, .Kind: CK_PentiumMMX, .KeyFeature: ~0U, .Features: FeaturesPentiumMMX, .Mangling: 'D', .OnlyForCPUDispatchSpecific: true }, |
| 282 | // i686-generation processors, P6 / Pentium M microarchitecture based. |
| 283 | { .Name: {"pentiumpro" }, .Kind: CK_PentiumPro, .KeyFeature: ~0U, .Features: FeatureCMOV | FeatureX87 | FeatureCMPXCHG8B, .Mangling: 'C', .OnlyForCPUDispatchSpecific: false }, |
| 284 | { .Name: {"pentium_pro" }, .Kind: CK_PentiumPro, .KeyFeature: ~0U, .Features: FeatureCMOV | FeatureX87 | FeatureCMPXCHG8B, .Mangling: 'C', .OnlyForCPUDispatchSpecific: true }, |
| 285 | { .Name: {"i686" }, .Kind: CK_i686, .KeyFeature: ~0U, .Features: FeatureCMOV | FeatureX87 | FeatureCMPXCHG8B, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 286 | { .Name: {"pentium2" }, .Kind: CK_Pentium2, .KeyFeature: ~0U, .Features: FeaturesPentium2, .Mangling: 'E', .OnlyForCPUDispatchSpecific: false }, |
| 287 | { .Name: {"pentium_ii" }, .Kind: CK_Pentium2, .KeyFeature: ~0U, .Features: FeaturesPentium2, .Mangling: 'E', .OnlyForCPUDispatchSpecific: true }, |
| 288 | { .Name: {"pentium3" }, .Kind: CK_Pentium3, .KeyFeature: ~0U, .Features: FeaturesPentium3, .Mangling: 'H', .OnlyForCPUDispatchSpecific: false }, |
| 289 | { .Name: {"pentium3m" }, .Kind: CK_Pentium3, .KeyFeature: ~0U, .Features: FeaturesPentium3, .Mangling: 'H', .OnlyForCPUDispatchSpecific: false }, |
| 290 | { .Name: {"pentium_iii" }, .Kind: CK_Pentium3, .KeyFeature: ~0U, .Features: FeaturesPentium3, .Mangling: 'H', .OnlyForCPUDispatchSpecific: true }, |
| 291 | { .Name: {"pentium_iii_no_xmm_regs" }, .Kind: CK_Pentium3, .KeyFeature: ~0U, .Features: FeaturesPentium3, .Mangling: 'H', .OnlyForCPUDispatchSpecific: true }, |
| 292 | { .Name: {"pentium-m" }, .Kind: CK_PentiumM, .KeyFeature: ~0U, .Features: FeaturesPentium4, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 293 | { .Name: {"pentium_m" }, .Kind: CK_PentiumM, .KeyFeature: ~0U, .Features: FeaturesPentium4, .Mangling: 'K', .OnlyForCPUDispatchSpecific: true }, |
| 294 | { .Name: {"c3-2" }, .Kind: CK_C3_2, .KeyFeature: ~0U, .Features: FeaturesPentium3, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 295 | { .Name: {"yonah" }, .Kind: CK_Yonah, .KeyFeature: ~0U, .Features: FeaturesPrescott, .Mangling: 'L', .OnlyForCPUDispatchSpecific: false }, |
| 296 | // Netburst microarchitecture based processors. |
| 297 | { .Name: {"pentium4" }, .Kind: CK_Pentium4, .KeyFeature: ~0U, .Features: FeaturesPentium4, .Mangling: 'J', .OnlyForCPUDispatchSpecific: false }, |
| 298 | { .Name: {"pentium4m" }, .Kind: CK_Pentium4, .KeyFeature: ~0U, .Features: FeaturesPentium4, .Mangling: 'J', .OnlyForCPUDispatchSpecific: false }, |
| 299 | { .Name: {"pentium_4" }, .Kind: CK_Pentium4, .KeyFeature: ~0U, .Features: FeaturesPentium4, .Mangling: 'J', .OnlyForCPUDispatchSpecific: true }, |
| 300 | { .Name: {"pentium_4_sse3" }, .Kind: CK_Prescott, .KeyFeature: ~0U, .Features: FeaturesPrescott, .Mangling: 'L', .OnlyForCPUDispatchSpecific: true }, |
| 301 | { .Name: {"prescott" }, .Kind: CK_Prescott, .KeyFeature: ~0U, .Features: FeaturesPrescott, .Mangling: 'L', .OnlyForCPUDispatchSpecific: false }, |
| 302 | { .Name: {"nocona" }, .Kind: CK_Nocona, .KeyFeature: ~0U, .Features: FeaturesNocona, .Mangling: 'L', .OnlyForCPUDispatchSpecific: false }, |
| 303 | // Core microarchitecture based processors. |
| 304 | { .Name: {"core2" }, .Kind: CK_Core2, .KeyFeature: FEATURE_SSSE3, .Features: FeaturesCore2, .Mangling: 'M', .OnlyForCPUDispatchSpecific: false }, |
| 305 | { .Name: {"core_2_duo_ssse3" }, .Kind: CK_Core2, .KeyFeature: ~0U, .Features: FeaturesCore2, .Mangling: 'M', .OnlyForCPUDispatchSpecific: true }, |
| 306 | { .Name: {"penryn" }, .Kind: CK_Penryn, .KeyFeature: ~0U, .Features: FeaturesPenryn, .Mangling: 'N', .OnlyForCPUDispatchSpecific: false }, |
| 307 | { .Name: {"core_2_duo_sse4_1" }, .Kind: CK_Penryn, .KeyFeature: ~0U, .Features: FeaturesPenryn, .Mangling: 'N', .OnlyForCPUDispatchSpecific: true }, |
| 308 | // Atom processors |
| 309 | { .Name: {"bonnell" }, .Kind: CK_Bonnell, .KeyFeature: FEATURE_SSSE3, .Features: FeaturesBonnell, .Mangling: 'O', .OnlyForCPUDispatchSpecific: false }, |
| 310 | { .Name: {"atom" }, .Kind: CK_Bonnell, .KeyFeature: FEATURE_SSSE3, .Features: FeaturesBonnell, .Mangling: 'O', .OnlyForCPUDispatchSpecific: false }, |
| 311 | { .Name: {"silvermont" }, .Kind: CK_Silvermont, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesSilvermont, .Mangling: 'c', .OnlyForCPUDispatchSpecific: false }, |
| 312 | { .Name: {"slm" }, .Kind: CK_Silvermont, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesSilvermont, .Mangling: 'c', .OnlyForCPUDispatchSpecific: false }, |
| 313 | { .Name: {"atom_sse4_2" }, .Kind: CK_Nehalem, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesNehalem, .Mangling: 'c', .OnlyForCPUDispatchSpecific: true }, |
| 314 | { .Name: {"atom_sse4_2_movbe" }, .Kind: CK_Goldmont, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesGoldmont, .Mangling: 'd', .OnlyForCPUDispatchSpecific: true }, |
| 315 | { .Name: {"goldmont" }, .Kind: CK_Goldmont, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesGoldmont, .Mangling: 'i', .OnlyForCPUDispatchSpecific: false }, |
| 316 | { .Name: {"goldmont-plus" }, .Kind: CK_GoldmontPlus, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesGoldmontPlus, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 317 | { .Name: {"goldmont_plus" }, .Kind: CK_GoldmontPlus, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesGoldmontPlus, .Mangling: 'd', .OnlyForCPUDispatchSpecific: true }, |
| 318 | { .Name: {"tremont" }, .Kind: CK_Tremont, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesTremont, .Mangling: 'd', .OnlyForCPUDispatchSpecific: false }, |
| 319 | // Nehalem microarchitecture based processors. |
| 320 | { .Name: {"nehalem" }, .Kind: CK_Nehalem, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesNehalem, .Mangling: 'P', .OnlyForCPUDispatchSpecific: false }, |
| 321 | { .Name: {"core_i7_sse4_2" }, .Kind: CK_Nehalem, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesNehalem, .Mangling: 'P', .OnlyForCPUDispatchSpecific: true }, |
| 322 | { .Name: {"corei7" }, .Kind: CK_Nehalem, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesNehalem, .Mangling: 'P', .OnlyForCPUDispatchSpecific: false }, |
| 323 | // Westmere microarchitecture based processors. |
| 324 | { .Name: {"westmere" }, .Kind: CK_Westmere, .KeyFeature: FEATURE_PCLMUL, .Features: FeaturesWestmere, .Mangling: 'Q', .OnlyForCPUDispatchSpecific: false }, |
| 325 | { .Name: {"core_aes_pclmulqdq" }, .Kind: CK_Nehalem, .KeyFeature: FEATURE_SSE4_2, .Features: FeaturesNehalem, .Mangling: 'Q', .OnlyForCPUDispatchSpecific: true }, |
| 326 | // Sandy Bridge microarchitecture based processors. |
| 327 | { .Name: {"sandybridge" }, .Kind: CK_SandyBridge, .KeyFeature: FEATURE_AVX, .Features: FeaturesSandyBridge, .Mangling: 'R', .OnlyForCPUDispatchSpecific: false }, |
| 328 | { .Name: {"core_2nd_gen_avx" }, .Kind: CK_SandyBridge, .KeyFeature: FEATURE_AVX, .Features: FeaturesSandyBridge, .Mangling: 'R', .OnlyForCPUDispatchSpecific: true }, |
| 329 | { .Name: {"corei7-avx" }, .Kind: CK_SandyBridge, .KeyFeature: FEATURE_AVX, .Features: FeaturesSandyBridge, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 330 | // Ivy Bridge microarchitecture based processors. |
| 331 | { .Name: {"ivybridge" }, .Kind: CK_IvyBridge, .KeyFeature: FEATURE_AVX, .Features: FeaturesIvyBridge, .Mangling: 'S', .OnlyForCPUDispatchSpecific: false }, |
| 332 | { .Name: {"core_3rd_gen_avx" }, .Kind: CK_IvyBridge, .KeyFeature: FEATURE_AVX, .Features: FeaturesIvyBridge, .Mangling: 'S', .OnlyForCPUDispatchSpecific: true }, |
| 333 | { .Name: {"core-avx-i" }, .Kind: CK_IvyBridge, .KeyFeature: FEATURE_AVX, .Features: FeaturesIvyBridge, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 334 | // Haswell microarchitecture based processors. |
| 335 | { .Name: {"haswell" }, .Kind: CK_Haswell, .KeyFeature: FEATURE_AVX2, .Features: FeaturesHaswell, .Mangling: 'V', .OnlyForCPUDispatchSpecific: false }, |
| 336 | { .Name: {"core-avx2" }, .Kind: CK_Haswell, .KeyFeature: FEATURE_AVX2, .Features: FeaturesHaswell, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 337 | { .Name: {"core_4th_gen_avx" }, .Kind: CK_Haswell, .KeyFeature: FEATURE_AVX2, .Features: FeaturesHaswell, .Mangling: 'V', .OnlyForCPUDispatchSpecific: true }, |
| 338 | { .Name: {"core_4th_gen_avx_tsx" }, .Kind: CK_Haswell, .KeyFeature: FEATURE_AVX2, .Features: FeaturesHaswell, .Mangling: 'W', .OnlyForCPUDispatchSpecific: true }, |
| 339 | // Broadwell microarchitecture based processors. |
| 340 | { .Name: {"broadwell" }, .Kind: CK_Broadwell, .KeyFeature: FEATURE_AVX2, .Features: FeaturesBroadwell, .Mangling: 'X', .OnlyForCPUDispatchSpecific: false }, |
| 341 | { .Name: {"core_5th_gen_avx" }, .Kind: CK_Broadwell, .KeyFeature: FEATURE_AVX2, .Features: FeaturesBroadwell, .Mangling: 'X', .OnlyForCPUDispatchSpecific: true }, |
| 342 | { .Name: {"core_5th_gen_avx_tsx" }, .Kind: CK_Broadwell, .KeyFeature: FEATURE_AVX2, .Features: FeaturesBroadwell, .Mangling: 'Y', .OnlyForCPUDispatchSpecific: true }, |
| 343 | // Skylake client microarchitecture based processors. |
| 344 | { .Name: {"skylake" }, .Kind: CK_SkylakeClient, .KeyFeature: FEATURE_AVX2, .Features: FeaturesSkylakeClient, .Mangling: 'b', .OnlyForCPUDispatchSpecific: false }, |
| 345 | // Skylake server microarchitecture based processors. |
| 346 | { .Name: {"skylake-avx512" }, .Kind: CK_SkylakeServer, .KeyFeature: FEATURE_AVX512F, .Features: FeaturesSkylakeServer, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 347 | { .Name: {"skx" }, .Kind: CK_SkylakeServer, .KeyFeature: FEATURE_AVX512F, .Features: FeaturesSkylakeServer, .Mangling: 'a', .OnlyForCPUDispatchSpecific: false }, |
| 348 | { .Name: {"skylake_avx512" }, .Kind: CK_SkylakeServer, .KeyFeature: FEATURE_AVX512F, .Features: FeaturesSkylakeServer, .Mangling: 'a', .OnlyForCPUDispatchSpecific: true }, |
| 349 | // Cascadelake Server microarchitecture based processors. |
| 350 | { .Name: {"cascadelake" }, .Kind: CK_Cascadelake, .KeyFeature: FEATURE_AVX512VNNI, .Features: FeaturesCascadeLake, .Mangling: 'o', .OnlyForCPUDispatchSpecific: false }, |
| 351 | // Cooperlake Server microarchitecture based processors. |
| 352 | { .Name: {"cooperlake" }, .Kind: CK_Cooperlake, .KeyFeature: FEATURE_AVX512BF16, .Features: FeaturesCooperLake, .Mangling: 'f', .OnlyForCPUDispatchSpecific: false }, |
| 353 | // Cannonlake client microarchitecture based processors. |
| 354 | { .Name: {"cannonlake" }, .Kind: CK_Cannonlake, .KeyFeature: FEATURE_AVX512VBMI, .Features: FeaturesCannonlake, .Mangling: 'e', .OnlyForCPUDispatchSpecific: false }, |
| 355 | // Icelake client microarchitecture based processors. |
| 356 | { .Name: {"icelake-client" }, .Kind: CK_IcelakeClient, .KeyFeature: FEATURE_AVX512VBMI2, .Features: FeaturesICLClient, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 357 | { .Name: {"icelake_client" }, .Kind: CK_IcelakeClient, .KeyFeature: FEATURE_AVX512VBMI2, .Features: FeaturesICLClient, .Mangling: 'k', .OnlyForCPUDispatchSpecific: true }, |
| 358 | // Rocketlake microarchitecture based processors. |
| 359 | { .Name: {"rocketlake" }, .Kind: CK_Rocketlake, .KeyFeature: FEATURE_AVX512VBMI2, .Features: FeaturesRocketlake, .Mangling: 'k', .OnlyForCPUDispatchSpecific: false }, |
| 360 | // Icelake server microarchitecture based processors. |
| 361 | { .Name: {"icelake-server" }, .Kind: CK_IcelakeServer, .KeyFeature: FEATURE_AVX512VBMI2, .Features: FeaturesICLServer, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 362 | { .Name: {"icelake_server" }, .Kind: CK_IcelakeServer, .KeyFeature: FEATURE_AVX512VBMI2, .Features: FeaturesICLServer, .Mangling: 'k', .OnlyForCPUDispatchSpecific: true }, |
| 363 | // Tigerlake microarchitecture based processors. |
| 364 | { .Name: {"tigerlake" }, .Kind: CK_Tigerlake, .KeyFeature: FEATURE_AVX512VP2INTERSECT, .Features: FeaturesTigerlake, .Mangling: 'l', .OnlyForCPUDispatchSpecific: false }, |
| 365 | // Sapphire Rapids microarchitecture based processors. |
| 366 | { .Name: {"sapphirerapids" }, .Kind: CK_SapphireRapids, .KeyFeature: FEATURE_AVX512FP16, .Features: FeaturesSapphireRapids, .Mangling: 'n', .OnlyForCPUDispatchSpecific: false }, |
| 367 | // Alderlake microarchitecture based processors. |
| 368 | { .Name: {"alderlake" }, .Kind: CK_Alderlake, .KeyFeature: FEATURE_AVX2, .Features: FeaturesAlderlake, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 369 | // Raptorlake microarchitecture based processors. |
| 370 | { .Name: {"raptorlake" }, .Kind: CK_Raptorlake, .KeyFeature: FEATURE_AVX2, .Features: FeaturesAlderlake, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 371 | // Meteorlake microarchitecture based processors. |
| 372 | { .Name: {"meteorlake" }, .Kind: CK_Meteorlake, .KeyFeature: FEATURE_AVX2, .Features: FeaturesAlderlake, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 373 | // Arrowlake microarchitecture based processors. |
| 374 | { .Name: {"arrowlake" }, .Kind: CK_Arrowlake, .KeyFeature: FEATURE_AVX2, .Features: FeaturesArrowlake, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 375 | { .Name: {"arrowlake-s" }, .Kind: CK_ArrowlakeS, .KeyFeature: FEATURE_AVX2, .Features: FeaturesArrowlakeS, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 376 | { .Name: {"arrowlake_s" }, .Kind: CK_ArrowlakeS, .KeyFeature: FEATURE_AVX2, .Features: FeaturesArrowlakeS, .Mangling: 'p', .OnlyForCPUDispatchSpecific: true }, |
| 377 | // Lunarlake microarchitecture based processors. |
| 378 | { .Name: {"lunarlake" }, .Kind: CK_Lunarlake, .KeyFeature: FEATURE_AVX2, .Features: FeaturesArrowlakeS, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 379 | // Gracemont microarchitecture based processors. |
| 380 | { .Name: {"gracemont" }, .Kind: CK_Gracemont, .KeyFeature: FEATURE_AVX2, .Features: FeaturesAlderlake, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 381 | // Pantherlake microarchitecture based processors. |
| 382 | { .Name: {"pantherlake" }, .Kind: CK_Lunarlake, .KeyFeature: FEATURE_AVX2, .Features: FeaturesPantherlake, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 383 | // Sierraforest microarchitecture based processors. |
| 384 | { .Name: {"sierraforest" }, .Kind: CK_Sierraforest, .KeyFeature: FEATURE_AVX2, .Features: FeaturesSierraforest, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 385 | // Grandridge microarchitecture based processors. |
| 386 | { .Name: {"grandridge" }, .Kind: CK_Grandridge, .KeyFeature: FEATURE_AVX2, .Features: FeaturesSierraforest, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 387 | // Granite Rapids microarchitecture based processors. |
| 388 | { .Name: {"graniterapids" }, .Kind: CK_Graniterapids, .KeyFeature: FEATURE_AVX512FP16, .Features: FeaturesGraniteRapids, .Mangling: 'n', .OnlyForCPUDispatchSpecific: false }, |
| 389 | // Granite Rapids D microarchitecture based processors. |
| 390 | { .Name: {"graniterapids-d" }, .Kind: CK_GraniterapidsD, .KeyFeature: FEATURE_AVX512FP16, .Features: FeaturesGraniteRapids | FeatureAMX_COMPLEX, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 391 | { .Name: {"graniterapids_d" }, .Kind: CK_GraniterapidsD, .KeyFeature: FEATURE_AVX512FP16, .Features: FeaturesGraniteRapids | FeatureAMX_COMPLEX, .Mangling: 'n', .OnlyForCPUDispatchSpecific: true }, |
| 392 | // Emerald Rapids microarchitecture based processors. |
| 393 | { .Name: {"emeraldrapids" }, .Kind: CK_Emeraldrapids, .KeyFeature: FEATURE_AVX512FP16, .Features: FeaturesSapphireRapids, .Mangling: 'n', .OnlyForCPUDispatchSpecific: false }, |
| 394 | // Clearwaterforest microarchitecture based processors. |
| 395 | { .Name: {"clearwaterforest" }, .Kind: CK_Lunarlake, .KeyFeature: FEATURE_AVX2, .Features: FeaturesClearwaterforest, .Mangling: 'p', .OnlyForCPUDispatchSpecific: false }, |
| 396 | // Diamond Rapids microarchitecture based processors. |
| 397 | { .Name: {"diamondrapids" }, .Kind: CK_Diamondrapids, .KeyFeature: FEATURE_AVX10_2_512, .Features: FeaturesDiamondRapids, .Mangling: 'z', .OnlyForCPUDispatchSpecific: false }, |
| 398 | // Knights Landing processor. |
| 399 | { .Name: {"knl" }, .Kind: CK_KNL, .KeyFeature: FEATURE_AVX512F, .Features: FeaturesKNL, .Mangling: 'Z', .OnlyForCPUDispatchSpecific: false }, |
| 400 | { .Name: {"mic_avx512" }, .Kind: CK_KNL, .KeyFeature: FEATURE_AVX512F, .Features: FeaturesKNL, .Mangling: 'Z', .OnlyForCPUDispatchSpecific: true }, |
| 401 | // Knights Mill processor. |
| 402 | { .Name: {"knm" }, .Kind: CK_KNM, .KeyFeature: FEATURE_AVX5124FMAPS, .Features: FeaturesKNM, .Mangling: 'j', .OnlyForCPUDispatchSpecific: false }, |
| 403 | // Lakemont microarchitecture based processors. |
| 404 | { .Name: {"lakemont" }, .Kind: CK_Lakemont, .KeyFeature: ~0U, .Features: FeatureCMPXCHG8B, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 405 | // K6 architecture processors. |
| 406 | { .Name: {"k6" }, .Kind: CK_K6, .KeyFeature: ~0U, .Features: FeaturesK6, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 407 | { .Name: {"k6-2" }, .Kind: CK_K6_2, .KeyFeature: ~0U, .Features: FeaturesK6 | FeaturePRFCHW, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 408 | { .Name: {"k6-3" }, .Kind: CK_K6_3, .KeyFeature: ~0U, .Features: FeaturesK6 | FeaturePRFCHW, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 409 | // K7 architecture processors. |
| 410 | { .Name: {"athlon" }, .Kind: CK_Athlon, .KeyFeature: ~0U, .Features: FeaturesAthlon, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 411 | { .Name: {"athlon-tbird" }, .Kind: CK_Athlon, .KeyFeature: ~0U, .Features: FeaturesAthlon, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 412 | { .Name: {"athlon-xp" }, .Kind: CK_AthlonXP, .KeyFeature: ~0U, .Features: FeaturesAthlonXP, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 413 | { .Name: {"athlon-mp" }, .Kind: CK_AthlonXP, .KeyFeature: ~0U, .Features: FeaturesAthlonXP, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 414 | { .Name: {"athlon-4" }, .Kind: CK_AthlonXP, .KeyFeature: ~0U, .Features: FeaturesAthlonXP, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 415 | // K8 architecture processors. |
| 416 | { .Name: {"k8" }, .Kind: CK_K8, .KeyFeature: ~0U, .Features: FeaturesK8, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 417 | { .Name: {"athlon64" }, .Kind: CK_K8, .KeyFeature: ~0U, .Features: FeaturesK8, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 418 | { .Name: {"athlon-fx" }, .Kind: CK_K8, .KeyFeature: ~0U, .Features: FeaturesK8, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 419 | { .Name: {"opteron" }, .Kind: CK_K8, .KeyFeature: ~0U, .Features: FeaturesK8, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 420 | { .Name: {"k8-sse3" }, .Kind: CK_K8SSE3, .KeyFeature: ~0U, .Features: FeaturesK8SSE3, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 421 | { .Name: {"athlon64-sse3" }, .Kind: CK_K8SSE3, .KeyFeature: ~0U, .Features: FeaturesK8SSE3, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 422 | { .Name: {"opteron-sse3" }, .Kind: CK_K8SSE3, .KeyFeature: ~0U, .Features: FeaturesK8SSE3, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 423 | { .Name: {"amdfam10" }, .Kind: CK_AMDFAM10, .KeyFeature: FEATURE_SSE4_A, .Features: FeaturesAMDFAM10, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 424 | { .Name: {"barcelona" }, .Kind: CK_AMDFAM10, .KeyFeature: FEATURE_SSE4_A, .Features: FeaturesAMDFAM10, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 425 | // Bobcat architecture processors. |
| 426 | { .Name: {"btver1" }, .Kind: CK_BTVER1, .KeyFeature: FEATURE_SSE4_A, .Features: FeaturesBTVER1, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 427 | { .Name: {"btver2" }, .Kind: CK_BTVER2, .KeyFeature: FEATURE_BMI, .Features: FeaturesBTVER2, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 428 | // Bulldozer architecture processors. |
| 429 | { .Name: {"bdver1" }, .Kind: CK_BDVER1, .KeyFeature: FEATURE_XOP, .Features: FeaturesBDVER1, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 430 | { .Name: {"bdver2" }, .Kind: CK_BDVER2, .KeyFeature: FEATURE_FMA, .Features: FeaturesBDVER2, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 431 | { .Name: {"bdver3" }, .Kind: CK_BDVER3, .KeyFeature: FEATURE_FMA, .Features: FeaturesBDVER3, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 432 | { .Name: {"bdver4" }, .Kind: CK_BDVER4, .KeyFeature: FEATURE_AVX2, .Features: FeaturesBDVER4, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 433 | // Zen architecture processors. |
| 434 | { .Name: {"znver1" }, .Kind: CK_ZNVER1, .KeyFeature: FEATURE_AVX2, .Features: FeaturesZNVER1, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 435 | { .Name: {"znver2" }, .Kind: CK_ZNVER2, .KeyFeature: FEATURE_AVX2, .Features: FeaturesZNVER2, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 436 | { .Name: {"znver3" }, .Kind: CK_ZNVER3, .KeyFeature: FEATURE_AVX2, .Features: FeaturesZNVER3, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 437 | { .Name: {"znver4" }, .Kind: CK_ZNVER4, .KeyFeature: FEATURE_AVX512VBMI2, .Features: FeaturesZNVER4, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 438 | { .Name: {"znver5" }, .Kind: CK_ZNVER5, .KeyFeature: FEATURE_AVX512VP2INTERSECT, .Features: FeaturesZNVER5, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 439 | // Generic 64-bit processor. |
| 440 | { .Name: {"x86-64" }, .Kind: CK_x86_64, .KeyFeature: FEATURE_SSE2 , .Features: FeaturesX86_64, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 441 | { .Name: {"x86-64-v2" }, .Kind: CK_x86_64_v2, .KeyFeature: FEATURE_SSE4_2 , .Features: FeaturesX86_64_V2, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 442 | { .Name: {"x86-64-v3" }, .Kind: CK_x86_64_v3, .KeyFeature: FEATURE_AVX2, .Features: FeaturesX86_64_V3, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 443 | { .Name: {"x86-64-v4" }, .Kind: CK_x86_64_v4, .KeyFeature: FEATURE_AVX512VL, .Features: FeaturesX86_64_V4, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 444 | // Geode processors. |
| 445 | { .Name: {"geode" }, .Kind: CK_Geode, .KeyFeature: ~0U, .Features: FeaturesGeode, .Mangling: '\0', .OnlyForCPUDispatchSpecific: false }, |
| 446 | }; |
| 447 | // clang-format on |
| 448 | |
| 449 | constexpr const char *NoTuneList[] = {"x86-64-v2" , "x86-64-v3" , "x86-64-v4" }; |
| 450 | |
| 451 | X86::CPUKind llvm::X86::parseArchX86(StringRef CPU, bool Only64Bit) { |
| 452 | for (const auto &P : Processors) |
| 453 | if (!P.OnlyForCPUDispatchSpecific && P.Name == CPU && |
| 454 | (P.Features[FEATURE_64BIT] || !Only64Bit)) |
| 455 | return P.Kind; |
| 456 | |
| 457 | return CK_None; |
| 458 | } |
| 459 | |
| 460 | X86::CPUKind llvm::X86::parseTuneCPU(StringRef CPU, bool Only64Bit) { |
| 461 | if (llvm::is_contained(Range: NoTuneList, Element: CPU)) |
| 462 | return CK_None; |
| 463 | return parseArchX86(CPU, Only64Bit); |
| 464 | } |
| 465 | |
| 466 | void llvm::X86::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, |
| 467 | bool Only64Bit) { |
| 468 | for (const auto &P : Processors) |
| 469 | if (!P.OnlyForCPUDispatchSpecific && !P.Name.empty() && |
| 470 | (P.Features[FEATURE_64BIT] || !Only64Bit)) |
| 471 | Values.emplace_back(Args: P.Name); |
| 472 | } |
| 473 | |
| 474 | void llvm::X86::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values, |
| 475 | bool Only64Bit) { |
| 476 | for (const ProcInfo &P : Processors) |
| 477 | if (!P.OnlyForCPUDispatchSpecific && !P.Name.empty() && |
| 478 | (P.Features[FEATURE_64BIT] || !Only64Bit) && |
| 479 | !llvm::is_contained(Range: NoTuneList, Element: P.Name)) |
| 480 | Values.emplace_back(Args: P.Name); |
| 481 | } |
| 482 | |
| 483 | ProcessorFeatures llvm::X86::getKeyFeature(X86::CPUKind Kind) { |
| 484 | // FIXME: Can we avoid a linear search here? The table might be sorted by |
| 485 | // CPUKind so we could binary search? |
| 486 | for (const auto &P : Processors) { |
| 487 | if (P.Kind == Kind) { |
| 488 | assert(P.KeyFeature != ~0U && "Processor does not have a key feature." ); |
| 489 | return static_cast<ProcessorFeatures>(P.KeyFeature); |
| 490 | } |
| 491 | } |
| 492 | |
| 493 | llvm_unreachable("Unable to find CPU kind!" ); |
| 494 | } |
| 495 | |
| 496 | // Features with no dependencies. |
| 497 | constexpr FeatureBitset ImpliedFeatures64BIT = {}; |
| 498 | constexpr FeatureBitset ImpliedFeaturesADX = {}; |
| 499 | constexpr FeatureBitset ImpliedFeaturesBMI = {}; |
| 500 | constexpr FeatureBitset ImpliedFeaturesBMI2 = {}; |
| 501 | constexpr FeatureBitset ImpliedFeaturesCLDEMOTE = {}; |
| 502 | constexpr FeatureBitset ImpliedFeaturesCLFLUSHOPT = {}; |
| 503 | constexpr FeatureBitset ImpliedFeaturesCLWB = {}; |
| 504 | constexpr FeatureBitset ImpliedFeaturesCLZERO = {}; |
| 505 | constexpr FeatureBitset ImpliedFeaturesCMOV = {}; |
| 506 | constexpr FeatureBitset ImpliedFeaturesCMPXCHG16B = {}; |
| 507 | constexpr FeatureBitset ImpliedFeaturesCMPXCHG8B = {}; |
| 508 | constexpr FeatureBitset ImpliedFeaturesCRC32 = {}; |
| 509 | constexpr FeatureBitset ImpliedFeaturesENQCMD = {}; |
| 510 | constexpr FeatureBitset ImpliedFeaturesFSGSBASE = {}; |
| 511 | constexpr FeatureBitset ImpliedFeaturesFXSR = {}; |
| 512 | constexpr FeatureBitset ImpliedFeaturesINVPCID = {}; |
| 513 | constexpr FeatureBitset ImpliedFeaturesLWP = {}; |
| 514 | constexpr FeatureBitset ImpliedFeaturesLZCNT = {}; |
| 515 | constexpr FeatureBitset ImpliedFeaturesMMX = {}; |
| 516 | constexpr FeatureBitset ImpliedFeaturesMWAITX = {}; |
| 517 | constexpr FeatureBitset ImpliedFeaturesMOVBE = {}; |
| 518 | constexpr FeatureBitset ImpliedFeaturesMOVDIR64B = {}; |
| 519 | constexpr FeatureBitset ImpliedFeaturesMOVDIRI = {}; |
| 520 | constexpr FeatureBitset ImpliedFeaturesPCONFIG = {}; |
| 521 | constexpr FeatureBitset ImpliedFeaturesPOPCNT = {}; |
| 522 | constexpr FeatureBitset ImpliedFeaturesPKU = {}; |
| 523 | constexpr FeatureBitset ImpliedFeaturesPRFCHW = {}; |
| 524 | constexpr FeatureBitset ImpliedFeaturesPTWRITE = {}; |
| 525 | constexpr FeatureBitset ImpliedFeaturesRDPID = {}; |
| 526 | constexpr FeatureBitset ImpliedFeaturesRDPRU = {}; |
| 527 | constexpr FeatureBitset ImpliedFeaturesRDRND = {}; |
| 528 | constexpr FeatureBitset ImpliedFeaturesRDSEED = {}; |
| 529 | constexpr FeatureBitset ImpliedFeaturesRTM = {}; |
| 530 | constexpr FeatureBitset ImpliedFeaturesSAHF = {}; |
| 531 | constexpr FeatureBitset ImpliedFeaturesSERIALIZE = {}; |
| 532 | constexpr FeatureBitset ImpliedFeaturesSGX = {}; |
| 533 | constexpr FeatureBitset ImpliedFeaturesSHSTK = {}; |
| 534 | constexpr FeatureBitset ImpliedFeaturesTBM = {}; |
| 535 | constexpr FeatureBitset ImpliedFeaturesTSXLDTRK = {}; |
| 536 | constexpr FeatureBitset ImpliedFeaturesUINTR = {}; |
| 537 | constexpr FeatureBitset ImpliedFeaturesUSERMSR = {}; |
| 538 | constexpr FeatureBitset ImpliedFeaturesWAITPKG = {}; |
| 539 | constexpr FeatureBitset ImpliedFeaturesWBNOINVD = {}; |
| 540 | constexpr FeatureBitset ImpliedFeaturesVZEROUPPER = {}; |
| 541 | constexpr FeatureBitset ImpliedFeaturesX87 = {}; |
| 542 | constexpr FeatureBitset ImpliedFeaturesXSAVE = {}; |
| 543 | constexpr FeatureBitset ImpliedFeaturesDUMMYFEATURE1 = {}; |
| 544 | constexpr FeatureBitset ImpliedFeaturesDUMMYFEATURE2 = {}; |
| 545 | |
| 546 | // Not really CPU features, but need to be in the table because clang uses |
| 547 | // target features to communicate them to the backend. |
| 548 | constexpr FeatureBitset ImpliedFeaturesRETPOLINE_EXTERNAL_THUNK = {}; |
| 549 | constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_BRANCHES = {}; |
| 550 | constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_CALLS = {}; |
| 551 | constexpr FeatureBitset ImpliedFeaturesLVI_CFI = {}; |
| 552 | constexpr FeatureBitset ImpliedFeaturesLVI_LOAD_HARDENING = {}; |
| 553 | |
| 554 | // XSAVE features are dependent on basic XSAVE. |
| 555 | constexpr FeatureBitset ImpliedFeaturesXSAVEC = FeatureXSAVE; |
| 556 | constexpr FeatureBitset ImpliedFeaturesXSAVEOPT = FeatureXSAVE; |
| 557 | constexpr FeatureBitset ImpliedFeaturesXSAVES = FeatureXSAVE; |
| 558 | |
| 559 | // SSE/AVX/AVX512F chain. |
| 560 | constexpr FeatureBitset ImpliedFeaturesSSE = {}; |
| 561 | constexpr FeatureBitset ImpliedFeaturesSSE2 = FeatureSSE; |
| 562 | constexpr FeatureBitset ImpliedFeaturesSSE3 = FeatureSSE2; |
| 563 | constexpr FeatureBitset ImpliedFeaturesSSSE3 = FeatureSSE3; |
| 564 | constexpr FeatureBitset ImpliedFeaturesSSE4_1 = FeatureSSSE3; |
| 565 | constexpr FeatureBitset ImpliedFeaturesSSE4_2 = FeatureSSE4_1; |
| 566 | constexpr FeatureBitset ImpliedFeaturesAVX = FeatureSSE4_2; |
| 567 | constexpr FeatureBitset ImpliedFeaturesAVX2 = FeatureAVX; |
| 568 | constexpr FeatureBitset ImpliedFeaturesEVEX512 = {}; |
| 569 | constexpr FeatureBitset ImpliedFeaturesAVX512F = |
| 570 | FeatureAVX2 | FeatureF16C | FeatureFMA; |
| 571 | |
| 572 | // Vector extensions that build on SSE or AVX. |
| 573 | constexpr FeatureBitset ImpliedFeaturesAES = FeatureSSE2; |
| 574 | constexpr FeatureBitset ImpliedFeaturesF16C = FeatureAVX; |
| 575 | constexpr FeatureBitset ImpliedFeaturesFMA = FeatureAVX; |
| 576 | constexpr FeatureBitset ImpliedFeaturesGFNI = FeatureSSE2; |
| 577 | constexpr FeatureBitset ImpliedFeaturesPCLMUL = FeatureSSE2; |
| 578 | constexpr FeatureBitset ImpliedFeaturesSHA = FeatureSSE2; |
| 579 | constexpr FeatureBitset ImpliedFeaturesVAES = FeatureAES | FeatureAVX2; |
| 580 | constexpr FeatureBitset ImpliedFeaturesVPCLMULQDQ = FeatureAVX | FeaturePCLMUL; |
| 581 | constexpr FeatureBitset ImpliedFeaturesSM3 = FeatureAVX; |
| 582 | constexpr FeatureBitset ImpliedFeaturesSM4 = FeatureAVX2; |
| 583 | |
| 584 | // AVX512 features. |
| 585 | constexpr FeatureBitset ImpliedFeaturesAVX512CD = FeatureAVX512F; |
| 586 | constexpr FeatureBitset ImpliedFeaturesAVX512BW = FeatureAVX512F; |
| 587 | constexpr FeatureBitset ImpliedFeaturesAVX512DQ = FeatureAVX512F; |
| 588 | constexpr FeatureBitset ImpliedFeaturesAVX512VL = FeatureAVX512F; |
| 589 | |
| 590 | constexpr FeatureBitset ImpliedFeaturesAVX512BF16 = FeatureAVX512BW; |
| 591 | constexpr FeatureBitset ImpliedFeaturesAVX512BITALG = FeatureAVX512BW; |
| 592 | constexpr FeatureBitset ImpliedFeaturesAVX512IFMA = FeatureAVX512F; |
| 593 | constexpr FeatureBitset ImpliedFeaturesAVX512VNNI = FeatureAVX512F; |
| 594 | constexpr FeatureBitset ImpliedFeaturesAVX512VPOPCNTDQ = FeatureAVX512F; |
| 595 | constexpr FeatureBitset ImpliedFeaturesAVX512VBMI = FeatureAVX512BW; |
| 596 | constexpr FeatureBitset ImpliedFeaturesAVX512VBMI2 = FeatureAVX512BW; |
| 597 | constexpr FeatureBitset ImpliedFeaturesAVX512VP2INTERSECT = FeatureAVX512F; |
| 598 | |
| 599 | // FIXME: These two aren't really implemented and just exist in the feature |
| 600 | // list for __builtin_cpu_supports. So omit their dependencies. |
| 601 | constexpr FeatureBitset ImpliedFeaturesAVX5124FMAPS = {}; |
| 602 | constexpr FeatureBitset ImpliedFeaturesAVX5124VNNIW = {}; |
| 603 | |
| 604 | // SSE4_A->FMA4->XOP chain. |
| 605 | constexpr FeatureBitset ImpliedFeaturesSSE4_A = FeatureSSE3; |
| 606 | constexpr FeatureBitset ImpliedFeaturesFMA4 = FeatureAVX | FeatureSSE4_A; |
| 607 | constexpr FeatureBitset ImpliedFeaturesXOP = FeatureFMA4; |
| 608 | |
| 609 | // AMX Features |
| 610 | constexpr FeatureBitset ImpliedFeaturesAMX_TILE = {}; |
| 611 | constexpr FeatureBitset ImpliedFeaturesAMX_BF16 = FeatureAMX_TILE; |
| 612 | constexpr FeatureBitset ImpliedFeaturesAMX_FP16 = FeatureAMX_TILE; |
| 613 | constexpr FeatureBitset ImpliedFeaturesAMX_INT8 = FeatureAMX_TILE; |
| 614 | constexpr FeatureBitset ImpliedFeaturesAMX_COMPLEX = FeatureAMX_TILE; |
| 615 | constexpr FeatureBitset ImpliedFeaturesAMX_FP8 = FeatureAMX_TILE; |
| 616 | constexpr FeatureBitset ImpliedFeaturesAMX_TRANSPOSE = FeatureAMX_TILE; |
| 617 | constexpr FeatureBitset ImpliedFeaturesAMX_MOVRS = FeatureAMX_TILE; |
| 618 | constexpr FeatureBitset ImpliedFeaturesAMX_AVX512 = |
| 619 | FeatureAMX_TILE | FeatureAVX10_2_512; |
| 620 | constexpr FeatureBitset ImpliedFeaturesAMX_TF32 = FeatureAMX_TILE; |
| 621 | constexpr FeatureBitset ImpliedFeaturesHRESET = {}; |
| 622 | |
| 623 | constexpr FeatureBitset ImpliedFeaturesPREFETCHI = {}; |
| 624 | constexpr FeatureBitset ImpliedFeaturesCMPCCXADD = {}; |
| 625 | constexpr FeatureBitset ImpliedFeaturesRAOINT = {}; |
| 626 | constexpr FeatureBitset ImpliedFeaturesAVXVNNIINT16 = FeatureAVX2; |
| 627 | constexpr FeatureBitset ImpliedFeaturesAVXVNNIINT8 = FeatureAVX2; |
| 628 | constexpr FeatureBitset ImpliedFeaturesAVXIFMA = FeatureAVX2; |
| 629 | constexpr FeatureBitset ImpliedFeaturesAVXNECONVERT = FeatureAVX2; |
| 630 | constexpr FeatureBitset ImpliedFeaturesSHA512 = FeatureAVX2; |
| 631 | constexpr FeatureBitset ImpliedFeaturesAVX512FP16 = FeatureAVX512BW; |
| 632 | // Key Locker Features |
| 633 | constexpr FeatureBitset ImpliedFeaturesKL = FeatureSSE2; |
| 634 | constexpr FeatureBitset ImpliedFeaturesWIDEKL = FeatureKL; |
| 635 | |
| 636 | // AVXVNNI Features |
| 637 | constexpr FeatureBitset ImpliedFeaturesAVXVNNI = FeatureAVX2; |
| 638 | |
| 639 | // AVX10 Features |
| 640 | constexpr FeatureBitset ImpliedFeaturesAVX10_1 = |
| 641 | FeatureAVX512CD | FeatureAVX512VBMI | FeatureAVX512IFMA | |
| 642 | FeatureAVX512VNNI | FeatureAVX512BF16 | FeatureAVX512VPOPCNTDQ | |
| 643 | FeatureAVX512VBMI2 | FeatureAVX512BITALG | FeatureAVX512FP16 | |
| 644 | FeatureAVX512DQ | FeatureAVX512VL; |
| 645 | constexpr FeatureBitset ImpliedFeaturesAVX10_1_512 = |
| 646 | FeatureAVX10_1 | FeatureEVEX512; |
| 647 | constexpr FeatureBitset ImpliedFeaturesAVX10_2 = FeatureAVX10_1; |
| 648 | constexpr FeatureBitset ImpliedFeaturesAVX10_2_512 = |
| 649 | FeatureAVX10_2 | FeatureAVX10_1_512; |
| 650 | |
| 651 | // APX Features |
| 652 | constexpr FeatureBitset ImpliedFeaturesEGPR = {}; |
| 653 | constexpr FeatureBitset ImpliedFeaturesPush2Pop2 = {}; |
| 654 | constexpr FeatureBitset ImpliedFeaturesPPX = {}; |
| 655 | constexpr FeatureBitset ImpliedFeaturesNDD = {}; |
| 656 | constexpr FeatureBitset ImpliedFeaturesCCMP = {}; |
| 657 | constexpr FeatureBitset ImpliedFeaturesNF = {}; |
| 658 | constexpr FeatureBitset ImpliedFeaturesCF = {}; |
| 659 | constexpr FeatureBitset ImpliedFeaturesZU = {}; |
| 660 | |
| 661 | constexpr FeatureBitset ImpliedFeaturesMOVRS = {}; |
| 662 | |
| 663 | constexpr FeatureInfo FeatureInfos[X86::CPU_FEATURE_MAX] = { |
| 664 | #define X86_FEATURE(ENUM, STR) {{"+" STR}, ImpliedFeatures##ENUM}, |
| 665 | #include "llvm/TargetParser/X86TargetParser.def" |
| 666 | }; |
| 667 | |
| 668 | void llvm::X86::getFeaturesForCPU(StringRef CPU, |
| 669 | SmallVectorImpl<StringRef> &EnabledFeatures, |
| 670 | bool NeedPlus) { |
| 671 | auto I = llvm::find_if(Range: Processors, |
| 672 | P: [&](const ProcInfo &P) { return P.Name == CPU; }); |
| 673 | assert(I != std::end(Processors) && "Processor not found!" ); |
| 674 | |
| 675 | FeatureBitset Bits = I->Features; |
| 676 | |
| 677 | // Remove the 64-bit feature which we only use to validate if a CPU can |
| 678 | // be used with 64-bit mode. |
| 679 | Bits &= ~Feature64BIT; |
| 680 | |
| 681 | // Add the string version of all set bits. |
| 682 | for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i) |
| 683 | if (Bits[i] && !FeatureInfos[i].getName(WithPlus: NeedPlus).empty()) |
| 684 | EnabledFeatures.push_back(Elt: FeatureInfos[i].getName(WithPlus: NeedPlus)); |
| 685 | } |
| 686 | |
| 687 | // For each feature that is (transitively) implied by this feature, set it. |
| 688 | static void getImpliedEnabledFeatures(FeatureBitset &Bits, |
| 689 | const FeatureBitset &Implies) { |
| 690 | // Fast path: Implies is often empty. |
| 691 | if (!Implies.any()) |
| 692 | return; |
| 693 | FeatureBitset Prev; |
| 694 | Bits |= Implies; |
| 695 | do { |
| 696 | Prev = Bits; |
| 697 | for (unsigned i = CPU_FEATURE_MAX; i;) |
| 698 | if (Bits[--i]) |
| 699 | Bits |= FeatureInfos[i].ImpliedFeatures; |
| 700 | } while (Prev != Bits); |
| 701 | } |
| 702 | |
| 703 | /// Create bit vector of features that are implied disabled if the feature |
| 704 | /// passed in Value is disabled. |
| 705 | static void getImpliedDisabledFeatures(FeatureBitset &Bits, unsigned Value) { |
| 706 | // Check all features looking for any dependent on this feature. If we find |
| 707 | // one, mark it and recursively find any feature that depend on it. |
| 708 | FeatureBitset Prev; |
| 709 | Bits.set(Value); |
| 710 | do { |
| 711 | Prev = Bits; |
| 712 | for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i) |
| 713 | if ((FeatureInfos[i].ImpliedFeatures & Bits).any()) |
| 714 | Bits.set(i); |
| 715 | } while (Prev != Bits); |
| 716 | } |
| 717 | |
| 718 | void llvm::X86::updateImpliedFeatures( |
| 719 | StringRef Feature, bool Enabled, |
| 720 | StringMap<bool> &Features) { |
| 721 | auto I = llvm::find_if(Range: FeatureInfos, P: [&](const FeatureInfo &FI) { |
| 722 | return FI.getName() == Feature; |
| 723 | }); |
| 724 | if (I == std::end(arr: FeatureInfos)) { |
| 725 | // FIXME: This shouldn't happen, but may not have all features in the table |
| 726 | // yet. |
| 727 | return; |
| 728 | } |
| 729 | |
| 730 | FeatureBitset ImpliedBits; |
| 731 | if (Enabled) |
| 732 | getImpliedEnabledFeatures(Bits&: ImpliedBits, Implies: I->ImpliedFeatures); |
| 733 | else |
| 734 | getImpliedDisabledFeatures(Bits&: ImpliedBits, |
| 735 | Value: std::distance(first: std::begin(arr: FeatureInfos), last: I)); |
| 736 | |
| 737 | // Update the map entry for all implied features. |
| 738 | for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i) |
| 739 | if (ImpliedBits[i] && !FeatureInfos[i].getName().empty()) |
| 740 | Features[FeatureInfos[i].getName()] = Enabled; |
| 741 | } |
| 742 | |
| 743 | char llvm::X86::getCPUDispatchMangling(StringRef CPU) { |
| 744 | auto I = llvm::find_if(Range: Processors, |
| 745 | P: [&](const ProcInfo &P) { return P.Name == CPU; }); |
| 746 | assert(I != std::end(Processors) && "Processor not found!" ); |
| 747 | assert(I->Mangling != '\0' && "Processor dooesn't support function multiversion!" ); |
| 748 | return I->Mangling; |
| 749 | } |
| 750 | |
| 751 | bool llvm::X86::validateCPUSpecificCPUDispatch(StringRef Name) { |
| 752 | auto I = llvm::find_if(Range: Processors, |
| 753 | P: [&](const ProcInfo &P) { return P.Name == Name; }); |
| 754 | return I != std::end(arr: Processors); |
| 755 | } |
| 756 | |
| 757 | std::array<uint32_t, 4> |
| 758 | llvm::X86::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) { |
| 759 | // Processor features and mapping to processor feature value. |
| 760 | std::array<uint32_t, 4> FeatureMask{}; |
| 761 | for (StringRef FeatureStr : FeatureStrs) { |
| 762 | unsigned Feature = StringSwitch<unsigned>(FeatureStr) |
| 763 | #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \ |
| 764 | .Case(STR, llvm::X86::FEATURE_##ENUM) |
| 765 | #define X86_MICROARCH_LEVEL(ENUM, STR, PRIORITY) \ |
| 766 | .Case(STR, llvm::X86::FEATURE_##ENUM) |
| 767 | #include "llvm/TargetParser/X86TargetParser.def" |
| 768 | ; |
| 769 | assert(Feature / 32 < FeatureMask.size()); |
| 770 | FeatureMask[Feature / 32] |= 1U << (Feature % 32); |
| 771 | } |
| 772 | return FeatureMask; |
| 773 | } |
| 774 | |
| 775 | unsigned llvm::X86::getFeaturePriority(ProcessorFeatures Feat) { |
| 776 | #ifndef NDEBUG |
| 777 | // Check that priorities are set properly in the .def file. We expect that |
| 778 | // "compat" features are assigned non-duplicate consecutive priorities |
| 779 | // starting from one (1, ..., 37) and multiple zeros. |
| 780 | #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) PRIORITY, |
| 781 | unsigned Priorities[] = { |
| 782 | #include "llvm/TargetParser/X86TargetParser.def" |
| 783 | }; |
| 784 | std::array<unsigned, std::size(Priorities)> HelperList; |
| 785 | const size_t MaxPriority = 37; |
| 786 | std::iota(HelperList.begin(), HelperList.begin() + MaxPriority + 1, 0); |
| 787 | for (size_t i = MaxPriority + 1; i != std::size(Priorities); ++i) |
| 788 | HelperList[i] = 0; |
| 789 | assert(std::is_permutation(HelperList.begin(), HelperList.end(), |
| 790 | std::begin(Priorities), std::end(Priorities)) && |
| 791 | "Priorities don't form consecutive range!" ); |
| 792 | #endif |
| 793 | |
| 794 | switch (Feat) { |
| 795 | #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \ |
| 796 | case X86::FEATURE_##ENUM: \ |
| 797 | return PRIORITY; |
| 798 | #include "llvm/TargetParser/X86TargetParser.def" |
| 799 | default: |
| 800 | llvm_unreachable("No Feature Priority for non-CPUSupports Features" ); |
| 801 | } |
| 802 | } |
| 803 | |