1d5c28c40SCraig Topper //===-- X86TargetParser - Parser for X86 features ---------------*- C++ -*-===//
2d5c28c40SCraig Topper //
3d5c28c40SCraig Topper // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d5c28c40SCraig Topper // See https://llvm.org/LICENSE.txt for license information.
5d5c28c40SCraig Topper // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d5c28c40SCraig Topper //
7d5c28c40SCraig Topper //===----------------------------------------------------------------------===//
8d5c28c40SCraig Topper //
9d5c28c40SCraig Topper // This file implements a target parser to recognise X86 hardware features.
10d5c28c40SCraig Topper //
11d5c28c40SCraig Topper //===----------------------------------------------------------------------===//
12d5c28c40SCraig Topper
13d5c28c40SCraig Topper #include "llvm/Support/X86TargetParser.h"
141724a164SAndrei Elovikov #include "llvm/ADT/StringSwitch.h"
151724a164SAndrei Elovikov #include <numeric>
16d5c28c40SCraig Topper
17d5c28c40SCraig Topper using namespace llvm;
188dc92142SCraig Topper using namespace llvm::X86;
19d5c28c40SCraig Topper
208dc92142SCraig Topper namespace {
218dc92142SCraig Topper
223537939cSCraig Topper /// Container class for CPU features.
233537939cSCraig Topper /// This is a constexpr reimplementation of a subset of std::bitset. It would be
243537939cSCraig Topper /// nice to use std::bitset directly, but it doesn't support constant
253537939cSCraig Topper /// initialization.
263537939cSCraig Topper class FeatureBitset {
273537939cSCraig Topper static constexpr unsigned NUM_FEATURE_WORDS =
283537939cSCraig Topper (X86::CPU_FEATURE_MAX + 31) / 32;
293537939cSCraig Topper
303537939cSCraig Topper // This cannot be a std::array, operator[] is not constexpr until C++17.
313537939cSCraig Topper uint32_t Bits[NUM_FEATURE_WORDS] = {};
323537939cSCraig Topper
333537939cSCraig Topper public:
343537939cSCraig Topper constexpr FeatureBitset() = default;
FeatureBitset(std::initializer_list<unsigned> Init)353537939cSCraig Topper constexpr FeatureBitset(std::initializer_list<unsigned> Init) {
363537939cSCraig Topper for (auto I : Init)
373537939cSCraig Topper set(I);
383537939cSCraig Topper }
393537939cSCraig Topper
any() const400c7af8c8SFangrui Song bool any() const {
410c7af8c8SFangrui Song return llvm::any_of(Bits, [](uint64_t V) { return V != 0; });
420c7af8c8SFangrui Song }
430c7af8c8SFangrui Song
set(unsigned I)443537939cSCraig Topper constexpr FeatureBitset &set(unsigned I) {
45f40b1132SCraig Topper // GCC <6.2 crashes if this is written in a single statement.
463537939cSCraig Topper uint32_t NewBits = Bits[I / 32] | (uint32_t(1) << (I % 32));
473537939cSCraig Topper Bits[I / 32] = NewBits;
483537939cSCraig Topper return *this;
493537939cSCraig Topper }
503537939cSCraig Topper
operator [](unsigned I) const513537939cSCraig Topper constexpr bool operator[](unsigned I) const {
523537939cSCraig Topper uint32_t Mask = uint32_t(1) << (I % 32);
533537939cSCraig Topper return (Bits[I / 32] & Mask) != 0;
543537939cSCraig Topper }
553537939cSCraig Topper
operator &=(const FeatureBitset & RHS)56f40b1132SCraig Topper constexpr FeatureBitset &operator&=(const FeatureBitset &RHS) {
57f15014ffSBenjamin Kramer for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I) {
58f40b1132SCraig Topper // GCC <6.2 crashes if this is written in a single statement.
59f40b1132SCraig Topper uint32_t NewBits = Bits[I] & RHS.Bits[I];
60f40b1132SCraig Topper Bits[I] = NewBits;
61f40b1132SCraig Topper }
62f40b1132SCraig Topper return *this;
63f40b1132SCraig Topper }
64f40b1132SCraig Topper
operator |=(const FeatureBitset & RHS)6516f3d698SCraig Topper constexpr FeatureBitset &operator|=(const FeatureBitset &RHS) {
66f15014ffSBenjamin Kramer for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I) {
67f40b1132SCraig Topper // GCC <6.2 crashes if this is written in a single statement.
6816f3d698SCraig Topper uint32_t NewBits = Bits[I] | RHS.Bits[I];
6916f3d698SCraig Topper Bits[I] = NewBits;
7016f3d698SCraig Topper }
7116f3d698SCraig Topper return *this;
7216f3d698SCraig Topper }
7316f3d698SCraig Topper
74f40b1132SCraig Topper // gcc 5.3 miscompiles this if we try to write this using operator&=.
operator &(const FeatureBitset & RHS) const753537939cSCraig Topper constexpr FeatureBitset operator&(const FeatureBitset &RHS) const {
769ecda9aaSHans Wennborg FeatureBitset Result;
77f15014ffSBenjamin Kramer for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I)
789ecda9aaSHans Wennborg Result.Bits[I] = Bits[I] & RHS.Bits[I];
793537939cSCraig Topper return Result;
803537939cSCraig Topper }
813537939cSCraig Topper
82f40b1132SCraig Topper // gcc 5.3 miscompiles this if we try to write this using operator&=.
operator |(const FeatureBitset & RHS) const833537939cSCraig Topper constexpr FeatureBitset operator|(const FeatureBitset &RHS) const {
849ecda9aaSHans Wennborg FeatureBitset Result;
85f15014ffSBenjamin Kramer for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I)
869ecda9aaSHans Wennborg Result.Bits[I] = Bits[I] | RHS.Bits[I];
873537939cSCraig Topper return Result;
883537939cSCraig Topper }
893537939cSCraig Topper
operator ~() const903537939cSCraig Topper constexpr FeatureBitset operator~() const {
913537939cSCraig Topper FeatureBitset Result;
92f15014ffSBenjamin Kramer for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I)
933537939cSCraig Topper Result.Bits[I] = ~Bits[I];
943537939cSCraig Topper return Result;
953537939cSCraig Topper }
960c7af8c8SFangrui Song
operator !=(const FeatureBitset & RHS) const970c7af8c8SFangrui Song constexpr bool operator!=(const FeatureBitset &RHS) const {
98f15014ffSBenjamin Kramer for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I)
990c7af8c8SFangrui Song if (Bits[I] != RHS.Bits[I])
1000c7af8c8SFangrui Song return true;
1010c7af8c8SFangrui Song return false;
1020c7af8c8SFangrui Song }
1033537939cSCraig Topper };
1043537939cSCraig Topper
1058dc92142SCraig Topper struct ProcInfo {
1068dc92142SCraig Topper StringLiteral Name;
1078dc92142SCraig Topper X86::CPUKind Kind;
1088dc92142SCraig Topper unsigned KeyFeature;
1093537939cSCraig Topper FeatureBitset Features;
1108dc92142SCraig Topper };
1118dc92142SCraig Topper
11216f3d698SCraig Topper struct FeatureInfo {
11316f3d698SCraig Topper StringLiteral Name;
11416f3d698SCraig Topper FeatureBitset ImpliedFeatures;
11516f3d698SCraig Topper };
11616f3d698SCraig Topper
1178dc92142SCraig Topper } // end anonymous namespace
1188dc92142SCraig Topper
1193537939cSCraig Topper #define X86_FEATURE(ENUM, STRING) \
120a8682554SFangrui Song constexpr FeatureBitset Feature##ENUM = {X86::FEATURE_##ENUM};
1213537939cSCraig Topper #include "llvm/Support/X86TargetParser.def"
1223537939cSCraig Topper
1233537939cSCraig Topper // Pentium with MMX.
124a8682554SFangrui Song constexpr FeatureBitset FeaturesPentiumMMX =
1253537939cSCraig Topper FeatureX87 | FeatureCMPXCHG8B | FeatureMMX;
1263537939cSCraig Topper
1273537939cSCraig Topper // Pentium 2 and 3.
128a8682554SFangrui Song constexpr FeatureBitset FeaturesPentium2 =
1293537939cSCraig Topper FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | FeatureFXSR;
130a8682554SFangrui Song constexpr FeatureBitset FeaturesPentium3 = FeaturesPentium2 | FeatureSSE;
1313537939cSCraig Topper
1323537939cSCraig Topper // Pentium 4 CPUs
133a8682554SFangrui Song constexpr FeatureBitset FeaturesPentium4 = FeaturesPentium3 | FeatureSSE2;
134a8682554SFangrui Song constexpr FeatureBitset FeaturesPrescott = FeaturesPentium4 | FeatureSSE3;
135a8682554SFangrui Song constexpr FeatureBitset FeaturesNocona =
136f40b1132SCraig Topper FeaturesPrescott | Feature64BIT | FeatureCMPXCHG16B;
1373537939cSCraig Topper
1383537939cSCraig Topper // Basic 64-bit capable CPU.
139a8682554SFangrui Song constexpr FeatureBitset FeaturesX86_64 = FeaturesPentium4 | Feature64BIT;
140012dd42eSFangrui Song constexpr FeatureBitset FeaturesX86_64_V2 = FeaturesX86_64 | FeatureSAHF |
14112fa608aSTianqing Wang FeaturePOPCNT | FeatureCRC32 |
14212fa608aSTianqing Wang FeatureSSE4_2 | FeatureCMPXCHG16B;
143012dd42eSFangrui Song constexpr FeatureBitset FeaturesX86_64_V3 =
144012dd42eSFangrui Song FeaturesX86_64_V2 | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureF16C |
145012dd42eSFangrui Song FeatureFMA | FeatureLZCNT | FeatureMOVBE | FeatureXSAVE;
146012dd42eSFangrui Song constexpr FeatureBitset FeaturesX86_64_V4 = FeaturesX86_64_V3 |
147012dd42eSFangrui Song FeatureAVX512BW | FeatureAVX512CD |
148012dd42eSFangrui Song FeatureAVX512DQ | FeatureAVX512VL;
1493537939cSCraig Topper
1503537939cSCraig Topper // Intel Core CPUs
151a8682554SFangrui Song constexpr FeatureBitset FeaturesCore2 =
1523537939cSCraig Topper FeaturesNocona | FeatureSAHF | FeatureSSSE3;
153a8682554SFangrui Song constexpr FeatureBitset FeaturesPenryn = FeaturesCore2 | FeatureSSE4_1;
154a8682554SFangrui Song constexpr FeatureBitset FeaturesNehalem =
15512fa608aSTianqing Wang FeaturesPenryn | FeaturePOPCNT | FeatureCRC32 | FeatureSSE4_2;
156a8682554SFangrui Song constexpr FeatureBitset FeaturesWestmere = FeaturesNehalem | FeaturePCLMUL;
157a8682554SFangrui Song constexpr FeatureBitset FeaturesSandyBridge =
1583537939cSCraig Topper FeaturesWestmere | FeatureAVX | FeatureXSAVE | FeatureXSAVEOPT;
159a8682554SFangrui Song constexpr FeatureBitset FeaturesIvyBridge =
1603537939cSCraig Topper FeaturesSandyBridge | FeatureF16C | FeatureFSGSBASE | FeatureRDRND;
161a8682554SFangrui Song constexpr FeatureBitset FeaturesHaswell =
1623537939cSCraig Topper FeaturesIvyBridge | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureFMA |
1633537939cSCraig Topper FeatureINVPCID | FeatureLZCNT | FeatureMOVBE;
164a8682554SFangrui Song constexpr FeatureBitset FeaturesBroadwell =
1653537939cSCraig Topper FeaturesHaswell | FeatureADX | FeaturePRFCHW | FeatureRDSEED;
1663537939cSCraig Topper
1673537939cSCraig Topper // Intel Knights Landing and Knights Mill
1683537939cSCraig Topper // Knights Landing has feature parity with Broadwell.
169a8682554SFangrui Song constexpr FeatureBitset FeaturesKNL =
1703537939cSCraig Topper FeaturesBroadwell | FeatureAES | FeatureAVX512F | FeatureAVX512CD |
1713537939cSCraig Topper FeatureAVX512ER | FeatureAVX512PF | FeaturePREFETCHWT1;
172a8682554SFangrui Song constexpr FeatureBitset FeaturesKNM = FeaturesKNL | FeatureAVX512VPOPCNTDQ;
1733537939cSCraig Topper
1743537939cSCraig Topper // Intel Skylake processors.
175a8682554SFangrui Song constexpr FeatureBitset FeaturesSkylakeClient =
1763537939cSCraig Topper FeaturesBroadwell | FeatureAES | FeatureCLFLUSHOPT | FeatureXSAVEC |
1773537939cSCraig Topper FeatureXSAVES | FeatureSGX;
1783537939cSCraig Topper // SkylakeServer inherits all SkylakeClient features except SGX.
1793537939cSCraig Topper // FIXME: That doesn't match gcc.
180a8682554SFangrui Song constexpr FeatureBitset FeaturesSkylakeServer =
1813537939cSCraig Topper (FeaturesSkylakeClient & ~FeatureSGX) | FeatureAVX512F | FeatureAVX512CD |
1823537939cSCraig Topper FeatureAVX512DQ | FeatureAVX512BW | FeatureAVX512VL | FeatureCLWB |
1833537939cSCraig Topper FeaturePKU;
184a8682554SFangrui Song constexpr FeatureBitset FeaturesCascadeLake =
1853537939cSCraig Topper FeaturesSkylakeServer | FeatureAVX512VNNI;
186a8682554SFangrui Song constexpr FeatureBitset FeaturesCooperLake =
1873537939cSCraig Topper FeaturesCascadeLake | FeatureAVX512BF16;
1883537939cSCraig Topper
1893537939cSCraig Topper // Intel 10nm processors.
190a8682554SFangrui Song constexpr FeatureBitset FeaturesCannonlake =
1913537939cSCraig Topper FeaturesSkylakeClient | FeatureAVX512F | FeatureAVX512CD | FeatureAVX512DQ |
1923537939cSCraig Topper FeatureAVX512BW | FeatureAVX512VL | FeatureAVX512IFMA | FeatureAVX512VBMI |
1933537939cSCraig Topper FeaturePKU | FeatureSHA;
194a8682554SFangrui Song constexpr FeatureBitset FeaturesICLClient =
1953537939cSCraig Topper FeaturesCannonlake | FeatureAVX512BITALG | FeatureAVX512VBMI2 |
1965cb47be4SFreddy Ye FeatureAVX512VNNI | FeatureAVX512VPOPCNTDQ | FeatureGFNI | FeatureRDPID |
1975cb47be4SFreddy Ye FeatureVAES | FeatureVPCLMULQDQ;
1983fc1fe8dSFreddy Ye constexpr FeatureBitset FeaturesRocketlake = FeaturesICLClient & ~FeatureSGX;
199a8682554SFangrui Song constexpr FeatureBitset FeaturesICLServer =
2005cb47be4SFreddy Ye FeaturesICLClient | FeatureCLWB | FeaturePCONFIG | FeatureWBNOINVD;
201a8682554SFangrui Song constexpr FeatureBitset FeaturesTigerlake =
2023537939cSCraig Topper FeaturesICLClient | FeatureAVX512VP2INTERSECT | FeatureMOVDIR64B |
2035cb47be4SFreddy Ye FeatureCLWB | FeatureMOVDIRI | FeatureSHSTK | FeatureKL | FeatureWIDEKL;
204a8682554SFangrui Song constexpr FeatureBitset FeaturesSapphireRapids =
2056f7f5b54SWang, Pengfei FeaturesICLServer | FeatureAMX_BF16 | FeatureAMX_INT8 | FeatureAMX_TILE |
206*bd5722b8SFreddy Ye FeatureAVX512BF16 | FeatureAVX512FP16 | FeatureAVXVNNI | FeatureCLDEMOTE |
207*bd5722b8SFreddy Ye FeatureENQCMD | FeatureMOVDIR64B | FeatureMOVDIRI | FeaturePTWRITE |
208*bd5722b8SFreddy Ye FeatureSERIALIZE | FeatureSHSTK | FeatureTSXLDTRK | FeatureUINTR |
209*bd5722b8SFreddy Ye FeatureWAITPKG;
2103537939cSCraig Topper
2113537939cSCraig Topper // Intel Atom processors.
2123537939cSCraig Topper // Bonnell has feature parity with Core2 and adds MOVBE.
213a8682554SFangrui Song constexpr FeatureBitset FeaturesBonnell = FeaturesCore2 | FeatureMOVBE;
2143537939cSCraig Topper // Silvermont has parity with Westmere and Bonnell plus PRFCHW and RDRND.
215a8682554SFangrui Song constexpr FeatureBitset FeaturesSilvermont =
2163537939cSCraig Topper FeaturesBonnell | FeaturesWestmere | FeaturePRFCHW | FeatureRDRND;
217a8682554SFangrui Song constexpr FeatureBitset FeaturesGoldmont =
2183537939cSCraig Topper FeaturesSilvermont | FeatureAES | FeatureCLFLUSHOPT | FeatureFSGSBASE |
2193537939cSCraig Topper FeatureRDSEED | FeatureSHA | FeatureXSAVE | FeatureXSAVEC |
2203537939cSCraig Topper FeatureXSAVEOPT | FeatureXSAVES;
221a8682554SFangrui Song constexpr FeatureBitset FeaturesGoldmontPlus =
2223537939cSCraig Topper FeaturesGoldmont | FeaturePTWRITE | FeatureRDPID | FeatureSGX;
223a8682554SFangrui Song constexpr FeatureBitset FeaturesTremont =
2243537939cSCraig Topper FeaturesGoldmontPlus | FeatureCLWB | FeatureGFNI;
2255f9489b7SFreddy Ye constexpr FeatureBitset FeaturesAlderlake =
2265f9489b7SFreddy Ye FeaturesTremont | FeatureADX | FeatureBMI | FeatureBMI2 | FeatureF16C |
2275f9489b7SFreddy Ye FeatureFMA | FeatureINVPCID | FeatureLZCNT | FeaturePCONFIG | FeaturePKU |
2285f9489b7SFreddy Ye FeatureSERIALIZE | FeatureSHSTK | FeatureVAES | FeatureVPCLMULQDQ |
2295f9489b7SFreddy Ye FeatureCLDEMOTE | FeatureMOVDIR64B | FeatureMOVDIRI | FeatureWAITPKG |
2305f9489b7SFreddy Ye FeatureAVXVNNI | FeatureHRESET | FeatureWIDEKL;
2313537939cSCraig Topper
2323537939cSCraig Topper // Geode Processor.
233a8682554SFangrui Song constexpr FeatureBitset FeaturesGeode =
2343537939cSCraig Topper FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | Feature3DNOW | Feature3DNOWA;
2353537939cSCraig Topper
2363537939cSCraig Topper // K6 processor.
237a8682554SFangrui Song constexpr FeatureBitset FeaturesK6 = FeatureX87 | FeatureCMPXCHG8B | FeatureMMX;
2383537939cSCraig Topper
2393537939cSCraig Topper // K7 and K8 architecture processors.
240a8682554SFangrui Song constexpr FeatureBitset FeaturesAthlon =
2413537939cSCraig Topper FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | Feature3DNOW | Feature3DNOWA;
242a8682554SFangrui Song constexpr FeatureBitset FeaturesAthlonXP =
2433537939cSCraig Topper FeaturesAthlon | FeatureFXSR | FeatureSSE;
244a8682554SFangrui Song constexpr FeatureBitset FeaturesK8 =
245f40b1132SCraig Topper FeaturesAthlonXP | FeatureSSE2 | Feature64BIT;
246a8682554SFangrui Song constexpr FeatureBitset FeaturesK8SSE3 = FeaturesK8 | FeatureSSE3;
247a8682554SFangrui Song constexpr FeatureBitset FeaturesAMDFAM10 =
2483537939cSCraig Topper FeaturesK8SSE3 | FeatureCMPXCHG16B | FeatureLZCNT | FeaturePOPCNT |
2497fb3a849SCraig Topper FeaturePRFCHW | FeatureSAHF | FeatureSSE4_A;
2503537939cSCraig Topper
2513537939cSCraig Topper // Bobcat architecture processors.
252a8682554SFangrui Song constexpr FeatureBitset FeaturesBTVER1 =
253f40b1132SCraig Topper FeatureX87 | FeatureCMPXCHG8B | FeatureCMPXCHG16B | Feature64BIT |
2543537939cSCraig Topper FeatureFXSR | FeatureLZCNT | FeatureMMX | FeaturePOPCNT | FeaturePRFCHW |
2557fb3a849SCraig Topper FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_A |
2563537939cSCraig Topper FeatureSAHF;
257a8682554SFangrui Song constexpr FeatureBitset FeaturesBTVER2 =
25812fa608aSTianqing Wang FeaturesBTVER1 | FeatureAES | FeatureAVX | FeatureBMI | FeatureCRC32 |
25912fa608aSTianqing Wang FeatureF16C | FeatureMOVBE | FeaturePCLMUL | FeatureXSAVE | FeatureXSAVEOPT;
2603537939cSCraig Topper
2613537939cSCraig Topper // AMD Bulldozer architecture processors.
262a8682554SFangrui Song constexpr FeatureBitset FeaturesBDVER1 =
2633537939cSCraig Topper FeatureX87 | FeatureAES | FeatureAVX | FeatureCMPXCHG8B |
26412fa608aSTianqing Wang FeatureCMPXCHG16B | FeatureCRC32 | Feature64BIT | FeatureFMA4 |
26512fa608aSTianqing Wang FeatureFXSR | FeatureLWP | FeatureLZCNT | FeatureMMX | FeaturePCLMUL |
26612fa608aSTianqing Wang FeaturePOPCNT | FeaturePRFCHW | FeatureSAHF | FeatureSSE | FeatureSSE2 |
26712fa608aSTianqing Wang FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 | FeatureSSE4_2 | FeatureSSE4_A |
26812fa608aSTianqing Wang FeatureXOP | FeatureXSAVE;
269a8682554SFangrui Song constexpr FeatureBitset FeaturesBDVER2 =
2703537939cSCraig Topper FeaturesBDVER1 | FeatureBMI | FeatureFMA | FeatureF16C | FeatureTBM;
271a8682554SFangrui Song constexpr FeatureBitset FeaturesBDVER3 =
2723537939cSCraig Topper FeaturesBDVER2 | FeatureFSGSBASE | FeatureXSAVEOPT;
273a8682554SFangrui Song constexpr FeatureBitset FeaturesBDVER4 = FeaturesBDVER3 | FeatureAVX2 |
274a8682554SFangrui Song FeatureBMI2 | FeatureMOVBE |
275a8682554SFangrui Song FeatureMWAITX | FeatureRDRND;
2763537939cSCraig Topper
2773537939cSCraig Topper // AMD Zen architecture processors.
278a8682554SFangrui Song constexpr FeatureBitset FeaturesZNVER1 =
2793537939cSCraig Topper FeatureX87 | FeatureADX | FeatureAES | FeatureAVX | FeatureAVX2 |
2803537939cSCraig Topper FeatureBMI | FeatureBMI2 | FeatureCLFLUSHOPT | FeatureCLZERO |
28112fa608aSTianqing Wang FeatureCMPXCHG8B | FeatureCMPXCHG16B | FeatureCRC32 | Feature64BIT |
28212fa608aSTianqing Wang FeatureF16C | FeatureFMA | FeatureFSGSBASE | FeatureFXSR | FeatureLZCNT |
28312fa608aSTianqing Wang FeatureMMX | FeatureMOVBE | FeatureMWAITX | FeaturePCLMUL | FeaturePOPCNT |
28456fc6b98SDouglas Yung FeaturePRFCHW | FeatureRDRND | FeatureRDSEED | FeatureSAHF | FeatureSHA |
28556fc6b98SDouglas Yung FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 |
2867fb3a849SCraig Topper FeatureSSE4_2 | FeatureSSE4_A | FeatureXSAVE | FeatureXSAVEC |
28756fc6b98SDouglas Yung FeatureXSAVEOPT | FeatureXSAVES;
28808e4fe6cSPaul Robinson constexpr FeatureBitset FeaturesZNVER2 = FeaturesZNVER1 | FeatureCLWB |
28908e4fe6cSPaul Robinson FeatureRDPID | FeatureRDPRU |
29008e4fe6cSPaul Robinson FeatureWBNOINVD;
291bd2cf96cSBenjamin Kramer static constexpr FeatureBitset FeaturesZNVER3 = FeaturesZNVER2 |
292bd2cf96cSBenjamin Kramer FeatureINVPCID | FeaturePKU |
293bd2cf96cSBenjamin Kramer FeatureVAES | FeatureVPCLMULQDQ;
2948dc92142SCraig Topper
295a8682554SFangrui Song constexpr ProcInfo Processors[] = {
2963537939cSCraig Topper // Empty processor. Include X87 and CMPXCHG8 for backwards compatibility.
2973537939cSCraig Topper { {""}, CK_None, ~0U, FeatureX87 | FeatureCMPXCHG8B },
2988dc92142SCraig Topper // i386-generation processors.
2993537939cSCraig Topper { {"i386"}, CK_i386, ~0U, FeatureX87 },
3008dc92142SCraig Topper // i486-generation processors.
3013537939cSCraig Topper { {"i486"}, CK_i486, ~0U, FeatureX87 },
3023537939cSCraig Topper { {"winchip-c6"}, CK_WinChipC6, ~0U, FeaturesPentiumMMX },
3033537939cSCraig Topper { {"winchip2"}, CK_WinChip2, ~0U, FeaturesPentiumMMX | Feature3DNOW },
3043537939cSCraig Topper { {"c3"}, CK_C3, ~0U, FeaturesPentiumMMX | Feature3DNOW },
3058dc92142SCraig Topper // i586-generation processors, P5 microarchitecture based.
3063537939cSCraig Topper { {"i586"}, CK_i586, ~0U, FeatureX87 | FeatureCMPXCHG8B },
3073537939cSCraig Topper { {"pentium"}, CK_Pentium, ~0U, FeatureX87 | FeatureCMPXCHG8B },
3083537939cSCraig Topper { {"pentium-mmx"}, CK_PentiumMMX, ~0U, FeaturesPentiumMMX },
3098dc92142SCraig Topper // i686-generation processors, P6 / Pentium M microarchitecture based.
3103537939cSCraig Topper { {"pentiumpro"}, CK_PentiumPro, ~0U, FeatureX87 | FeatureCMPXCHG8B },
3113537939cSCraig Topper { {"i686"}, CK_i686, ~0U, FeatureX87 | FeatureCMPXCHG8B },
3123537939cSCraig Topper { {"pentium2"}, CK_Pentium2, ~0U, FeaturesPentium2 },
3133537939cSCraig Topper { {"pentium3"}, CK_Pentium3, ~0U, FeaturesPentium3 },
3143537939cSCraig Topper { {"pentium3m"}, CK_Pentium3, ~0U, FeaturesPentium3 },
3153537939cSCraig Topper { {"pentium-m"}, CK_PentiumM, ~0U, FeaturesPentium4 },
3163537939cSCraig Topper { {"c3-2"}, CK_C3_2, ~0U, FeaturesPentium3 },
3173537939cSCraig Topper { {"yonah"}, CK_Yonah, ~0U, FeaturesPrescott },
3188dc92142SCraig Topper // Netburst microarchitecture based processors.
3193537939cSCraig Topper { {"pentium4"}, CK_Pentium4, ~0U, FeaturesPentium4 },
3203537939cSCraig Topper { {"pentium4m"}, CK_Pentium4, ~0U, FeaturesPentium4 },
3213537939cSCraig Topper { {"prescott"}, CK_Prescott, ~0U, FeaturesPrescott },
3223537939cSCraig Topper { {"nocona"}, CK_Nocona, ~0U, FeaturesNocona },
3238dc92142SCraig Topper // Core microarchitecture based processors.
3243537939cSCraig Topper { {"core2"}, CK_Core2, ~0U, FeaturesCore2 },
3253537939cSCraig Topper { {"penryn"}, CK_Penryn, ~0U, FeaturesPenryn },
3268dc92142SCraig Topper // Atom processors
3273537939cSCraig Topper { {"bonnell"}, CK_Bonnell, FEATURE_SSSE3, FeaturesBonnell },
3283537939cSCraig Topper { {"atom"}, CK_Bonnell, FEATURE_SSSE3, FeaturesBonnell },
3293537939cSCraig Topper { {"silvermont"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont },
3303537939cSCraig Topper { {"slm"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont },
3313537939cSCraig Topper { {"goldmont"}, CK_Goldmont, FEATURE_SSE4_2, FeaturesGoldmont },
3323537939cSCraig Topper { {"goldmont-plus"}, CK_GoldmontPlus, FEATURE_SSE4_2, FeaturesGoldmontPlus },
3333537939cSCraig Topper { {"tremont"}, CK_Tremont, FEATURE_SSE4_2, FeaturesTremont },
3348dc92142SCraig Topper // Nehalem microarchitecture based processors.
3353537939cSCraig Topper { {"nehalem"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem },
3363537939cSCraig Topper { {"corei7"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem },
3378dc92142SCraig Topper // Westmere microarchitecture based processors.
3383537939cSCraig Topper { {"westmere"}, CK_Westmere, FEATURE_PCLMUL, FeaturesWestmere },
3398dc92142SCraig Topper // Sandy Bridge microarchitecture based processors.
3403537939cSCraig Topper { {"sandybridge"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge },
3413537939cSCraig Topper { {"corei7-avx"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge },
3428dc92142SCraig Topper // Ivy Bridge microarchitecture based processors.
3433537939cSCraig Topper { {"ivybridge"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge },
3443537939cSCraig Topper { {"core-avx-i"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge },
3458dc92142SCraig Topper // Haswell microarchitecture based processors.
3463537939cSCraig Topper { {"haswell"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell },
3473537939cSCraig Topper { {"core-avx2"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell },
3488dc92142SCraig Topper // Broadwell microarchitecture based processors.
3493537939cSCraig Topper { {"broadwell"}, CK_Broadwell, FEATURE_AVX2, FeaturesBroadwell },
3508dc92142SCraig Topper // Skylake client microarchitecture based processors.
3513537939cSCraig Topper { {"skylake"}, CK_SkylakeClient, FEATURE_AVX2, FeaturesSkylakeClient },
3528dc92142SCraig Topper // Skylake server microarchitecture based processors.
3533537939cSCraig Topper { {"skylake-avx512"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer },
3543537939cSCraig Topper { {"skx"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer },
3558dc92142SCraig Topper // Cascadelake Server microarchitecture based processors.
3563537939cSCraig Topper { {"cascadelake"}, CK_Cascadelake, FEATURE_AVX512VNNI, FeaturesCascadeLake },
3578dc92142SCraig Topper // Cooperlake Server microarchitecture based processors.
3583537939cSCraig Topper { {"cooperlake"}, CK_Cooperlake, FEATURE_AVX512BF16, FeaturesCooperLake },
3598dc92142SCraig Topper // Cannonlake client microarchitecture based processors.
3603537939cSCraig Topper { {"cannonlake"}, CK_Cannonlake, FEATURE_AVX512VBMI, FeaturesCannonlake },
3618dc92142SCraig Topper // Icelake client microarchitecture based processors.
3623537939cSCraig Topper { {"icelake-client"}, CK_IcelakeClient, FEATURE_AVX512VBMI2, FeaturesICLClient },
3633fc1fe8dSFreddy Ye // Rocketlake microarchitecture based processors.
3643fc1fe8dSFreddy Ye { {"rocketlake"}, CK_Rocketlake, FEATURE_AVX512VBMI2, FeaturesRocketlake },
3658dc92142SCraig Topper // Icelake server microarchitecture based processors.
3663537939cSCraig Topper { {"icelake-server"}, CK_IcelakeServer, FEATURE_AVX512VBMI2, FeaturesICLServer },
3678dc92142SCraig Topper // Tigerlake microarchitecture based processors.
3683537939cSCraig Topper { {"tigerlake"}, CK_Tigerlake, FEATURE_AVX512VP2INTERSECT, FeaturesTigerlake },
369e02d081fSFreddy Ye // Sapphire Rapids microarchitecture based processors.
370*bd5722b8SFreddy Ye { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512BF16, FeaturesSapphireRapids },
37139a0d688SBenjamin Kramer // Alderlake microarchitecture based processors.
37239a0d688SBenjamin Kramer { {"alderlake"}, CK_Alderlake, FEATURE_AVX2, FeaturesAlderlake },
3738dc92142SCraig Topper // Knights Landing processor.
3743537939cSCraig Topper { {"knl"}, CK_KNL, FEATURE_AVX512F, FeaturesKNL },
3758dc92142SCraig Topper // Knights Mill processor.
3763537939cSCraig Topper { {"knm"}, CK_KNM, FEATURE_AVX5124FMAPS, FeaturesKNM },
3778dc92142SCraig Topper // Lakemont microarchitecture based processors.
3783537939cSCraig Topper { {"lakemont"}, CK_Lakemont, ~0U, FeatureCMPXCHG8B },
3798dc92142SCraig Topper // K6 architecture processors.
3803537939cSCraig Topper { {"k6"}, CK_K6, ~0U, FeaturesK6 },
3813537939cSCraig Topper { {"k6-2"}, CK_K6_2, ~0U, FeaturesK6 | Feature3DNOW },
3823537939cSCraig Topper { {"k6-3"}, CK_K6_3, ~0U, FeaturesK6 | Feature3DNOW },
3838dc92142SCraig Topper // K7 architecture processors.
3843537939cSCraig Topper { {"athlon"}, CK_Athlon, ~0U, FeaturesAthlon },
3853537939cSCraig Topper { {"athlon-tbird"}, CK_Athlon, ~0U, FeaturesAthlon },
3863537939cSCraig Topper { {"athlon-xp"}, CK_AthlonXP, ~0U, FeaturesAthlonXP },
3873537939cSCraig Topper { {"athlon-mp"}, CK_AthlonXP, ~0U, FeaturesAthlonXP },
3883537939cSCraig Topper { {"athlon-4"}, CK_AthlonXP, ~0U, FeaturesAthlonXP },
3898dc92142SCraig Topper // K8 architecture processors.
3903537939cSCraig Topper { {"k8"}, CK_K8, ~0U, FeaturesK8 },
3913537939cSCraig Topper { {"athlon64"}, CK_K8, ~0U, FeaturesK8 },
3923537939cSCraig Topper { {"athlon-fx"}, CK_K8, ~0U, FeaturesK8 },
3933537939cSCraig Topper { {"opteron"}, CK_K8, ~0U, FeaturesK8 },
3943537939cSCraig Topper { {"k8-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3 },
3953537939cSCraig Topper { {"athlon64-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3 },
3963537939cSCraig Topper { {"opteron-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3 },
3973537939cSCraig Topper { {"amdfam10"}, CK_AMDFAM10, FEATURE_SSE4_A, FeaturesAMDFAM10 },
3983537939cSCraig Topper { {"barcelona"}, CK_AMDFAM10, FEATURE_SSE4_A, FeaturesAMDFAM10 },
3998dc92142SCraig Topper // Bobcat architecture processors.
4003537939cSCraig Topper { {"btver1"}, CK_BTVER1, FEATURE_SSE4_A, FeaturesBTVER1 },
4013537939cSCraig Topper { {"btver2"}, CK_BTVER2, FEATURE_BMI, FeaturesBTVER2 },
4028dc92142SCraig Topper // Bulldozer architecture processors.
4033537939cSCraig Topper { {"bdver1"}, CK_BDVER1, FEATURE_XOP, FeaturesBDVER1 },
4043537939cSCraig Topper { {"bdver2"}, CK_BDVER2, FEATURE_FMA, FeaturesBDVER2 },
4053537939cSCraig Topper { {"bdver3"}, CK_BDVER3, FEATURE_FMA, FeaturesBDVER3 },
4063537939cSCraig Topper { {"bdver4"}, CK_BDVER4, FEATURE_AVX2, FeaturesBDVER4 },
4078dc92142SCraig Topper // Zen architecture processors.
4083537939cSCraig Topper { {"znver1"}, CK_ZNVER1, FEATURE_AVX2, FeaturesZNVER1 },
4093537939cSCraig Topper { {"znver2"}, CK_ZNVER2, FEATURE_AVX2, FeaturesZNVER2 },
410bd2cf96cSBenjamin Kramer { {"znver3"}, CK_ZNVER3, FEATURE_AVX2, FeaturesZNVER3 },
4118dc92142SCraig Topper // Generic 64-bit processor.
4123537939cSCraig Topper { {"x86-64"}, CK_x86_64, ~0U, FeaturesX86_64 },
413012dd42eSFangrui Song { {"x86-64-v2"}, CK_x86_64_v2, ~0U, FeaturesX86_64_V2 },
414012dd42eSFangrui Song { {"x86-64-v3"}, CK_x86_64_v3, ~0U, FeaturesX86_64_V3 },
415012dd42eSFangrui Song { {"x86-64-v4"}, CK_x86_64_v4, ~0U, FeaturesX86_64_V4 },
4168dc92142SCraig Topper // Geode processors.
4173537939cSCraig Topper { {"geode"}, CK_Geode, ~0U, FeaturesGeode },
4188dc92142SCraig Topper };
419d5c28c40SCraig Topper
420012dd42eSFangrui Song constexpr const char *NoTuneList[] = {"x86-64-v2", "x86-64-v3", "x86-64-v4"};
421012dd42eSFangrui Song
parseArchX86(StringRef CPU,bool Only64Bit)422d5c28c40SCraig Topper X86::CPUKind llvm::X86::parseArchX86(StringRef CPU, bool Only64Bit) {
4238dc92142SCraig Topper for (const auto &P : Processors)
424f40b1132SCraig Topper if (P.Name == CPU && (P.Features[FEATURE_64BIT] || !Only64Bit))
4258dc92142SCraig Topper return P.Kind;
426d5c28c40SCraig Topper
4278dc92142SCraig Topper return CK_None;
428d5c28c40SCraig Topper }
429d5c28c40SCraig Topper
parseTuneCPU(StringRef CPU,bool Only64Bit)430012dd42eSFangrui Song X86::CPUKind llvm::X86::parseTuneCPU(StringRef CPU, bool Only64Bit) {
431012dd42eSFangrui Song if (llvm::is_contained(NoTuneList, CPU))
432012dd42eSFangrui Song return CK_None;
433012dd42eSFangrui Song return parseArchX86(CPU, Only64Bit);
434012dd42eSFangrui Song }
435012dd42eSFangrui Song
fillValidCPUArchList(SmallVectorImpl<StringRef> & Values,bool Only64Bit)436d5c28c40SCraig Topper void llvm::X86::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values,
437d5c28c40SCraig Topper bool Only64Bit) {
4388dc92142SCraig Topper for (const auto &P : Processors)
439f40b1132SCraig Topper if (!P.Name.empty() && (P.Features[FEATURE_64BIT] || !Only64Bit))
4408dc92142SCraig Topper Values.emplace_back(P.Name);
4418dc92142SCraig Topper }
4428dc92142SCraig Topper
fillValidTuneCPUList(SmallVectorImpl<StringRef> & Values,bool Only64Bit)443012dd42eSFangrui Song void llvm::X86::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values,
444012dd42eSFangrui Song bool Only64Bit) {
445012dd42eSFangrui Song for (const ProcInfo &P : Processors)
446012dd42eSFangrui Song if (!P.Name.empty() && (P.Features[FEATURE_64BIT] || !Only64Bit) &&
447012dd42eSFangrui Song !llvm::is_contained(NoTuneList, P.Name))
448012dd42eSFangrui Song Values.emplace_back(P.Name);
449012dd42eSFangrui Song }
450012dd42eSFangrui Song
getKeyFeature(X86::CPUKind Kind)4518dc92142SCraig Topper ProcessorFeatures llvm::X86::getKeyFeature(X86::CPUKind Kind) {
4528dc92142SCraig Topper // FIXME: Can we avoid a linear search here? The table might be sorted by
4538dc92142SCraig Topper // CPUKind so we could binary search?
4548dc92142SCraig Topper for (const auto &P : Processors) {
4558dc92142SCraig Topper if (P.Kind == Kind) {
4568dc92142SCraig Topper assert(P.KeyFeature != ~0U && "Processor does not have a key feature.");
4578dc92142SCraig Topper return static_cast<ProcessorFeatures>(P.KeyFeature);
4588dc92142SCraig Topper }
4598dc92142SCraig Topper }
4608dc92142SCraig Topper
4618dc92142SCraig Topper llvm_unreachable("Unable to find CPU kind!");
462d5c28c40SCraig Topper }
4633537939cSCraig Topper
46416f3d698SCraig Topper // Features with no dependencies.
465a8682554SFangrui Song constexpr FeatureBitset ImpliedFeatures64BIT = {};
466a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesADX = {};
467a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesBMI = {};
468a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesBMI2 = {};
469a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesCLDEMOTE = {};
470a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesCLFLUSHOPT = {};
471a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesCLWB = {};
472a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesCLZERO = {};
473a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesCMOV = {};
474a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesCMPXCHG16B = {};
475a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesCMPXCHG8B = {};
47612fa608aSTianqing Wang constexpr FeatureBitset ImpliedFeaturesCRC32 = {};
477a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesENQCMD = {};
478a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesFSGSBASE = {};
479a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesFXSR = {};
480a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesINVPCID = {};
481a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesLWP = {};
482a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesLZCNT = {};
483a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesMWAITX = {};
484a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesMOVBE = {};
485a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesMOVDIR64B = {};
486a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesMOVDIRI = {};
487a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesPCONFIG = {};
488a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesPOPCNT = {};
489a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesPKU = {};
490a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesPREFETCHWT1 = {};
491a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesPRFCHW = {};
492a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesPTWRITE = {};
493a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesRDPID = {};
49408e4fe6cSPaul Robinson constexpr FeatureBitset ImpliedFeaturesRDPRU = {};
495a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesRDRND = {};
496a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesRDSEED = {};
497a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesRTM = {};
498a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSAHF = {};
499a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSERIALIZE = {};
500a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSGX = {};
501a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSHSTK = {};
502a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesTBM = {};
503a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesTSXLDTRK = {};
504be39a6feSTianqing Wang constexpr FeatureBitset ImpliedFeaturesUINTR = {};
505a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesWAITPKG = {};
506a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesWBNOINVD = {};
507a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesVZEROUPPER = {};
508a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesX87 = {};
509a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesXSAVE = {};
51016f3d698SCraig Topper
51116f3d698SCraig Topper // Not really CPU features, but need to be in the table because clang uses
51216f3d698SCraig Topper // target features to communicate them to the backend.
513a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesRETPOLINE_EXTERNAL_THUNK = {};
514a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_BRANCHES = {};
515a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_CALLS = {};
516a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesLVI_CFI = {};
517a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesLVI_LOAD_HARDENING = {};
51816f3d698SCraig Topper
51916f3d698SCraig Topper // XSAVE features are dependent on basic XSAVE.
520a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesXSAVEC = FeatureXSAVE;
521a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesXSAVEOPT = FeatureXSAVE;
522a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesXSAVES = FeatureXSAVE;
52316f3d698SCraig Topper
52416f3d698SCraig Topper // MMX->3DNOW->3DNOWA chain.
525a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesMMX = {};
526a8682554SFangrui Song constexpr FeatureBitset ImpliedFeatures3DNOW = FeatureMMX;
527a8682554SFangrui Song constexpr FeatureBitset ImpliedFeatures3DNOWA = Feature3DNOW;
52816f3d698SCraig Topper
52916f3d698SCraig Topper // SSE/AVX/AVX512F chain.
530a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSSE = {};
531a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSSE2 = FeatureSSE;
532a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSSE3 = FeatureSSE2;
533a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSSSE3 = FeatureSSE3;
534a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSSE4_1 = FeatureSSSE3;
535a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSSE4_2 = FeatureSSE4_1;
536a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX = FeatureSSE4_2;
537a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX2 = FeatureAVX;
538a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512F =
53916f3d698SCraig Topper FeatureAVX2 | FeatureF16C | FeatureFMA;
54016f3d698SCraig Topper
54116f3d698SCraig Topper // Vector extensions that build on SSE or AVX.
542a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAES = FeatureSSE2;
543a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesF16C = FeatureAVX;
544a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesFMA = FeatureAVX;
545a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesGFNI = FeatureSSE2;
546a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesPCLMUL = FeatureSSE2;
547a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSHA = FeatureSSE2;
548a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesVAES = FeatureAES | FeatureAVX;
549a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesVPCLMULQDQ = FeatureAVX | FeaturePCLMUL;
55016f3d698SCraig Topper
55116f3d698SCraig Topper // AVX512 features.
552a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512CD = FeatureAVX512F;
553a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512BW = FeatureAVX512F;
554a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512DQ = FeatureAVX512F;
555a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512ER = FeatureAVX512F;
556a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512PF = FeatureAVX512F;
557a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512VL = FeatureAVX512F;
55816f3d698SCraig Topper
559a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512BF16 = FeatureAVX512BW;
560a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512BITALG = FeatureAVX512BW;
561a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512IFMA = FeatureAVX512F;
562a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512VNNI = FeatureAVX512F;
563a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512VPOPCNTDQ = FeatureAVX512F;
564a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512VBMI = FeatureAVX512BW;
565a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512VBMI2 = FeatureAVX512BW;
566a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX512VP2INTERSECT = FeatureAVX512F;
56716f3d698SCraig Topper
56816f3d698SCraig Topper // FIXME: These two aren't really implemented and just exist in the feature
56916f3d698SCraig Topper // list for __builtin_cpu_supports. So omit their dependencies.
570a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX5124FMAPS = {};
571a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAVX5124VNNIW = {};
57216f3d698SCraig Topper
57316f3d698SCraig Topper // SSE4_A->FMA4->XOP chain.
574a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesSSE4_A = FeatureSSE3;
575a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesFMA4 = FeatureAVX | FeatureSSE4_A;
576a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesXOP = FeatureFMA4;
57716f3d698SCraig Topper
57816f3d698SCraig Topper // AMX Features
579a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAMX_TILE = {};
580a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAMX_BF16 = FeatureAMX_TILE;
581a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesAMX_INT8 = FeatureAMX_TILE;
582412cdcf2SWang, Pengfei constexpr FeatureBitset ImpliedFeaturesHRESET = {};
58316f3d698SCraig Topper
5846f7f5b54SWang, Pengfei static constexpr FeatureBitset ImpliedFeaturesAVX512FP16 =
5856f7f5b54SWang, Pengfei FeatureAVX512BW | FeatureAVX512DQ | FeatureAVX512VL;
586413577a8SXiang1 Zhang // Key Locker Features
587a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesKL = FeatureSSE2;
588a8682554SFangrui Song constexpr FeatureBitset ImpliedFeaturesWIDEKL = FeatureKL;
589413577a8SXiang1 Zhang
590756f5978SLiu, Chen3 // AVXVNNI Features
591756f5978SLiu, Chen3 constexpr FeatureBitset ImpliedFeaturesAVXVNNI = FeatureAVX2;
592756f5978SLiu, Chen3
593a8682554SFangrui Song constexpr FeatureInfo FeatureInfos[X86::CPU_FEATURE_MAX] = {
59416f3d698SCraig Topper #define X86_FEATURE(ENUM, STR) {{STR}, ImpliedFeatures##ENUM},
5953537939cSCraig Topper #include "llvm/Support/X86TargetParser.def"
5963537939cSCraig Topper };
5973537939cSCraig Topper
getFeaturesForCPU(StringRef CPU,SmallVectorImpl<StringRef> & EnabledFeatures)59816f3d698SCraig Topper void llvm::X86::getFeaturesForCPU(StringRef CPU,
59916f3d698SCraig Topper SmallVectorImpl<StringRef> &EnabledFeatures) {
6003537939cSCraig Topper auto I = llvm::find_if(Processors,
6013537939cSCraig Topper [&](const ProcInfo &P) { return P.Name == CPU; });
6023537939cSCraig Topper assert(I != std::end(Processors) && "Processor not found!");
6033537939cSCraig Topper
604f40b1132SCraig Topper FeatureBitset Bits = I->Features;
605f40b1132SCraig Topper
606f40b1132SCraig Topper // Remove the 64-bit feature which we only use to validate if a CPU can
607f40b1132SCraig Topper // be used with 64-bit mode.
608f40b1132SCraig Topper Bits &= ~Feature64BIT;
609f40b1132SCraig Topper
6103537939cSCraig Topper // Add the string version of all set bits.
611504a197fSCraig Topper for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
612504a197fSCraig Topper if (Bits[i] && !FeatureInfos[i].Name.empty())
613504a197fSCraig Topper EnabledFeatures.push_back(FeatureInfos[i].Name);
61416f3d698SCraig Topper }
61516f3d698SCraig Topper
61616f3d698SCraig Topper // For each feature that is (transitively) implied by this feature, set it.
getImpliedEnabledFeatures(FeatureBitset & Bits,const FeatureBitset & Implies)61716f3d698SCraig Topper static void getImpliedEnabledFeatures(FeatureBitset &Bits,
61816f3d698SCraig Topper const FeatureBitset &Implies) {
6190c7af8c8SFangrui Song // Fast path: Implies is often empty.
6200c7af8c8SFangrui Song if (!Implies.any())
6210c7af8c8SFangrui Song return;
6220c7af8c8SFangrui Song FeatureBitset Prev;
62316f3d698SCraig Topper Bits |= Implies;
6240c7af8c8SFangrui Song do {
6250c7af8c8SFangrui Song Prev = Bits;
6260c7af8c8SFangrui Song for (unsigned i = CPU_FEATURE_MAX; i;)
6270c7af8c8SFangrui Song if (Bits[--i])
6280c7af8c8SFangrui Song Bits |= FeatureInfos[i].ImpliedFeatures;
6290c7af8c8SFangrui Song } while (Prev != Bits);
63016f3d698SCraig Topper }
63116f3d698SCraig Topper
63216f3d698SCraig Topper /// Create bit vector of features that are implied disabled if the feature
63316f3d698SCraig Topper /// passed in Value is disabled.
getImpliedDisabledFeatures(FeatureBitset & Bits,unsigned Value)63416f3d698SCraig Topper static void getImpliedDisabledFeatures(FeatureBitset &Bits, unsigned Value) {
63516f3d698SCraig Topper // Check all features looking for any dependent on this feature. If we find
63616f3d698SCraig Topper // one, mark it and recursively find any feature that depend on it.
6370c7af8c8SFangrui Song FeatureBitset Prev;
6380c7af8c8SFangrui Song Bits.set(Value);
6390c7af8c8SFangrui Song do {
6400c7af8c8SFangrui Song Prev = Bits;
6410c7af8c8SFangrui Song for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
6420c7af8c8SFangrui Song if ((FeatureInfos[i].ImpliedFeatures & Bits).any())
64316f3d698SCraig Topper Bits.set(i);
6440c7af8c8SFangrui Song } while (Prev != Bits);
64516f3d698SCraig Topper }
64616f3d698SCraig Topper
updateImpliedFeatures(StringRef Feature,bool Enabled,StringMap<bool> & Features)647504a197fSCraig Topper void llvm::X86::updateImpliedFeatures(
64816f3d698SCraig Topper StringRef Feature, bool Enabled,
649504a197fSCraig Topper StringMap<bool> &Features) {
65016f3d698SCraig Topper auto I = llvm::find_if(
65116f3d698SCraig Topper FeatureInfos, [&](const FeatureInfo &FI) { return FI.Name == Feature; });
65216f3d698SCraig Topper if (I == std::end(FeatureInfos)) {
65344ea81acSCraig Topper // FIXME: This shouldn't happen, but may not have all features in the table
65444ea81acSCraig Topper // yet.
65516f3d698SCraig Topper return;
65616f3d698SCraig Topper }
65716f3d698SCraig Topper
65816f3d698SCraig Topper FeatureBitset ImpliedBits;
65916f3d698SCraig Topper if (Enabled)
66016f3d698SCraig Topper getImpliedEnabledFeatures(ImpliedBits, I->ImpliedFeatures);
66116f3d698SCraig Topper else
66216f3d698SCraig Topper getImpliedDisabledFeatures(ImpliedBits,
66316f3d698SCraig Topper std::distance(std::begin(FeatureInfos), I));
66416f3d698SCraig Topper
665504a197fSCraig Topper // Update the map entry for all implied features.
666504a197fSCraig Topper for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
667504a197fSCraig Topper if (ImpliedBits[i] && !FeatureInfos[i].Name.empty())
668504a197fSCraig Topper Features[FeatureInfos[i].Name] = Enabled;
6693537939cSCraig Topper }
6701724a164SAndrei Elovikov
getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs)6711724a164SAndrei Elovikov uint64_t llvm::X86::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) {
6721724a164SAndrei Elovikov // Processor features and mapping to processor feature value.
6731724a164SAndrei Elovikov uint64_t FeaturesMask = 0;
6741724a164SAndrei Elovikov for (const StringRef &FeatureStr : FeatureStrs) {
6751724a164SAndrei Elovikov unsigned Feature = StringSwitch<unsigned>(FeatureStr)
6761724a164SAndrei Elovikov #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \
6771724a164SAndrei Elovikov .Case(STR, llvm::X86::FEATURE_##ENUM)
6781724a164SAndrei Elovikov #include "llvm/Support/X86TargetParser.def"
6791724a164SAndrei Elovikov ;
6801724a164SAndrei Elovikov FeaturesMask |= (1ULL << Feature);
6811724a164SAndrei Elovikov }
6821724a164SAndrei Elovikov return FeaturesMask;
6831724a164SAndrei Elovikov }
6841724a164SAndrei Elovikov
getFeaturePriority(ProcessorFeatures Feat)6851724a164SAndrei Elovikov unsigned llvm::X86::getFeaturePriority(ProcessorFeatures Feat) {
6861724a164SAndrei Elovikov #ifndef NDEBUG
6871724a164SAndrei Elovikov // Check that priorities are set properly in the .def file. We expect that
6881724a164SAndrei Elovikov // "compat" features are assigned non-duplicate consecutive priorities
6891724a164SAndrei Elovikov // starting from zero (0, 1, ..., num_features - 1).
6901724a164SAndrei Elovikov #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) PRIORITY,
6911724a164SAndrei Elovikov unsigned Priorities[] = {
6921724a164SAndrei Elovikov #include "llvm/Support/X86TargetParser.def"
6931724a164SAndrei Elovikov std::numeric_limits<unsigned>::max() // Need to consume last comma.
6941724a164SAndrei Elovikov };
695f15014ffSBenjamin Kramer std::array<unsigned, array_lengthof(Priorities) - 1> HelperList;
6961724a164SAndrei Elovikov std::iota(HelperList.begin(), HelperList.end(), 0);
6971724a164SAndrei Elovikov assert(std::is_permutation(HelperList.begin(), HelperList.end(),
6981724a164SAndrei Elovikov std::begin(Priorities),
6991724a164SAndrei Elovikov std::prev(std::end(Priorities))) &&
7001724a164SAndrei Elovikov "Priorities don't form consecutive range!");
7011724a164SAndrei Elovikov #endif
7021724a164SAndrei Elovikov
7031724a164SAndrei Elovikov switch (Feat) {
7041724a164SAndrei Elovikov #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \
7051724a164SAndrei Elovikov case X86::FEATURE_##ENUM: \
7061724a164SAndrei Elovikov return PRIORITY;
7071724a164SAndrei Elovikov #include "llvm/Support/X86TargetParser.def"
7081724a164SAndrei Elovikov default:
7091724a164SAndrei Elovikov llvm_unreachable("No Feature Priority for non-CPUSupports Features");
7101724a164SAndrei Elovikov }
7111724a164SAndrei Elovikov }
712