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