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