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