1cfca06d7SDimitry Andric //===-- X86TargetParser - Parser for X86 features ---------------*- C++ -*-===//
2cfca06d7SDimitry Andric //
3cfca06d7SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cfca06d7SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5cfca06d7SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cfca06d7SDimitry Andric //
7cfca06d7SDimitry Andric //===----------------------------------------------------------------------===//
8cfca06d7SDimitry Andric //
9cfca06d7SDimitry Andric // This file implements a target parser to recognise X86 hardware features.
10cfca06d7SDimitry Andric //
11cfca06d7SDimitry Andric //===----------------------------------------------------------------------===//
12cfca06d7SDimitry Andric
13e3b55780SDimitry Andric #include "llvm/TargetParser/X86TargetParser.h"
14b1c73532SDimitry Andric #include "llvm/ADT/Bitset.h"
15c0981da4SDimitry Andric #include "llvm/ADT/StringSwitch.h"
16c0981da4SDimitry Andric #include <numeric>
17cfca06d7SDimitry Andric
18cfca06d7SDimitry Andric using namespace llvm;
19cfca06d7SDimitry Andric using namespace llvm::X86;
20cfca06d7SDimitry Andric
21cfca06d7SDimitry Andric namespace {
22cfca06d7SDimitry Andric
23b1c73532SDimitry Andric using FeatureBitset = Bitset<X86::CPU_FEATURE_MAX>;
24cfca06d7SDimitry Andric
25cfca06d7SDimitry Andric struct ProcInfo {
26cfca06d7SDimitry Andric StringLiteral Name;
27cfca06d7SDimitry Andric X86::CPUKind Kind;
28cfca06d7SDimitry Andric unsigned KeyFeature;
29cfca06d7SDimitry Andric FeatureBitset Features;
307fa27ce4SDimitry Andric char Mangling;
317fa27ce4SDimitry Andric bool OnlyForCPUDispatchSpecific;
32cfca06d7SDimitry Andric };
33cfca06d7SDimitry Andric
34cfca06d7SDimitry Andric struct FeatureInfo {
35b1c73532SDimitry Andric StringLiteral NameWithPlus;
36cfca06d7SDimitry Andric FeatureBitset ImpliedFeatures;
37b1c73532SDimitry Andric
getName__anon1a56a5c20111::FeatureInfo38b1c73532SDimitry Andric StringRef getName(bool WithPlus = false) const {
39b1c73532SDimitry Andric assert(NameWithPlus[0] == '+' && "Expected string to start with '+'");
40b1c73532SDimitry Andric if (WithPlus)
41b1c73532SDimitry Andric return NameWithPlus;
42b1c73532SDimitry Andric return NameWithPlus.drop_front();
43b1c73532SDimitry Andric }
44cfca06d7SDimitry Andric };
45cfca06d7SDimitry Andric
46cfca06d7SDimitry Andric } // end anonymous namespace
47cfca06d7SDimitry Andric
48cfca06d7SDimitry Andric #define X86_FEATURE(ENUM, STRING) \
49b60736ecSDimitry Andric constexpr FeatureBitset Feature##ENUM = {X86::FEATURE_##ENUM};
50e3b55780SDimitry Andric #include "llvm/TargetParser/X86TargetParser.def"
51cfca06d7SDimitry Andric
52cfca06d7SDimitry Andric // Pentium with MMX.
53b60736ecSDimitry Andric constexpr FeatureBitset FeaturesPentiumMMX =
54cfca06d7SDimitry Andric FeatureX87 | FeatureCMPXCHG8B | FeatureMMX;
55cfca06d7SDimitry Andric
56cfca06d7SDimitry Andric // Pentium 2 and 3.
57b60736ecSDimitry Andric constexpr FeatureBitset FeaturesPentium2 =
587fa27ce4SDimitry Andric FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | FeatureFXSR | FeatureCMOV;
59b60736ecSDimitry Andric constexpr FeatureBitset FeaturesPentium3 = FeaturesPentium2 | FeatureSSE;
60cfca06d7SDimitry Andric
61cfca06d7SDimitry Andric // Pentium 4 CPUs
62b60736ecSDimitry Andric constexpr FeatureBitset FeaturesPentium4 = FeaturesPentium3 | FeatureSSE2;
63b60736ecSDimitry Andric constexpr FeatureBitset FeaturesPrescott = FeaturesPentium4 | FeatureSSE3;
64b60736ecSDimitry Andric constexpr FeatureBitset FeaturesNocona =
65cfca06d7SDimitry Andric FeaturesPrescott | Feature64BIT | FeatureCMPXCHG16B;
66cfca06d7SDimitry Andric
67cfca06d7SDimitry Andric // Basic 64-bit capable CPU.
68b60736ecSDimitry Andric constexpr FeatureBitset FeaturesX86_64 = FeaturesPentium4 | Feature64BIT;
69b60736ecSDimitry Andric constexpr FeatureBitset FeaturesX86_64_V2 = FeaturesX86_64 | FeatureSAHF |
70c0981da4SDimitry Andric FeaturePOPCNT | FeatureCRC32 |
71c0981da4SDimitry Andric FeatureSSE4_2 | FeatureCMPXCHG16B;
72b60736ecSDimitry Andric constexpr FeatureBitset FeaturesX86_64_V3 =
73b60736ecSDimitry Andric FeaturesX86_64_V2 | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureF16C |
74b60736ecSDimitry Andric FeatureFMA | FeatureLZCNT | FeatureMOVBE | FeatureXSAVE;
75b1c73532SDimitry Andric constexpr FeatureBitset FeaturesX86_64_V4 = FeaturesX86_64_V3 | FeatureEVEX512 |
76b60736ecSDimitry Andric FeatureAVX512BW | FeatureAVX512CD |
77b60736ecSDimitry Andric FeatureAVX512DQ | FeatureAVX512VL;
78cfca06d7SDimitry Andric
79cfca06d7SDimitry Andric // Intel Core CPUs
80b60736ecSDimitry Andric constexpr FeatureBitset FeaturesCore2 =
81cfca06d7SDimitry Andric FeaturesNocona | FeatureSAHF | FeatureSSSE3;
82b60736ecSDimitry Andric constexpr FeatureBitset FeaturesPenryn = FeaturesCore2 | FeatureSSE4_1;
83b60736ecSDimitry Andric constexpr FeatureBitset FeaturesNehalem =
84c0981da4SDimitry Andric FeaturesPenryn | FeaturePOPCNT | FeatureCRC32 | FeatureSSE4_2;
85b60736ecSDimitry Andric constexpr FeatureBitset FeaturesWestmere = FeaturesNehalem | FeaturePCLMUL;
86b60736ecSDimitry Andric constexpr FeatureBitset FeaturesSandyBridge =
87cfca06d7SDimitry Andric FeaturesWestmere | FeatureAVX | FeatureXSAVE | FeatureXSAVEOPT;
88b60736ecSDimitry Andric constexpr FeatureBitset FeaturesIvyBridge =
89cfca06d7SDimitry Andric FeaturesSandyBridge | FeatureF16C | FeatureFSGSBASE | FeatureRDRND;
90b60736ecSDimitry Andric constexpr FeatureBitset FeaturesHaswell =
91cfca06d7SDimitry Andric FeaturesIvyBridge | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureFMA |
92cfca06d7SDimitry Andric FeatureINVPCID | FeatureLZCNT | FeatureMOVBE;
93b60736ecSDimitry Andric constexpr FeatureBitset FeaturesBroadwell =
94cfca06d7SDimitry Andric FeaturesHaswell | FeatureADX | FeaturePRFCHW | FeatureRDSEED;
95cfca06d7SDimitry Andric
96cfca06d7SDimitry Andric // Intel Knights Landing and Knights Mill
97cfca06d7SDimitry Andric // Knights Landing has feature parity with Broadwell.
98ac9a064cSDimitry Andric constexpr FeatureBitset FeaturesKNL = FeaturesBroadwell | FeatureAES |
99ac9a064cSDimitry Andric FeatureAVX512F | FeatureEVEX512 |
100ac9a064cSDimitry Andric FeatureAVX512CD;
101b60736ecSDimitry Andric constexpr FeatureBitset FeaturesKNM = FeaturesKNL | FeatureAVX512VPOPCNTDQ;
102cfca06d7SDimitry Andric
103cfca06d7SDimitry Andric // Intel Skylake processors.
104b60736ecSDimitry Andric constexpr FeatureBitset FeaturesSkylakeClient =
105cfca06d7SDimitry Andric FeaturesBroadwell | FeatureAES | FeatureCLFLUSHOPT | FeatureXSAVEC |
106cfca06d7SDimitry Andric FeatureXSAVES | FeatureSGX;
107cfca06d7SDimitry Andric // SkylakeServer inherits all SkylakeClient features except SGX.
108cfca06d7SDimitry Andric // FIXME: That doesn't match gcc.
109b60736ecSDimitry Andric constexpr FeatureBitset FeaturesSkylakeServer =
110b1c73532SDimitry Andric (FeaturesSkylakeClient & ~FeatureSGX) | FeatureAVX512F | FeatureEVEX512 |
111b1c73532SDimitry Andric FeatureAVX512CD | FeatureAVX512DQ | FeatureAVX512BW | FeatureAVX512VL |
112b1c73532SDimitry Andric FeatureCLWB | FeaturePKU;
113b60736ecSDimitry Andric constexpr FeatureBitset FeaturesCascadeLake =
114cfca06d7SDimitry Andric FeaturesSkylakeServer | FeatureAVX512VNNI;
115b60736ecSDimitry Andric constexpr FeatureBitset FeaturesCooperLake =
116cfca06d7SDimitry Andric FeaturesCascadeLake | FeatureAVX512BF16;
117cfca06d7SDimitry Andric
118cfca06d7SDimitry Andric // Intel 10nm processors.
119b60736ecSDimitry Andric constexpr FeatureBitset FeaturesCannonlake =
120b1c73532SDimitry Andric FeaturesSkylakeClient | FeatureAVX512F | FeatureEVEX512 | FeatureAVX512CD |
121b1c73532SDimitry Andric FeatureAVX512DQ | FeatureAVX512BW | FeatureAVX512VL | FeatureAVX512IFMA |
122b1c73532SDimitry Andric FeatureAVX512VBMI | FeaturePKU | FeatureSHA;
123b60736ecSDimitry Andric constexpr FeatureBitset FeaturesICLClient =
124cfca06d7SDimitry Andric FeaturesCannonlake | FeatureAVX512BITALG | FeatureAVX512VBMI2 |
125344a3780SDimitry Andric FeatureAVX512VNNI | FeatureAVX512VPOPCNTDQ | FeatureGFNI | FeatureRDPID |
126344a3780SDimitry Andric FeatureVAES | FeatureVPCLMULQDQ;
127344a3780SDimitry Andric constexpr FeatureBitset FeaturesRocketlake = FeaturesICLClient & ~FeatureSGX;
128b60736ecSDimitry Andric constexpr FeatureBitset FeaturesICLServer =
129344a3780SDimitry Andric FeaturesICLClient | FeatureCLWB | FeaturePCONFIG | FeatureWBNOINVD;
130b60736ecSDimitry Andric constexpr FeatureBitset FeaturesTigerlake =
131cfca06d7SDimitry Andric FeaturesICLClient | FeatureAVX512VP2INTERSECT | FeatureMOVDIR64B |
132344a3780SDimitry Andric FeatureCLWB | FeatureMOVDIRI | FeatureSHSTK | FeatureKL | FeatureWIDEKL;
133b60736ecSDimitry Andric constexpr FeatureBitset FeaturesSapphireRapids =
134c0981da4SDimitry Andric FeaturesICLServer | FeatureAMX_BF16 | FeatureAMX_INT8 | FeatureAMX_TILE |
135e3b55780SDimitry Andric FeatureAVX512BF16 | FeatureAVX512FP16 | FeatureAVXVNNI | FeatureCLDEMOTE |
136e3b55780SDimitry Andric FeatureENQCMD | FeatureMOVDIR64B | FeatureMOVDIRI | FeaturePTWRITE |
137e3b55780SDimitry Andric FeatureSERIALIZE | FeatureSHSTK | FeatureTSXLDTRK | FeatureUINTR |
138e3b55780SDimitry Andric FeatureWAITPKG;
139e3b55780SDimitry Andric constexpr FeatureBitset FeaturesGraniteRapids =
140e3b55780SDimitry Andric FeaturesSapphireRapids | FeatureAMX_FP16 | FeaturePREFETCHI;
141cfca06d7SDimitry Andric
142cfca06d7SDimitry Andric // Intel Atom processors.
143cfca06d7SDimitry Andric // Bonnell has feature parity with Core2 and adds MOVBE.
144b60736ecSDimitry Andric constexpr FeatureBitset FeaturesBonnell = FeaturesCore2 | FeatureMOVBE;
145cfca06d7SDimitry Andric // Silvermont has parity with Westmere and Bonnell plus PRFCHW and RDRND.
146b60736ecSDimitry Andric constexpr FeatureBitset FeaturesSilvermont =
147cfca06d7SDimitry Andric FeaturesBonnell | FeaturesWestmere | FeaturePRFCHW | FeatureRDRND;
148b60736ecSDimitry Andric constexpr FeatureBitset FeaturesGoldmont =
149cfca06d7SDimitry Andric FeaturesSilvermont | FeatureAES | FeatureCLFLUSHOPT | FeatureFSGSBASE |
150cfca06d7SDimitry Andric FeatureRDSEED | FeatureSHA | FeatureXSAVE | FeatureXSAVEC |
151cfca06d7SDimitry Andric FeatureXSAVEOPT | FeatureXSAVES;
152b60736ecSDimitry Andric constexpr FeatureBitset FeaturesGoldmontPlus =
153cfca06d7SDimitry Andric FeaturesGoldmont | FeaturePTWRITE | FeatureRDPID | FeatureSGX;
154b60736ecSDimitry Andric constexpr FeatureBitset FeaturesTremont =
155cfca06d7SDimitry Andric FeaturesGoldmontPlus | FeatureCLWB | FeatureGFNI;
156344a3780SDimitry Andric constexpr FeatureBitset FeaturesAlderlake =
157344a3780SDimitry Andric FeaturesTremont | FeatureADX | FeatureBMI | FeatureBMI2 | FeatureF16C |
158344a3780SDimitry Andric FeatureFMA | FeatureINVPCID | FeatureLZCNT | FeaturePCONFIG | FeaturePKU |
159344a3780SDimitry Andric FeatureSERIALIZE | FeatureSHSTK | FeatureVAES | FeatureVPCLMULQDQ |
160344a3780SDimitry Andric FeatureCLDEMOTE | FeatureMOVDIR64B | FeatureMOVDIRI | FeatureWAITPKG |
161344a3780SDimitry Andric FeatureAVXVNNI | FeatureHRESET | FeatureWIDEKL;
162e3b55780SDimitry Andric constexpr FeatureBitset FeaturesSierraforest =
1637fa27ce4SDimitry Andric FeaturesAlderlake | FeatureCMPCCXADD | FeatureAVXIFMA | FeatureUINTR |
1647fa27ce4SDimitry Andric FeatureENQCMD | FeatureAVXNECONVERT | FeatureAVXVNNIINT8;
165b1c73532SDimitry Andric constexpr FeatureBitset FeaturesArrowlakeS = FeaturesSierraforest |
166b1c73532SDimitry Andric FeatureAVXVNNIINT16 | FeatureSHA512 | FeatureSM3 | FeatureSM4;
167b1c73532SDimitry Andric constexpr FeatureBitset FeaturesPantherlake =
168b1c73532SDimitry Andric FeaturesArrowlakeS | FeaturePREFETCHI;
169b1c73532SDimitry Andric constexpr FeatureBitset FeaturesClearwaterforest =
170b1c73532SDimitry Andric FeaturesArrowlakeS | FeatureUSERMSR | FeaturePREFETCHI;
171cfca06d7SDimitry Andric
172cfca06d7SDimitry Andric // Geode Processor.
173b60736ecSDimitry Andric constexpr FeatureBitset FeaturesGeode =
174ac9a064cSDimitry Andric FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | FeaturePRFCHW;
175cfca06d7SDimitry Andric
176cfca06d7SDimitry Andric // K6 processor.
177b60736ecSDimitry Andric constexpr FeatureBitset FeaturesK6 = FeatureX87 | FeatureCMPXCHG8B | FeatureMMX;
178cfca06d7SDimitry Andric
179cfca06d7SDimitry Andric // K7 and K8 architecture processors.
180b60736ecSDimitry Andric constexpr FeatureBitset FeaturesAthlon =
181ac9a064cSDimitry Andric FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | FeaturePRFCHW;
182b60736ecSDimitry Andric constexpr FeatureBitset FeaturesAthlonXP =
183cfca06d7SDimitry Andric FeaturesAthlon | FeatureFXSR | FeatureSSE;
184b60736ecSDimitry Andric constexpr FeatureBitset FeaturesK8 =
185cfca06d7SDimitry Andric FeaturesAthlonXP | FeatureSSE2 | Feature64BIT;
186b60736ecSDimitry Andric constexpr FeatureBitset FeaturesK8SSE3 = FeaturesK8 | FeatureSSE3;
187b60736ecSDimitry Andric constexpr FeatureBitset FeaturesAMDFAM10 =
188cfca06d7SDimitry Andric FeaturesK8SSE3 | FeatureCMPXCHG16B | FeatureLZCNT | FeaturePOPCNT |
189cfca06d7SDimitry Andric FeaturePRFCHW | FeatureSAHF | FeatureSSE4_A;
190cfca06d7SDimitry Andric
191cfca06d7SDimitry Andric // Bobcat architecture processors.
192b60736ecSDimitry Andric constexpr FeatureBitset FeaturesBTVER1 =
193cfca06d7SDimitry Andric FeatureX87 | FeatureCMPXCHG8B | FeatureCMPXCHG16B | Feature64BIT |
194cfca06d7SDimitry Andric FeatureFXSR | FeatureLZCNT | FeatureMMX | FeaturePOPCNT | FeaturePRFCHW |
195cfca06d7SDimitry Andric FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_A |
196cfca06d7SDimitry Andric FeatureSAHF;
197b60736ecSDimitry Andric constexpr FeatureBitset FeaturesBTVER2 =
198c0981da4SDimitry Andric FeaturesBTVER1 | FeatureAES | FeatureAVX | FeatureBMI | FeatureCRC32 |
199c0981da4SDimitry Andric FeatureF16C | FeatureMOVBE | FeaturePCLMUL | FeatureXSAVE | FeatureXSAVEOPT;
200cfca06d7SDimitry Andric
201cfca06d7SDimitry Andric // AMD Bulldozer architecture processors.
202b60736ecSDimitry Andric constexpr FeatureBitset FeaturesBDVER1 =
203cfca06d7SDimitry Andric FeatureX87 | FeatureAES | FeatureAVX | FeatureCMPXCHG8B |
204c0981da4SDimitry Andric FeatureCMPXCHG16B | FeatureCRC32 | Feature64BIT | FeatureFMA4 |
205c0981da4SDimitry Andric FeatureFXSR | FeatureLWP | FeatureLZCNT | FeatureMMX | FeaturePCLMUL |
206c0981da4SDimitry Andric FeaturePOPCNT | FeaturePRFCHW | FeatureSAHF | FeatureSSE | FeatureSSE2 |
207c0981da4SDimitry Andric FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 | FeatureSSE4_2 | FeatureSSE4_A |
208c0981da4SDimitry Andric FeatureXOP | FeatureXSAVE;
209b60736ecSDimitry Andric constexpr FeatureBitset FeaturesBDVER2 =
210cfca06d7SDimitry Andric FeaturesBDVER1 | FeatureBMI | FeatureFMA | FeatureF16C | FeatureTBM;
211b60736ecSDimitry Andric constexpr FeatureBitset FeaturesBDVER3 =
212cfca06d7SDimitry Andric FeaturesBDVER2 | FeatureFSGSBASE | FeatureXSAVEOPT;
213b60736ecSDimitry Andric constexpr FeatureBitset FeaturesBDVER4 = FeaturesBDVER3 | FeatureAVX2 |
214b60736ecSDimitry Andric FeatureBMI2 | FeatureMOVBE |
215b60736ecSDimitry Andric FeatureMWAITX | FeatureRDRND;
216cfca06d7SDimitry Andric
217cfca06d7SDimitry Andric // AMD Zen architecture processors.
218b60736ecSDimitry Andric constexpr FeatureBitset FeaturesZNVER1 =
219cfca06d7SDimitry Andric FeatureX87 | FeatureADX | FeatureAES | FeatureAVX | FeatureAVX2 |
220cfca06d7SDimitry Andric FeatureBMI | FeatureBMI2 | FeatureCLFLUSHOPT | FeatureCLZERO |
221c0981da4SDimitry Andric FeatureCMPXCHG8B | FeatureCMPXCHG16B | FeatureCRC32 | Feature64BIT |
222c0981da4SDimitry Andric FeatureF16C | FeatureFMA | FeatureFSGSBASE | FeatureFXSR | FeatureLZCNT |
223c0981da4SDimitry Andric FeatureMMX | FeatureMOVBE | FeatureMWAITX | FeaturePCLMUL | FeaturePOPCNT |
224cfca06d7SDimitry Andric FeaturePRFCHW | FeatureRDRND | FeatureRDSEED | FeatureSAHF | FeatureSHA |
225cfca06d7SDimitry Andric FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 |
226cfca06d7SDimitry Andric FeatureSSE4_2 | FeatureSSE4_A | FeatureXSAVE | FeatureXSAVEC |
227cfca06d7SDimitry Andric FeatureXSAVEOPT | FeatureXSAVES;
2281f917f69SDimitry Andric constexpr FeatureBitset FeaturesZNVER2 = FeaturesZNVER1 | FeatureCLWB |
2291f917f69SDimitry Andric FeatureRDPID | FeatureRDPRU |
2301f917f69SDimitry Andric FeatureWBNOINVD;
231b60736ecSDimitry Andric static constexpr FeatureBitset FeaturesZNVER3 = FeaturesZNVER2 |
232b60736ecSDimitry Andric FeatureINVPCID | FeaturePKU |
233b60736ecSDimitry Andric FeatureVAES | FeatureVPCLMULQDQ;
234e3b55780SDimitry Andric static constexpr FeatureBitset FeaturesZNVER4 =
235b1c73532SDimitry Andric FeaturesZNVER3 | FeatureAVX512F | FeatureEVEX512 | FeatureAVX512CD |
236b1c73532SDimitry Andric FeatureAVX512DQ | FeatureAVX512BW | FeatureAVX512VL | FeatureAVX512IFMA |
237b1c73532SDimitry Andric FeatureAVX512VBMI | FeatureAVX512VBMI2 | FeatureAVX512VNNI |
238b1c73532SDimitry Andric FeatureAVX512BITALG | FeatureAVX512VPOPCNTDQ | FeatureAVX512BF16 |
239b1c73532SDimitry Andric FeatureGFNI | FeatureSHSTK;
240cfca06d7SDimitry Andric
2411de139fdSDimitry Andric static constexpr FeatureBitset FeaturesZNVER5 =
2421de139fdSDimitry Andric FeaturesZNVER4 | FeatureAVXVNNI | FeatureMOVDIRI | FeatureMOVDIR64B |
2431de139fdSDimitry Andric FeatureAVX512VP2INTERSECT | FeaturePREFETCHI | FeatureAVXVNNI;
2441de139fdSDimitry Andric
2457fa27ce4SDimitry Andric // D151696 tranplanted Mangling and OnlyForCPUDispatchSpecific from
2467fa27ce4SDimitry Andric // X86TargetParser.def to here. They are assigned by following ways:
2477fa27ce4SDimitry Andric // 1. Copy the mangling from the original CPU_SPEICIFC MACROs. If no, assign
2487fa27ce4SDimitry Andric // to '\0' by default, which means not support cpu_specific/dispatch feature.
2497fa27ce4SDimitry Andric // 2. set OnlyForCPUDispatchSpecific as true if this cpu name was not
2507fa27ce4SDimitry Andric // listed here before, which means it doesn't support -march, -mtune and so on.
2517fa27ce4SDimitry Andric // FIXME: Remove OnlyForCPUDispatchSpecific after all CPUs here support both
2527fa27ce4SDimitry Andric // cpu_dispatch/specific() feature and -march, -mtune, and so on.
253b1c73532SDimitry Andric // clang-format off
254b60736ecSDimitry Andric constexpr ProcInfo Processors[] = {
255cfca06d7SDimitry Andric // Empty processor. Include X87 and CMPXCHG8 for backwards compatibility.
2567fa27ce4SDimitry Andric { {""}, CK_None, ~0U, FeatureX87 | FeatureCMPXCHG8B, '\0', false },
2577fa27ce4SDimitry Andric { {"generic"}, CK_None, ~0U, FeatureX87 | FeatureCMPXCHG8B | Feature64BIT, 'A', true },
258cfca06d7SDimitry Andric // i386-generation processors.
2597fa27ce4SDimitry Andric { {"i386"}, CK_i386, ~0U, FeatureX87, '\0', false },
260cfca06d7SDimitry Andric // i486-generation processors.
2617fa27ce4SDimitry Andric { {"i486"}, CK_i486, ~0U, FeatureX87, '\0', false },
2627fa27ce4SDimitry Andric { {"winchip-c6"}, CK_WinChipC6, ~0U, FeaturesPentiumMMX, '\0', false },
263ac9a064cSDimitry Andric { {"winchip2"}, CK_WinChip2, ~0U, FeaturesPentiumMMX | FeaturePRFCHW, '\0', false },
264ac9a064cSDimitry Andric { {"c3"}, CK_C3, ~0U, FeaturesPentiumMMX | FeaturePRFCHW, '\0', false },
265cfca06d7SDimitry Andric // i586-generation processors, P5 microarchitecture based.
2667fa27ce4SDimitry Andric { {"i586"}, CK_i586, ~0U, FeatureX87 | FeatureCMPXCHG8B, '\0', false },
2677fa27ce4SDimitry Andric { {"pentium"}, CK_Pentium, ~0U, FeatureX87 | FeatureCMPXCHG8B, 'B', false },
2687fa27ce4SDimitry Andric { {"pentium-mmx"}, CK_PentiumMMX, ~0U, FeaturesPentiumMMX, '\0', false },
2697fa27ce4SDimitry Andric { {"pentium_mmx"}, CK_PentiumMMX, ~0U, FeaturesPentiumMMX, 'D', true },
270cfca06d7SDimitry Andric // i686-generation processors, P6 / Pentium M microarchitecture based.
2717fa27ce4SDimitry Andric { {"pentiumpro"}, CK_PentiumPro, ~0U, FeatureCMOV | FeatureX87 | FeatureCMPXCHG8B, 'C', false },
2727fa27ce4SDimitry Andric { {"pentium_pro"}, CK_PentiumPro, ~0U, FeatureCMOV | FeatureX87 | FeatureCMPXCHG8B, 'C', true },
2737fa27ce4SDimitry Andric { {"i686"}, CK_i686, ~0U, FeatureCMOV | FeatureX87 | FeatureCMPXCHG8B, '\0', false },
2747fa27ce4SDimitry Andric { {"pentium2"}, CK_Pentium2, ~0U, FeaturesPentium2, 'E', false },
2757fa27ce4SDimitry Andric { {"pentium_ii"}, CK_Pentium2, ~0U, FeaturesPentium2, 'E', true },
2767fa27ce4SDimitry Andric { {"pentium3"}, CK_Pentium3, ~0U, FeaturesPentium3, 'H', false },
2777fa27ce4SDimitry Andric { {"pentium3m"}, CK_Pentium3, ~0U, FeaturesPentium3, 'H', false },
2787fa27ce4SDimitry Andric { {"pentium_iii"}, CK_Pentium3, ~0U, FeaturesPentium3, 'H', true },
2797fa27ce4SDimitry Andric { {"pentium_iii_no_xmm_regs"}, CK_Pentium3, ~0U, FeaturesPentium3, 'H', true },
2807fa27ce4SDimitry Andric { {"pentium-m"}, CK_PentiumM, ~0U, FeaturesPentium4, '\0', false },
2817fa27ce4SDimitry Andric { {"pentium_m"}, CK_PentiumM, ~0U, FeaturesPentium4, 'K', true },
2827fa27ce4SDimitry Andric { {"c3-2"}, CK_C3_2, ~0U, FeaturesPentium3, '\0', false },
2837fa27ce4SDimitry Andric { {"yonah"}, CK_Yonah, ~0U, FeaturesPrescott, 'L', false },
284cfca06d7SDimitry Andric // Netburst microarchitecture based processors.
2857fa27ce4SDimitry Andric { {"pentium4"}, CK_Pentium4, ~0U, FeaturesPentium4, 'J', false },
2867fa27ce4SDimitry Andric { {"pentium4m"}, CK_Pentium4, ~0U, FeaturesPentium4, 'J', false },
2877fa27ce4SDimitry Andric { {"pentium_4"}, CK_Pentium4, ~0U, FeaturesPentium4, 'J', true },
2887fa27ce4SDimitry Andric { {"pentium_4_sse3"}, CK_Prescott, ~0U, FeaturesPrescott, 'L', true },
2897fa27ce4SDimitry Andric { {"prescott"}, CK_Prescott, ~0U, FeaturesPrescott, 'L', false },
2907fa27ce4SDimitry Andric { {"nocona"}, CK_Nocona, ~0U, FeaturesNocona, 'L', false },
291cfca06d7SDimitry Andric // Core microarchitecture based processors.
2927fa27ce4SDimitry Andric { {"core2"}, CK_Core2, FEATURE_SSSE3, FeaturesCore2, 'M', false },
2937fa27ce4SDimitry Andric { {"core_2_duo_ssse3"}, CK_Core2, ~0U, FeaturesCore2, 'M', true },
2947fa27ce4SDimitry Andric { {"penryn"}, CK_Penryn, ~0U, FeaturesPenryn, 'N', false },
2957fa27ce4SDimitry Andric { {"core_2_duo_sse4_1"}, CK_Penryn, ~0U, FeaturesPenryn, 'N', true },
296cfca06d7SDimitry Andric // Atom processors
2977fa27ce4SDimitry Andric { {"bonnell"}, CK_Bonnell, FEATURE_SSSE3, FeaturesBonnell, 'O', false },
2987fa27ce4SDimitry Andric { {"atom"}, CK_Bonnell, FEATURE_SSSE3, FeaturesBonnell, 'O', false },
2997fa27ce4SDimitry Andric { {"silvermont"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont, 'c', false },
3007fa27ce4SDimitry Andric { {"slm"}, CK_Silvermont, FEATURE_SSE4_2, FeaturesSilvermont, 'c', false },
3017fa27ce4SDimitry Andric { {"atom_sse4_2"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem, 'c', true },
3027fa27ce4SDimitry Andric { {"atom_sse4_2_movbe"}, CK_Goldmont, FEATURE_SSE4_2, FeaturesGoldmont, 'd', true },
3037fa27ce4SDimitry Andric { {"goldmont"}, CK_Goldmont, FEATURE_SSE4_2, FeaturesGoldmont, 'i', false },
3047fa27ce4SDimitry Andric { {"goldmont-plus"}, CK_GoldmontPlus, FEATURE_SSE4_2, FeaturesGoldmontPlus, '\0', false },
3057fa27ce4SDimitry Andric { {"goldmont_plus"}, CK_GoldmontPlus, FEATURE_SSE4_2, FeaturesGoldmontPlus, 'd', true },
3067fa27ce4SDimitry Andric { {"tremont"}, CK_Tremont, FEATURE_SSE4_2, FeaturesTremont, 'd', false },
307cfca06d7SDimitry Andric // Nehalem microarchitecture based processors.
3087fa27ce4SDimitry Andric { {"nehalem"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem, 'P', false },
3097fa27ce4SDimitry Andric { {"core_i7_sse4_2"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem, 'P', true },
3107fa27ce4SDimitry Andric { {"corei7"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem, 'P', false },
311cfca06d7SDimitry Andric // Westmere microarchitecture based processors.
3127fa27ce4SDimitry Andric { {"westmere"}, CK_Westmere, FEATURE_PCLMUL, FeaturesWestmere, 'Q', false },
3137fa27ce4SDimitry Andric { {"core_aes_pclmulqdq"}, CK_Nehalem, FEATURE_SSE4_2, FeaturesNehalem, 'Q', true },
314cfca06d7SDimitry Andric // Sandy Bridge microarchitecture based processors.
3157fa27ce4SDimitry Andric { {"sandybridge"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge, 'R', false },
3167fa27ce4SDimitry Andric { {"core_2nd_gen_avx"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge, 'R', true },
3177fa27ce4SDimitry Andric { {"corei7-avx"}, CK_SandyBridge, FEATURE_AVX, FeaturesSandyBridge, '\0', false },
318cfca06d7SDimitry Andric // Ivy Bridge microarchitecture based processors.
3197fa27ce4SDimitry Andric { {"ivybridge"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge, 'S', false },
3207fa27ce4SDimitry Andric { {"core_3rd_gen_avx"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge, 'S', true },
3217fa27ce4SDimitry Andric { {"core-avx-i"}, CK_IvyBridge, FEATURE_AVX, FeaturesIvyBridge, '\0', false },
322cfca06d7SDimitry Andric // Haswell microarchitecture based processors.
3237fa27ce4SDimitry Andric { {"haswell"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell, 'V', false },
3247fa27ce4SDimitry Andric { {"core-avx2"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell, '\0', false },
3257fa27ce4SDimitry Andric { {"core_4th_gen_avx"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell, 'V', true },
3267fa27ce4SDimitry Andric { {"core_4th_gen_avx_tsx"}, CK_Haswell, FEATURE_AVX2, FeaturesHaswell, 'W', true },
327cfca06d7SDimitry Andric // Broadwell microarchitecture based processors.
3287fa27ce4SDimitry Andric { {"broadwell"}, CK_Broadwell, FEATURE_AVX2, FeaturesBroadwell, 'X', false },
3297fa27ce4SDimitry Andric { {"core_5th_gen_avx"}, CK_Broadwell, FEATURE_AVX2, FeaturesBroadwell, 'X', true },
3307fa27ce4SDimitry Andric { {"core_5th_gen_avx_tsx"}, CK_Broadwell, FEATURE_AVX2, FeaturesBroadwell, 'Y', true },
331cfca06d7SDimitry Andric // Skylake client microarchitecture based processors.
3327fa27ce4SDimitry Andric { {"skylake"}, CK_SkylakeClient, FEATURE_AVX2, FeaturesSkylakeClient, 'b', false },
333cfca06d7SDimitry Andric // Skylake server microarchitecture based processors.
3347fa27ce4SDimitry Andric { {"skylake-avx512"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer, '\0', false },
3357fa27ce4SDimitry Andric { {"skx"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer, 'a', false },
3367fa27ce4SDimitry Andric { {"skylake_avx512"}, CK_SkylakeServer, FEATURE_AVX512F, FeaturesSkylakeServer, 'a', true },
337cfca06d7SDimitry Andric // Cascadelake Server microarchitecture based processors.
3387fa27ce4SDimitry Andric { {"cascadelake"}, CK_Cascadelake, FEATURE_AVX512VNNI, FeaturesCascadeLake, 'o', false },
339cfca06d7SDimitry Andric // Cooperlake Server microarchitecture based processors.
3407fa27ce4SDimitry Andric { {"cooperlake"}, CK_Cooperlake, FEATURE_AVX512BF16, FeaturesCooperLake, 'f', false },
341cfca06d7SDimitry Andric // Cannonlake client microarchitecture based processors.
3427fa27ce4SDimitry Andric { {"cannonlake"}, CK_Cannonlake, FEATURE_AVX512VBMI, FeaturesCannonlake, 'e', false },
343cfca06d7SDimitry Andric // Icelake client microarchitecture based processors.
3447fa27ce4SDimitry Andric { {"icelake-client"}, CK_IcelakeClient, FEATURE_AVX512VBMI2, FeaturesICLClient, '\0', false },
3457fa27ce4SDimitry Andric { {"icelake_client"}, CK_IcelakeClient, FEATURE_AVX512VBMI2, FeaturesICLClient, 'k', true },
346344a3780SDimitry Andric // Rocketlake microarchitecture based processors.
3477fa27ce4SDimitry Andric { {"rocketlake"}, CK_Rocketlake, FEATURE_AVX512VBMI2, FeaturesRocketlake, 'k', false },
348cfca06d7SDimitry Andric // Icelake server microarchitecture based processors.
3497fa27ce4SDimitry Andric { {"icelake-server"}, CK_IcelakeServer, FEATURE_AVX512VBMI2, FeaturesICLServer, '\0', false },
3507fa27ce4SDimitry Andric { {"icelake_server"}, CK_IcelakeServer, FEATURE_AVX512VBMI2, FeaturesICLServer, 'k', true },
351cfca06d7SDimitry Andric // Tigerlake microarchitecture based processors.
3527fa27ce4SDimitry Andric { {"tigerlake"}, CK_Tigerlake, FEATURE_AVX512VP2INTERSECT, FeaturesTigerlake, 'l', false },
353b60736ecSDimitry Andric // Sapphire Rapids microarchitecture based processors.
3544df029ccSDimitry Andric { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512FP16, FeaturesSapphireRapids, 'n', false },
355b60736ecSDimitry Andric // Alderlake microarchitecture based processors.
3567fa27ce4SDimitry Andric { {"alderlake"}, CK_Alderlake, FEATURE_AVX2, FeaturesAlderlake, 'p', false },
357e3b55780SDimitry Andric // Raptorlake microarchitecture based processors.
3587fa27ce4SDimitry Andric { {"raptorlake"}, CK_Raptorlake, FEATURE_AVX2, FeaturesAlderlake, 'p', false },
359e3b55780SDimitry Andric // Meteorlake microarchitecture based processors.
3607fa27ce4SDimitry Andric { {"meteorlake"}, CK_Meteorlake, FEATURE_AVX2, FeaturesAlderlake, 'p', false },
361b1c73532SDimitry Andric // Arrowlake microarchitecture based processors.
362b1c73532SDimitry Andric { {"arrowlake"}, CK_Arrowlake, FEATURE_AVX2, FeaturesSierraforest, 'p', false },
363b1c73532SDimitry Andric { {"arrowlake-s"}, CK_ArrowlakeS, FEATURE_AVX2, FeaturesArrowlakeS, '\0', false },
364b1c73532SDimitry Andric { {"arrowlake_s"}, CK_ArrowlakeS, FEATURE_AVX2, FeaturesArrowlakeS, 'p', true },
365b1c73532SDimitry Andric // Lunarlake microarchitecture based processors.
366b1c73532SDimitry Andric { {"lunarlake"}, CK_Lunarlake, FEATURE_AVX2, FeaturesArrowlakeS, 'p', false },
367b1c73532SDimitry Andric // Gracemont microarchitecture based processors.
368b1c73532SDimitry Andric { {"gracemont"}, CK_Gracemont, FEATURE_AVX2, FeaturesAlderlake, 'p', false },
369b1c73532SDimitry Andric // Pantherlake microarchitecture based processors.
370b1c73532SDimitry Andric { {"pantherlake"}, CK_Lunarlake, FEATURE_AVX2, FeaturesPantherlake, 'p', false },
371e3b55780SDimitry Andric // Sierraforest microarchitecture based processors.
3727fa27ce4SDimitry Andric { {"sierraforest"}, CK_Sierraforest, FEATURE_AVX2, FeaturesSierraforest, 'p', false },
373e3b55780SDimitry Andric // Grandridge microarchitecture based processors.
37477dbea07SDimitry Andric { {"grandridge"}, CK_Grandridge, FEATURE_AVX2, FeaturesSierraforest, 'p', false },
375e3b55780SDimitry Andric // Granite Rapids microarchitecture based processors.
3764df029ccSDimitry Andric { {"graniterapids"}, CK_Graniterapids, FEATURE_AVX512FP16, FeaturesGraniteRapids, 'n', false },
3777fa27ce4SDimitry Andric // Granite Rapids D microarchitecture based processors.
3784df029ccSDimitry Andric { {"graniterapids-d"}, CK_GraniterapidsD, FEATURE_AVX512FP16, FeaturesGraniteRapids | FeatureAMX_COMPLEX, '\0', false },
3794df029ccSDimitry Andric { {"graniterapids_d"}, CK_GraniterapidsD, FEATURE_AVX512FP16, FeaturesGraniteRapids | FeatureAMX_COMPLEX, 'n', true },
380e3b55780SDimitry Andric // Emerald Rapids microarchitecture based processors.
3814df029ccSDimitry Andric { {"emeraldrapids"}, CK_Emeraldrapids, FEATURE_AVX512FP16, FeaturesSapphireRapids, 'n', false },
382b1c73532SDimitry Andric // Clearwaterforest microarchitecture based processors.
383b1c73532SDimitry Andric { {"clearwaterforest"}, CK_Lunarlake, FEATURE_AVX2, FeaturesClearwaterforest, 'p', false },
384cfca06d7SDimitry Andric // Knights Landing processor.
3857fa27ce4SDimitry Andric { {"knl"}, CK_KNL, FEATURE_AVX512F, FeaturesKNL, 'Z', false },
3867fa27ce4SDimitry Andric { {"mic_avx512"}, CK_KNL, FEATURE_AVX512F, FeaturesKNL, 'Z', true },
387cfca06d7SDimitry Andric // Knights Mill processor.
3887fa27ce4SDimitry Andric { {"knm"}, CK_KNM, FEATURE_AVX5124FMAPS, FeaturesKNM, 'j', false },
389cfca06d7SDimitry Andric // Lakemont microarchitecture based processors.
3907fa27ce4SDimitry Andric { {"lakemont"}, CK_Lakemont, ~0U, FeatureCMPXCHG8B, '\0', false },
391cfca06d7SDimitry Andric // K6 architecture processors.
3927fa27ce4SDimitry Andric { {"k6"}, CK_K6, ~0U, FeaturesK6, '\0', false },
393ac9a064cSDimitry Andric { {"k6-2"}, CK_K6_2, ~0U, FeaturesK6 | FeaturePRFCHW, '\0', false },
394ac9a064cSDimitry Andric { {"k6-3"}, CK_K6_3, ~0U, FeaturesK6 | FeaturePRFCHW, '\0', false },
395cfca06d7SDimitry Andric // K7 architecture processors.
3967fa27ce4SDimitry Andric { {"athlon"}, CK_Athlon, ~0U, FeaturesAthlon, '\0', false },
3977fa27ce4SDimitry Andric { {"athlon-tbird"}, CK_Athlon, ~0U, FeaturesAthlon, '\0', false },
3987fa27ce4SDimitry Andric { {"athlon-xp"}, CK_AthlonXP, ~0U, FeaturesAthlonXP, '\0', false },
3997fa27ce4SDimitry Andric { {"athlon-mp"}, CK_AthlonXP, ~0U, FeaturesAthlonXP, '\0', false },
4007fa27ce4SDimitry Andric { {"athlon-4"}, CK_AthlonXP, ~0U, FeaturesAthlonXP, '\0', false },
401cfca06d7SDimitry Andric // K8 architecture processors.
4027fa27ce4SDimitry Andric { {"k8"}, CK_K8, ~0U, FeaturesK8, '\0', false },
4037fa27ce4SDimitry Andric { {"athlon64"}, CK_K8, ~0U, FeaturesK8, '\0', false },
4047fa27ce4SDimitry Andric { {"athlon-fx"}, CK_K8, ~0U, FeaturesK8, '\0', false },
4057fa27ce4SDimitry Andric { {"opteron"}, CK_K8, ~0U, FeaturesK8, '\0', false },
4067fa27ce4SDimitry Andric { {"k8-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3, '\0', false },
4077fa27ce4SDimitry Andric { {"athlon64-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3, '\0', false },
4087fa27ce4SDimitry Andric { {"opteron-sse3"}, CK_K8SSE3, ~0U, FeaturesK8SSE3, '\0', false },
4097fa27ce4SDimitry Andric { {"amdfam10"}, CK_AMDFAM10, FEATURE_SSE4_A, FeaturesAMDFAM10, '\0', false },
4107fa27ce4SDimitry Andric { {"barcelona"}, CK_AMDFAM10, FEATURE_SSE4_A, FeaturesAMDFAM10, '\0', false },
411cfca06d7SDimitry Andric // Bobcat architecture processors.
4127fa27ce4SDimitry Andric { {"btver1"}, CK_BTVER1, FEATURE_SSE4_A, FeaturesBTVER1, '\0', false },
4137fa27ce4SDimitry Andric { {"btver2"}, CK_BTVER2, FEATURE_BMI, FeaturesBTVER2, '\0', false },
414cfca06d7SDimitry Andric // Bulldozer architecture processors.
4157fa27ce4SDimitry Andric { {"bdver1"}, CK_BDVER1, FEATURE_XOP, FeaturesBDVER1, '\0', false },
4167fa27ce4SDimitry Andric { {"bdver2"}, CK_BDVER2, FEATURE_FMA, FeaturesBDVER2, '\0', false },
4177fa27ce4SDimitry Andric { {"bdver3"}, CK_BDVER3, FEATURE_FMA, FeaturesBDVER3, '\0', false },
4187fa27ce4SDimitry Andric { {"bdver4"}, CK_BDVER4, FEATURE_AVX2, FeaturesBDVER4, '\0', false },
419cfca06d7SDimitry Andric // Zen architecture processors.
4207fa27ce4SDimitry Andric { {"znver1"}, CK_ZNVER1, FEATURE_AVX2, FeaturesZNVER1, '\0', false },
4217fa27ce4SDimitry Andric { {"znver2"}, CK_ZNVER2, FEATURE_AVX2, FeaturesZNVER2, '\0', false },
4227fa27ce4SDimitry Andric { {"znver3"}, CK_ZNVER3, FEATURE_AVX2, FeaturesZNVER3, '\0', false },
4237fa27ce4SDimitry Andric { {"znver4"}, CK_ZNVER4, FEATURE_AVX512VBMI2, FeaturesZNVER4, '\0', false },
4241de139fdSDimitry Andric { {"znver5"}, CK_ZNVER5, FEATURE_AVX512VP2INTERSECT, FeaturesZNVER5, '\0', false },
425cfca06d7SDimitry Andric // Generic 64-bit processor.
426b1c73532SDimitry Andric { {"x86-64"}, CK_x86_64, FEATURE_SSE2 , FeaturesX86_64, '\0', false },
427b1c73532SDimitry Andric { {"x86-64-v2"}, CK_x86_64_v2, FEATURE_SSE4_2 , FeaturesX86_64_V2, '\0', false },
428b1c73532SDimitry Andric { {"x86-64-v3"}, CK_x86_64_v3, FEATURE_AVX2, FeaturesX86_64_V3, '\0', false },
429b1c73532SDimitry Andric { {"x86-64-v4"}, CK_x86_64_v4, FEATURE_AVX512VL, FeaturesX86_64_V4, '\0', false },
430cfca06d7SDimitry Andric // Geode processors.
4317fa27ce4SDimitry Andric { {"geode"}, CK_Geode, ~0U, FeaturesGeode, '\0', false },
432cfca06d7SDimitry Andric };
433b1c73532SDimitry Andric // clang-format on
434cfca06d7SDimitry Andric
435b60736ecSDimitry Andric constexpr const char *NoTuneList[] = {"x86-64-v2", "x86-64-v3", "x86-64-v4"};
436b60736ecSDimitry Andric
parseArchX86(StringRef CPU,bool Only64Bit)437cfca06d7SDimitry Andric X86::CPUKind llvm::X86::parseArchX86(StringRef CPU, bool Only64Bit) {
438cfca06d7SDimitry Andric for (const auto &P : Processors)
4397fa27ce4SDimitry Andric if (!P.OnlyForCPUDispatchSpecific && P.Name == CPU &&
4407fa27ce4SDimitry Andric (P.Features[FEATURE_64BIT] || !Only64Bit))
441cfca06d7SDimitry Andric return P.Kind;
442cfca06d7SDimitry Andric
443cfca06d7SDimitry Andric return CK_None;
444cfca06d7SDimitry Andric }
445cfca06d7SDimitry Andric
parseTuneCPU(StringRef CPU,bool Only64Bit)446b60736ecSDimitry Andric X86::CPUKind llvm::X86::parseTuneCPU(StringRef CPU, bool Only64Bit) {
447b60736ecSDimitry Andric if (llvm::is_contained(NoTuneList, CPU))
448b60736ecSDimitry Andric return CK_None;
449b60736ecSDimitry Andric return parseArchX86(CPU, Only64Bit);
450b60736ecSDimitry Andric }
451b60736ecSDimitry Andric
fillValidCPUArchList(SmallVectorImpl<StringRef> & Values,bool Only64Bit)452cfca06d7SDimitry Andric void llvm::X86::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values,
453cfca06d7SDimitry Andric bool Only64Bit) {
454cfca06d7SDimitry Andric for (const auto &P : Processors)
4557fa27ce4SDimitry Andric if (!P.OnlyForCPUDispatchSpecific && !P.Name.empty() &&
4567fa27ce4SDimitry Andric (P.Features[FEATURE_64BIT] || !Only64Bit))
457cfca06d7SDimitry Andric Values.emplace_back(P.Name);
458cfca06d7SDimitry Andric }
459cfca06d7SDimitry Andric
fillValidTuneCPUList(SmallVectorImpl<StringRef> & Values,bool Only64Bit)460b60736ecSDimitry Andric void llvm::X86::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values,
461b60736ecSDimitry Andric bool Only64Bit) {
462b60736ecSDimitry Andric for (const ProcInfo &P : Processors)
4637fa27ce4SDimitry Andric if (!P.OnlyForCPUDispatchSpecific && !P.Name.empty() &&
4647fa27ce4SDimitry Andric (P.Features[FEATURE_64BIT] || !Only64Bit) &&
465b60736ecSDimitry Andric !llvm::is_contained(NoTuneList, P.Name))
466b60736ecSDimitry Andric Values.emplace_back(P.Name);
467b60736ecSDimitry Andric }
468b60736ecSDimitry Andric
getKeyFeature(X86::CPUKind Kind)469cfca06d7SDimitry Andric ProcessorFeatures llvm::X86::getKeyFeature(X86::CPUKind Kind) {
470cfca06d7SDimitry Andric // FIXME: Can we avoid a linear search here? The table might be sorted by
471cfca06d7SDimitry Andric // CPUKind so we could binary search?
472cfca06d7SDimitry Andric for (const auto &P : Processors) {
473cfca06d7SDimitry Andric if (P.Kind == Kind) {
474cfca06d7SDimitry Andric assert(P.KeyFeature != ~0U && "Processor does not have a key feature.");
475cfca06d7SDimitry Andric return static_cast<ProcessorFeatures>(P.KeyFeature);
476cfca06d7SDimitry Andric }
477cfca06d7SDimitry Andric }
478cfca06d7SDimitry Andric
479cfca06d7SDimitry Andric llvm_unreachable("Unable to find CPU kind!");
480cfca06d7SDimitry Andric }
481cfca06d7SDimitry Andric
482cfca06d7SDimitry Andric // Features with no dependencies.
483b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeatures64BIT = {};
484b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesADX = {};
485b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesBMI = {};
486b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesBMI2 = {};
487b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesCLDEMOTE = {};
488b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesCLFLUSHOPT = {};
489b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesCLWB = {};
490b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesCLZERO = {};
491b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesCMOV = {};
492b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesCMPXCHG16B = {};
493b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesCMPXCHG8B = {};
494c0981da4SDimitry Andric constexpr FeatureBitset ImpliedFeaturesCRC32 = {};
495b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesENQCMD = {};
496b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesFSGSBASE = {};
497b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesFXSR = {};
498b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesINVPCID = {};
499b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesLWP = {};
500b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesLZCNT = {};
501ac9a064cSDimitry Andric constexpr FeatureBitset ImpliedFeaturesMMX = {};
502b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesMWAITX = {};
503b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesMOVBE = {};
504b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesMOVDIR64B = {};
505b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesMOVDIRI = {};
506b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesPCONFIG = {};
507b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesPOPCNT = {};
508b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesPKU = {};
509b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesPRFCHW = {};
510b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesPTWRITE = {};
511b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesRDPID = {};
5121f917f69SDimitry Andric constexpr FeatureBitset ImpliedFeaturesRDPRU = {};
513b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesRDRND = {};
514b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesRDSEED = {};
515b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesRTM = {};
516b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSAHF = {};
517b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSERIALIZE = {};
518b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSGX = {};
519b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSHSTK = {};
520b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesTBM = {};
521b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesTSXLDTRK = {};
522b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesUINTR = {};
523b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesUSERMSR = {};
524b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesWAITPKG = {};
525b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesWBNOINVD = {};
526b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesVZEROUPPER = {};
527b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesX87 = {};
528b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesXSAVE = {};
529ac9a064cSDimitry Andric constexpr FeatureBitset ImpliedFeaturesDUMMYFEATURE1 = {};
530ac9a064cSDimitry Andric constexpr FeatureBitset ImpliedFeaturesDUMMYFEATURE2 = {};
531cfca06d7SDimitry Andric
532cfca06d7SDimitry Andric // Not really CPU features, but need to be in the table because clang uses
533cfca06d7SDimitry Andric // target features to communicate them to the backend.
534b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesRETPOLINE_EXTERNAL_THUNK = {};
535b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_BRANCHES = {};
536b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_CALLS = {};
537b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesLVI_CFI = {};
538b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesLVI_LOAD_HARDENING = {};
539cfca06d7SDimitry Andric
540cfca06d7SDimitry Andric // XSAVE features are dependent on basic XSAVE.
541b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesXSAVEC = FeatureXSAVE;
542b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesXSAVEOPT = FeatureXSAVE;
543b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesXSAVES = FeatureXSAVE;
544cfca06d7SDimitry Andric
545cfca06d7SDimitry Andric // SSE/AVX/AVX512F chain.
546b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSSE = {};
547b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSSE2 = FeatureSSE;
548b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSSE3 = FeatureSSE2;
549b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSSSE3 = FeatureSSE3;
550b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSSE4_1 = FeatureSSSE3;
551b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSSE4_2 = FeatureSSE4_1;
552b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX = FeatureSSE4_2;
553b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX2 = FeatureAVX;
554b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesEVEX512 = {};
555b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512F =
556cfca06d7SDimitry Andric FeatureAVX2 | FeatureF16C | FeatureFMA;
557cfca06d7SDimitry Andric
558cfca06d7SDimitry Andric // Vector extensions that build on SSE or AVX.
559b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAES = FeatureSSE2;
560b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesF16C = FeatureAVX;
561b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesFMA = FeatureAVX;
562b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesGFNI = FeatureSSE2;
563b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesPCLMUL = FeatureSSE2;
564b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSHA = FeatureSSE2;
565b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesVAES = FeatureAES | FeatureAVX2;
566b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesVPCLMULQDQ = FeatureAVX | FeaturePCLMUL;
5677fa27ce4SDimitry Andric constexpr FeatureBitset ImpliedFeaturesSM3 = FeatureAVX;
568b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesSM4 = FeatureAVX2;
569cfca06d7SDimitry Andric
570cfca06d7SDimitry Andric // AVX512 features.
571b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512CD = FeatureAVX512F;
572b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512BW = FeatureAVX512F;
573b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512DQ = FeatureAVX512F;
574b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512VL = FeatureAVX512F;
575cfca06d7SDimitry Andric
576b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512BF16 = FeatureAVX512BW;
577b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512BITALG = FeatureAVX512BW;
578b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512IFMA = FeatureAVX512F;
579b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512VNNI = FeatureAVX512F;
580b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512VPOPCNTDQ = FeatureAVX512F;
581b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512VBMI = FeatureAVX512BW;
582b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512VBMI2 = FeatureAVX512BW;
583b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512VP2INTERSECT = FeatureAVX512F;
584cfca06d7SDimitry Andric
585cfca06d7SDimitry Andric // FIXME: These two aren't really implemented and just exist in the feature
586cfca06d7SDimitry Andric // list for __builtin_cpu_supports. So omit their dependencies.
587b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX5124FMAPS = {};
588b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX5124VNNIW = {};
589cfca06d7SDimitry Andric
590cfca06d7SDimitry Andric // SSE4_A->FMA4->XOP chain.
591b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesSSE4_A = FeatureSSE3;
592b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesFMA4 = FeatureAVX | FeatureSSE4_A;
593b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesXOP = FeatureFMA4;
594cfca06d7SDimitry Andric
595cfca06d7SDimitry Andric // AMX Features
596b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAMX_TILE = {};
597b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAMX_BF16 = FeatureAMX_TILE;
598e3b55780SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAMX_FP16 = FeatureAMX_TILE;
599b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAMX_INT8 = FeatureAMX_TILE;
6007fa27ce4SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAMX_COMPLEX = FeatureAMX_TILE;
601b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesHRESET = {};
602cfca06d7SDimitry Andric
603e3b55780SDimitry Andric constexpr FeatureBitset ImpliedFeaturesPREFETCHI = {};
604e3b55780SDimitry Andric constexpr FeatureBitset ImpliedFeaturesCMPCCXADD = {};
605e3b55780SDimitry Andric constexpr FeatureBitset ImpliedFeaturesRAOINT = {};
6067fa27ce4SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVXVNNIINT16 = FeatureAVX2;
607e3b55780SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVXVNNIINT8 = FeatureAVX2;
608e3b55780SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVXIFMA = FeatureAVX2;
609e3b55780SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVXNECONVERT = FeatureAVX2;
610b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesSHA512 = FeatureAVX2;
611e3b55780SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX512FP16 =
612c0981da4SDimitry Andric FeatureAVX512BW | FeatureAVX512DQ | FeatureAVX512VL;
613b60736ecSDimitry Andric // Key Locker Features
614b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesKL = FeatureSSE2;
615b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesWIDEKL = FeatureKL;
616b60736ecSDimitry Andric
617b60736ecSDimitry Andric // AVXVNNI Features
618b60736ecSDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVXVNNI = FeatureAVX2;
619b60736ecSDimitry Andric
620b1c73532SDimitry Andric // AVX10 Features
621b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX10_1 =
622b1c73532SDimitry Andric FeatureAVX512CD | FeatureAVX512VBMI | FeatureAVX512IFMA |
623b1c73532SDimitry Andric FeatureAVX512VNNI | FeatureAVX512BF16 | FeatureAVX512VPOPCNTDQ |
624b1c73532SDimitry Andric FeatureAVX512VBMI2 | FeatureAVX512BITALG | FeatureVAES | FeatureVPCLMULQDQ |
625b1c73532SDimitry Andric FeatureAVX512FP16;
626b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesAVX10_1_512 =
627b1c73532SDimitry Andric FeatureAVX10_1 | FeatureEVEX512;
628cfca06d7SDimitry Andric
629b1c73532SDimitry Andric // APX Features
630b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesEGPR = {};
631b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesPush2Pop2 = {};
632b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesPPX = {};
633b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesNDD = {};
634b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesCCMP = {};
635ac9a064cSDimitry Andric constexpr FeatureBitset ImpliedFeaturesNF = {};
636b1c73532SDimitry Andric constexpr FeatureBitset ImpliedFeaturesCF = {};
637ac9a064cSDimitry Andric constexpr FeatureBitset ImpliedFeaturesZU = {};
638b1c73532SDimitry Andric
639b1c73532SDimitry Andric constexpr FeatureInfo FeatureInfos[X86::CPU_FEATURE_MAX] = {
6407fa27ce4SDimitry Andric #define X86_FEATURE(ENUM, STR) {{"+" STR}, ImpliedFeatures##ENUM},
6417fa27ce4SDimitry Andric #include "llvm/TargetParser/X86TargetParser.def"
6427fa27ce4SDimitry Andric };
6437fa27ce4SDimitry Andric
getFeaturesForCPU(StringRef CPU,SmallVectorImpl<StringRef> & EnabledFeatures,bool NeedPlus)644cfca06d7SDimitry Andric void llvm::X86::getFeaturesForCPU(StringRef CPU,
6457fa27ce4SDimitry Andric SmallVectorImpl<StringRef> &EnabledFeatures,
646b1c73532SDimitry Andric bool NeedPlus) {
647cfca06d7SDimitry Andric auto I = llvm::find_if(Processors,
648cfca06d7SDimitry Andric [&](const ProcInfo &P) { return P.Name == CPU; });
649cfca06d7SDimitry Andric assert(I != std::end(Processors) && "Processor not found!");
650cfca06d7SDimitry Andric
651cfca06d7SDimitry Andric FeatureBitset Bits = I->Features;
652cfca06d7SDimitry Andric
653cfca06d7SDimitry Andric // Remove the 64-bit feature which we only use to validate if a CPU can
654cfca06d7SDimitry Andric // be used with 64-bit mode.
655cfca06d7SDimitry Andric Bits &= ~Feature64BIT;
656cfca06d7SDimitry Andric
657cfca06d7SDimitry Andric // Add the string version of all set bits.
658b60736ecSDimitry Andric for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
659b1c73532SDimitry Andric if (Bits[i] && !FeatureInfos[i].getName(NeedPlus).empty())
660b1c73532SDimitry Andric EnabledFeatures.push_back(FeatureInfos[i].getName(NeedPlus));
661cfca06d7SDimitry Andric }
662cfca06d7SDimitry Andric
663cfca06d7SDimitry Andric // For each feature that is (transitively) implied by this feature, set it.
getImpliedEnabledFeatures(FeatureBitset & Bits,const FeatureBitset & Implies)664cfca06d7SDimitry Andric static void getImpliedEnabledFeatures(FeatureBitset &Bits,
665cfca06d7SDimitry Andric const FeatureBitset &Implies) {
666b60736ecSDimitry Andric // Fast path: Implies is often empty.
667b60736ecSDimitry Andric if (!Implies.any())
668b60736ecSDimitry Andric return;
669b60736ecSDimitry Andric FeatureBitset Prev;
670cfca06d7SDimitry Andric Bits |= Implies;
671b60736ecSDimitry Andric do {
672b60736ecSDimitry Andric Prev = Bits;
673b60736ecSDimitry Andric for (unsigned i = CPU_FEATURE_MAX; i;)
674b60736ecSDimitry Andric if (Bits[--i])
675b60736ecSDimitry Andric Bits |= FeatureInfos[i].ImpliedFeatures;
676b60736ecSDimitry Andric } while (Prev != Bits);
677cfca06d7SDimitry Andric }
678cfca06d7SDimitry Andric
679cfca06d7SDimitry Andric /// Create bit vector of features that are implied disabled if the feature
680cfca06d7SDimitry Andric /// passed in Value is disabled.
getImpliedDisabledFeatures(FeatureBitset & Bits,unsigned Value)681cfca06d7SDimitry Andric static void getImpliedDisabledFeatures(FeatureBitset &Bits, unsigned Value) {
682cfca06d7SDimitry Andric // Check all features looking for any dependent on this feature. If we find
683cfca06d7SDimitry Andric // one, mark it and recursively find any feature that depend on it.
684b60736ecSDimitry Andric FeatureBitset Prev;
685b60736ecSDimitry Andric Bits.set(Value);
686b60736ecSDimitry Andric do {
687b60736ecSDimitry Andric Prev = Bits;
688b60736ecSDimitry Andric for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
689b60736ecSDimitry Andric if ((FeatureInfos[i].ImpliedFeatures & Bits).any())
690cfca06d7SDimitry Andric Bits.set(i);
691b60736ecSDimitry Andric } while (Prev != Bits);
692cfca06d7SDimitry Andric }
693cfca06d7SDimitry Andric
updateImpliedFeatures(StringRef Feature,bool Enabled,StringMap<bool> & Features)694b60736ecSDimitry Andric void llvm::X86::updateImpliedFeatures(
695cfca06d7SDimitry Andric StringRef Feature, bool Enabled,
696b60736ecSDimitry Andric StringMap<bool> &Features) {
697b1c73532SDimitry Andric auto I = llvm::find_if(FeatureInfos, [&](const FeatureInfo &FI) {
698b1c73532SDimitry Andric return FI.getName() == Feature;
699b1c73532SDimitry Andric });
700cfca06d7SDimitry Andric if (I == std::end(FeatureInfos)) {
701cfca06d7SDimitry Andric // FIXME: This shouldn't happen, but may not have all features in the table
702cfca06d7SDimitry Andric // yet.
703cfca06d7SDimitry Andric return;
704cfca06d7SDimitry Andric }
705cfca06d7SDimitry Andric
706cfca06d7SDimitry Andric FeatureBitset ImpliedBits;
707cfca06d7SDimitry Andric if (Enabled)
708cfca06d7SDimitry Andric getImpliedEnabledFeatures(ImpliedBits, I->ImpliedFeatures);
709cfca06d7SDimitry Andric else
710cfca06d7SDimitry Andric getImpliedDisabledFeatures(ImpliedBits,
711cfca06d7SDimitry Andric std::distance(std::begin(FeatureInfos), I));
712cfca06d7SDimitry Andric
713b60736ecSDimitry Andric // Update the map entry for all implied features.
714b60736ecSDimitry Andric for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
715b1c73532SDimitry Andric if (ImpliedBits[i] && !FeatureInfos[i].getName().empty())
716b1c73532SDimitry Andric Features[FeatureInfos[i].getName()] = Enabled;
717cfca06d7SDimitry Andric }
718c0981da4SDimitry Andric
getCPUDispatchMangling(StringRef CPU)7197fa27ce4SDimitry Andric char llvm::X86::getCPUDispatchMangling(StringRef CPU) {
7207fa27ce4SDimitry Andric auto I = llvm::find_if(Processors,
7217fa27ce4SDimitry Andric [&](const ProcInfo &P) { return P.Name == CPU; });
7227fa27ce4SDimitry Andric assert(I != std::end(Processors) && "Processor not found!");
7237fa27ce4SDimitry Andric assert(I->Mangling != '\0' && "Processor dooesn't support function multiversion!");
7247fa27ce4SDimitry Andric return I->Mangling;
7257fa27ce4SDimitry Andric }
7267fa27ce4SDimitry Andric
validateCPUSpecificCPUDispatch(StringRef Name)7277fa27ce4SDimitry Andric bool llvm::X86::validateCPUSpecificCPUDispatch(StringRef Name) {
7287fa27ce4SDimitry Andric auto I = llvm::find_if(Processors,
7297fa27ce4SDimitry Andric [&](const ProcInfo &P) { return P.Name == Name; });
7307fa27ce4SDimitry Andric return I != std::end(Processors);
7317fa27ce4SDimitry Andric }
7327fa27ce4SDimitry Andric
733b1c73532SDimitry Andric std::array<uint32_t, 4>
getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs)734b1c73532SDimitry Andric llvm::X86::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) {
735c0981da4SDimitry Andric // Processor features and mapping to processor feature value.
736b1c73532SDimitry Andric std::array<uint32_t, 4> FeatureMask{};
737b1c73532SDimitry Andric for (StringRef FeatureStr : FeatureStrs) {
738c0981da4SDimitry Andric unsigned Feature = StringSwitch<unsigned>(FeatureStr)
739c0981da4SDimitry Andric #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \
740c0981da4SDimitry Andric .Case(STR, llvm::X86::FEATURE_##ENUM)
741b1c73532SDimitry Andric #define X86_MICROARCH_LEVEL(ENUM, STR, PRIORITY) \
742b1c73532SDimitry Andric .Case(STR, llvm::X86::FEATURE_##ENUM)
743e3b55780SDimitry Andric #include "llvm/TargetParser/X86TargetParser.def"
744c0981da4SDimitry Andric ;
745b1c73532SDimitry Andric assert(Feature / 32 < FeatureMask.size());
746b1c73532SDimitry Andric FeatureMask[Feature / 32] |= 1U << (Feature % 32);
747c0981da4SDimitry Andric }
748b1c73532SDimitry Andric return FeatureMask;
749c0981da4SDimitry Andric }
750c0981da4SDimitry Andric
getFeaturePriority(ProcessorFeatures Feat)751c0981da4SDimitry Andric unsigned llvm::X86::getFeaturePriority(ProcessorFeatures Feat) {
752c0981da4SDimitry Andric #ifndef NDEBUG
753c0981da4SDimitry Andric // Check that priorities are set properly in the .def file. We expect that
754c0981da4SDimitry Andric // "compat" features are assigned non-duplicate consecutive priorities
755ac9a064cSDimitry Andric // starting from one (1, ..., 37) and multiple zeros.
756c0981da4SDimitry Andric #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) PRIORITY,
757c0981da4SDimitry Andric unsigned Priorities[] = {
758e3b55780SDimitry Andric #include "llvm/TargetParser/X86TargetParser.def"
759c0981da4SDimitry Andric };
760b1c73532SDimitry Andric std::array<unsigned, std::size(Priorities)> HelperList;
761ac9a064cSDimitry Andric const size_t MaxPriority = 37;
762ac9a064cSDimitry Andric std::iota(HelperList.begin(), HelperList.begin() + MaxPriority + 1, 0);
763ac9a064cSDimitry Andric for (size_t i = MaxPriority + 1; i != std::size(Priorities); ++i)
764ac9a064cSDimitry Andric HelperList[i] = 0;
765c0981da4SDimitry Andric assert(std::is_permutation(HelperList.begin(), HelperList.end(),
766b1c73532SDimitry Andric std::begin(Priorities), std::end(Priorities)) &&
767c0981da4SDimitry Andric "Priorities don't form consecutive range!");
768c0981da4SDimitry Andric #endif
769c0981da4SDimitry Andric
770c0981da4SDimitry Andric switch (Feat) {
771c0981da4SDimitry Andric #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \
772c0981da4SDimitry Andric case X86::FEATURE_##ENUM: \
773c0981da4SDimitry Andric return PRIORITY;
774e3b55780SDimitry Andric #include "llvm/TargetParser/X86TargetParser.def"
775c0981da4SDimitry Andric default:
776c0981da4SDimitry Andric llvm_unreachable("No Feature Priority for non-CPUSupports Features");
777c0981da4SDimitry Andric }
778c0981da4SDimitry Andric }
779