xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Targets/X86.cpp (revision 7a9b00ce7716f522d49aa36666c74a71cd12203a)
1e5dd7070Spatrick //===--- X86.cpp - Implement X86 target feature support -------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements X86 TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "X86.h"
14e5dd7070Spatrick #include "clang/Basic/Builtins.h"
15e5dd7070Spatrick #include "clang/Basic/Diagnostic.h"
16e5dd7070Spatrick #include "clang/Basic/TargetBuiltins.h"
17e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
18e5dd7070Spatrick #include "llvm/ADT/StringRef.h"
19e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
20ec727ea7Spatrick #include "llvm/Support/X86TargetParser.h"
21*7a9b00ceSrobert #include <optional>
22e5dd7070Spatrick 
23e5dd7070Spatrick namespace clang {
24e5dd7070Spatrick namespace targets {
25e5dd7070Spatrick 
26*7a9b00ceSrobert static constexpr Builtin::Info BuiltinInfoX86[] = {
27e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
28*7a9b00ceSrobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
29e5dd7070Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
30*7a9b00ceSrobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
31e5dd7070Spatrick #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
32*7a9b00ceSrobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
33e5dd7070Spatrick #include "clang/Basic/BuiltinsX86.def"
34e5dd7070Spatrick 
35e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
36*7a9b00ceSrobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
37e5dd7070Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
38*7a9b00ceSrobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
39e5dd7070Spatrick #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
40*7a9b00ceSrobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
41e5dd7070Spatrick #include "clang/Basic/BuiltinsX86_64.def"
42e5dd7070Spatrick };
43e5dd7070Spatrick 
44e5dd7070Spatrick static const char *const GCCRegNames[] = {
45e5dd7070Spatrick     "ax",    "dx",    "cx",    "bx",    "si",      "di",    "bp",    "sp",
46e5dd7070Spatrick     "st",    "st(1)", "st(2)", "st(3)", "st(4)",   "st(5)", "st(6)", "st(7)",
47e5dd7070Spatrick     "argp",  "flags", "fpcr",  "fpsr",  "dirflag", "frame", "xmm0",  "xmm1",
48e5dd7070Spatrick     "xmm2",  "xmm3",  "xmm4",  "xmm5",  "xmm6",    "xmm7",  "mm0",   "mm1",
49e5dd7070Spatrick     "mm2",   "mm3",   "mm4",   "mm5",   "mm6",     "mm7",   "r8",    "r9",
50e5dd7070Spatrick     "r10",   "r11",   "r12",   "r13",   "r14",     "r15",   "xmm8",  "xmm9",
51e5dd7070Spatrick     "xmm10", "xmm11", "xmm12", "xmm13", "xmm14",   "xmm15", "ymm0",  "ymm1",
52e5dd7070Spatrick     "ymm2",  "ymm3",  "ymm4",  "ymm5",  "ymm6",    "ymm7",  "ymm8",  "ymm9",
53e5dd7070Spatrick     "ymm10", "ymm11", "ymm12", "ymm13", "ymm14",   "ymm15", "xmm16", "xmm17",
54e5dd7070Spatrick     "xmm18", "xmm19", "xmm20", "xmm21", "xmm22",   "xmm23", "xmm24", "xmm25",
55e5dd7070Spatrick     "xmm26", "xmm27", "xmm28", "xmm29", "xmm30",   "xmm31", "ymm16", "ymm17",
56e5dd7070Spatrick     "ymm18", "ymm19", "ymm20", "ymm21", "ymm22",   "ymm23", "ymm24", "ymm25",
57e5dd7070Spatrick     "ymm26", "ymm27", "ymm28", "ymm29", "ymm30",   "ymm31", "zmm0",  "zmm1",
58e5dd7070Spatrick     "zmm2",  "zmm3",  "zmm4",  "zmm5",  "zmm6",    "zmm7",  "zmm8",  "zmm9",
59e5dd7070Spatrick     "zmm10", "zmm11", "zmm12", "zmm13", "zmm14",   "zmm15", "zmm16", "zmm17",
60e5dd7070Spatrick     "zmm18", "zmm19", "zmm20", "zmm21", "zmm22",   "zmm23", "zmm24", "zmm25",
61e5dd7070Spatrick     "zmm26", "zmm27", "zmm28", "zmm29", "zmm30",   "zmm31", "k0",    "k1",
62e5dd7070Spatrick     "k2",    "k3",    "k4",    "k5",    "k6",      "k7",
63e5dd7070Spatrick     "cr0",   "cr2",   "cr3",   "cr4",   "cr8",
64e5dd7070Spatrick     "dr0",   "dr1",   "dr2",   "dr3",   "dr6",     "dr7",
65e5dd7070Spatrick     "bnd0",  "bnd1",  "bnd2",  "bnd3",
66ec727ea7Spatrick     "tmm0",  "tmm1",  "tmm2",  "tmm3",  "tmm4",    "tmm5",  "tmm6",  "tmm7",
67e5dd7070Spatrick };
68e5dd7070Spatrick 
69e5dd7070Spatrick const TargetInfo::AddlRegName AddlRegNames[] = {
70e5dd7070Spatrick     {{"al", "ah", "eax", "rax"}, 0},
71e5dd7070Spatrick     {{"bl", "bh", "ebx", "rbx"}, 3},
72e5dd7070Spatrick     {{"cl", "ch", "ecx", "rcx"}, 2},
73e5dd7070Spatrick     {{"dl", "dh", "edx", "rdx"}, 1},
74e5dd7070Spatrick     {{"esi", "rsi"}, 4},
75e5dd7070Spatrick     {{"edi", "rdi"}, 5},
76e5dd7070Spatrick     {{"esp", "rsp"}, 7},
77e5dd7070Spatrick     {{"ebp", "rbp"}, 6},
78e5dd7070Spatrick     {{"r8d", "r8w", "r8b"}, 38},
79e5dd7070Spatrick     {{"r9d", "r9w", "r9b"}, 39},
80e5dd7070Spatrick     {{"r10d", "r10w", "r10b"}, 40},
81e5dd7070Spatrick     {{"r11d", "r11w", "r11b"}, 41},
82e5dd7070Spatrick     {{"r12d", "r12w", "r12b"}, 42},
83e5dd7070Spatrick     {{"r13d", "r13w", "r13b"}, 43},
84e5dd7070Spatrick     {{"r14d", "r14w", "r14b"}, 44},
85e5dd7070Spatrick     {{"r15d", "r15w", "r15b"}, 45},
86e5dd7070Spatrick };
87e5dd7070Spatrick 
88e5dd7070Spatrick } // namespace targets
89e5dd7070Spatrick } // namespace clang
90e5dd7070Spatrick 
91e5dd7070Spatrick using namespace clang;
92e5dd7070Spatrick using namespace clang::targets;
93e5dd7070Spatrick 
setFPMath(StringRef Name)94e5dd7070Spatrick bool X86TargetInfo::setFPMath(StringRef Name) {
95e5dd7070Spatrick   if (Name == "387") {
96e5dd7070Spatrick     FPMath = FP_387;
97e5dd7070Spatrick     return true;
98e5dd7070Spatrick   }
99e5dd7070Spatrick   if (Name == "sse") {
100e5dd7070Spatrick     FPMath = FP_SSE;
101e5dd7070Spatrick     return true;
102e5dd7070Spatrick   }
103e5dd7070Spatrick   return false;
104e5dd7070Spatrick }
105e5dd7070Spatrick 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const106e5dd7070Spatrick bool X86TargetInfo::initFeatureMap(
107e5dd7070Spatrick     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
108e5dd7070Spatrick     const std::vector<std::string> &FeaturesVec) const {
109e5dd7070Spatrick   // FIXME: This *really* should not be here.
110e5dd7070Spatrick   // X86_64 always has SSE2.
111e5dd7070Spatrick   if (getTriple().getArch() == llvm::Triple::x86_64)
112ec727ea7Spatrick     setFeatureEnabled(Features, "sse2", true);
113e5dd7070Spatrick 
114ec727ea7Spatrick   using namespace llvm::X86;
115e5dd7070Spatrick 
116ec727ea7Spatrick   SmallVector<StringRef, 16> CPUFeatures;
117ec727ea7Spatrick   getFeaturesForCPU(CPU, CPUFeatures);
118ec727ea7Spatrick   for (auto &F : CPUFeatures)
119ec727ea7Spatrick     setFeatureEnabled(Features, F, true);
120e5dd7070Spatrick 
121a0747c9fSpatrick   std::vector<std::string> UpdatedFeaturesVec;
122a0747c9fSpatrick   for (const auto &Feature : FeaturesVec) {
123a0747c9fSpatrick     // Expand general-regs-only to -x86, -mmx and -sse
124a0747c9fSpatrick     if (Feature == "+general-regs-only") {
125a0747c9fSpatrick       UpdatedFeaturesVec.push_back("-x87");
126a0747c9fSpatrick       UpdatedFeaturesVec.push_back("-mmx");
127a0747c9fSpatrick       UpdatedFeaturesVec.push_back("-sse");
128a0747c9fSpatrick       continue;
129a0747c9fSpatrick     }
130a0747c9fSpatrick 
131a0747c9fSpatrick     UpdatedFeaturesVec.push_back(Feature);
132a0747c9fSpatrick   }
133a0747c9fSpatrick 
134a0747c9fSpatrick   if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec))
135e5dd7070Spatrick     return false;
136e5dd7070Spatrick 
137e5dd7070Spatrick   // Can't do this earlier because we need to be able to explicitly enable
138e5dd7070Spatrick   // or disable these features and the things that they depend upon.
139e5dd7070Spatrick 
140e5dd7070Spatrick   // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
141e5dd7070Spatrick   auto I = Features.find("sse4.2");
142e5dd7070Spatrick   if (I != Features.end() && I->getValue() &&
143*7a9b00ceSrobert       !llvm::is_contained(UpdatedFeaturesVec, "-popcnt"))
144e5dd7070Spatrick     Features["popcnt"] = true;
145e5dd7070Spatrick 
146e5dd7070Spatrick   // Additionally, if SSE is enabled and mmx is not explicitly disabled,
147e5dd7070Spatrick   // then enable MMX.
148e5dd7070Spatrick   I = Features.find("sse");
149e5dd7070Spatrick   if (I != Features.end() && I->getValue() &&
150*7a9b00ceSrobert       !llvm::is_contained(UpdatedFeaturesVec, "-mmx"))
151e5dd7070Spatrick     Features["mmx"] = true;
152e5dd7070Spatrick 
153ec727ea7Spatrick   // Enable xsave if avx is enabled and xsave is not explicitly disabled.
154ec727ea7Spatrick   I = Features.find("avx");
155ec727ea7Spatrick   if (I != Features.end() && I->getValue() &&
156*7a9b00ceSrobert       !llvm::is_contained(UpdatedFeaturesVec, "-xsave"))
157ec727ea7Spatrick     Features["xsave"] = true;
158ec727ea7Spatrick 
159*7a9b00ceSrobert   // Enable CRC32 if SSE4.2 is enabled and CRC32 is not explicitly disabled.
160*7a9b00ceSrobert   I = Features.find("sse4.2");
161*7a9b00ceSrobert   if (I != Features.end() && I->getValue() &&
162*7a9b00ceSrobert       !llvm::is_contained(UpdatedFeaturesVec, "-crc32"))
163*7a9b00ceSrobert     Features["crc32"] = true;
164*7a9b00ceSrobert 
165e5dd7070Spatrick   return true;
166e5dd7070Spatrick }
167e5dd7070Spatrick 
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const168ec727ea7Spatrick void X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
169ec727ea7Spatrick                                       StringRef Name, bool Enabled) const {
170ec727ea7Spatrick   if (Name == "sse4") {
171e5dd7070Spatrick     // We can get here via the __target__ attribute since that's not controlled
172e5dd7070Spatrick     // via the -msse4/-mno-sse4 command line alias. Handle this the same way
173e5dd7070Spatrick     // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if
174e5dd7070Spatrick     // disabled.
175e5dd7070Spatrick     if (Enabled)
176ec727ea7Spatrick       Name = "sse4.2";
177e5dd7070Spatrick     else
178ec727ea7Spatrick       Name = "sse4.1";
179e5dd7070Spatrick   }
180ec727ea7Spatrick 
181ec727ea7Spatrick   Features[Name] = Enabled;
182a0747c9fSpatrick   llvm::X86::updateImpliedFeatures(Name, Enabled, Features);
183e5dd7070Spatrick }
184e5dd7070Spatrick 
185e5dd7070Spatrick /// handleTargetFeatures - Perform initialization based on the user
186e5dd7070Spatrick /// configured set of features.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)187e5dd7070Spatrick bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
188e5dd7070Spatrick                                          DiagnosticsEngine &Diags) {
189e5dd7070Spatrick   for (const auto &Feature : Features) {
190e5dd7070Spatrick     if (Feature[0] != '+')
191e5dd7070Spatrick       continue;
192e5dd7070Spatrick 
193e5dd7070Spatrick     if (Feature == "+aes") {
194e5dd7070Spatrick       HasAES = true;
195e5dd7070Spatrick     } else if (Feature == "+vaes") {
196e5dd7070Spatrick       HasVAES = true;
197e5dd7070Spatrick     } else if (Feature == "+pclmul") {
198e5dd7070Spatrick       HasPCLMUL = true;
199e5dd7070Spatrick     } else if (Feature == "+vpclmulqdq") {
200e5dd7070Spatrick       HasVPCLMULQDQ = true;
201e5dd7070Spatrick     } else if (Feature == "+lzcnt") {
202e5dd7070Spatrick       HasLZCNT = true;
203e5dd7070Spatrick     } else if (Feature == "+rdrnd") {
204e5dd7070Spatrick       HasRDRND = true;
205e5dd7070Spatrick     } else if (Feature == "+fsgsbase") {
206e5dd7070Spatrick       HasFSGSBASE = true;
207e5dd7070Spatrick     } else if (Feature == "+bmi") {
208e5dd7070Spatrick       HasBMI = true;
209e5dd7070Spatrick     } else if (Feature == "+bmi2") {
210e5dd7070Spatrick       HasBMI2 = true;
211e5dd7070Spatrick     } else if (Feature == "+popcnt") {
212e5dd7070Spatrick       HasPOPCNT = true;
213e5dd7070Spatrick     } else if (Feature == "+rtm") {
214e5dd7070Spatrick       HasRTM = true;
215e5dd7070Spatrick     } else if (Feature == "+prfchw") {
216e5dd7070Spatrick       HasPRFCHW = true;
217e5dd7070Spatrick     } else if (Feature == "+rdseed") {
218e5dd7070Spatrick       HasRDSEED = true;
219e5dd7070Spatrick     } else if (Feature == "+adx") {
220e5dd7070Spatrick       HasADX = true;
221e5dd7070Spatrick     } else if (Feature == "+tbm") {
222e5dd7070Spatrick       HasTBM = true;
223e5dd7070Spatrick     } else if (Feature == "+lwp") {
224e5dd7070Spatrick       HasLWP = true;
225e5dd7070Spatrick     } else if (Feature == "+fma") {
226e5dd7070Spatrick       HasFMA = true;
227e5dd7070Spatrick     } else if (Feature == "+f16c") {
228e5dd7070Spatrick       HasF16C = true;
229e5dd7070Spatrick     } else if (Feature == "+gfni") {
230e5dd7070Spatrick       HasGFNI = true;
231e5dd7070Spatrick     } else if (Feature == "+avx512cd") {
232e5dd7070Spatrick       HasAVX512CD = true;
233e5dd7070Spatrick     } else if (Feature == "+avx512vpopcntdq") {
234e5dd7070Spatrick       HasAVX512VPOPCNTDQ = true;
235e5dd7070Spatrick     } else if (Feature == "+avx512vnni") {
236e5dd7070Spatrick       HasAVX512VNNI = true;
237e5dd7070Spatrick     } else if (Feature == "+avx512bf16") {
238e5dd7070Spatrick       HasAVX512BF16 = true;
239e5dd7070Spatrick     } else if (Feature == "+avx512er") {
240e5dd7070Spatrick       HasAVX512ER = true;
241*7a9b00ceSrobert     } else if (Feature == "+avx512fp16") {
242*7a9b00ceSrobert       HasAVX512FP16 = true;
243*7a9b00ceSrobert       HasLegalHalfType = true;
244e5dd7070Spatrick     } else if (Feature == "+avx512pf") {
245e5dd7070Spatrick       HasAVX512PF = true;
246e5dd7070Spatrick     } else if (Feature == "+avx512dq") {
247e5dd7070Spatrick       HasAVX512DQ = true;
248e5dd7070Spatrick     } else if (Feature == "+avx512bitalg") {
249e5dd7070Spatrick       HasAVX512BITALG = true;
250e5dd7070Spatrick     } else if (Feature == "+avx512bw") {
251e5dd7070Spatrick       HasAVX512BW = true;
252e5dd7070Spatrick     } else if (Feature == "+avx512vl") {
253e5dd7070Spatrick       HasAVX512VL = true;
254e5dd7070Spatrick     } else if (Feature == "+avx512vbmi") {
255e5dd7070Spatrick       HasAVX512VBMI = true;
256e5dd7070Spatrick     } else if (Feature == "+avx512vbmi2") {
257e5dd7070Spatrick       HasAVX512VBMI2 = true;
258e5dd7070Spatrick     } else if (Feature == "+avx512ifma") {
259e5dd7070Spatrick       HasAVX512IFMA = true;
260e5dd7070Spatrick     } else if (Feature == "+avx512vp2intersect") {
261e5dd7070Spatrick       HasAVX512VP2INTERSECT = true;
262e5dd7070Spatrick     } else if (Feature == "+sha") {
263e5dd7070Spatrick       HasSHA = true;
264e5dd7070Spatrick     } else if (Feature == "+shstk") {
265e5dd7070Spatrick       HasSHSTK = true;
266e5dd7070Spatrick     } else if (Feature == "+movbe") {
267e5dd7070Spatrick       HasMOVBE = true;
268e5dd7070Spatrick     } else if (Feature == "+sgx") {
269e5dd7070Spatrick       HasSGX = true;
270e5dd7070Spatrick     } else if (Feature == "+cx8") {
271e5dd7070Spatrick       HasCX8 = true;
272e5dd7070Spatrick     } else if (Feature == "+cx16") {
273e5dd7070Spatrick       HasCX16 = true;
274e5dd7070Spatrick     } else if (Feature == "+fxsr") {
275e5dd7070Spatrick       HasFXSR = true;
276e5dd7070Spatrick     } else if (Feature == "+xsave") {
277e5dd7070Spatrick       HasXSAVE = true;
278e5dd7070Spatrick     } else if (Feature == "+xsaveopt") {
279e5dd7070Spatrick       HasXSAVEOPT = true;
280e5dd7070Spatrick     } else if (Feature == "+xsavec") {
281e5dd7070Spatrick       HasXSAVEC = true;
282e5dd7070Spatrick     } else if (Feature == "+xsaves") {
283e5dd7070Spatrick       HasXSAVES = true;
284e5dd7070Spatrick     } else if (Feature == "+mwaitx") {
285e5dd7070Spatrick       HasMWAITX = true;
286e5dd7070Spatrick     } else if (Feature == "+pku") {
287e5dd7070Spatrick       HasPKU = true;
288e5dd7070Spatrick     } else if (Feature == "+clflushopt") {
289e5dd7070Spatrick       HasCLFLUSHOPT = true;
290e5dd7070Spatrick     } else if (Feature == "+clwb") {
291e5dd7070Spatrick       HasCLWB = true;
292e5dd7070Spatrick     } else if (Feature == "+wbnoinvd") {
293e5dd7070Spatrick       HasWBNOINVD = true;
294*7a9b00ceSrobert     } else if (Feature == "+prefetchi") {
295*7a9b00ceSrobert       HasPREFETCHI = true;
296e5dd7070Spatrick     } else if (Feature == "+prefetchwt1") {
297e5dd7070Spatrick       HasPREFETCHWT1 = true;
298e5dd7070Spatrick     } else if (Feature == "+clzero") {
299e5dd7070Spatrick       HasCLZERO = true;
300e5dd7070Spatrick     } else if (Feature == "+cldemote") {
301e5dd7070Spatrick       HasCLDEMOTE = true;
302e5dd7070Spatrick     } else if (Feature == "+rdpid") {
303e5dd7070Spatrick       HasRDPID = true;
304*7a9b00ceSrobert     } else if (Feature == "+rdpru") {
305*7a9b00ceSrobert       HasRDPRU = true;
306a0747c9fSpatrick     } else if (Feature == "+kl") {
307a0747c9fSpatrick       HasKL = true;
308a0747c9fSpatrick     } else if (Feature == "+widekl") {
309a0747c9fSpatrick       HasWIDEKL = true;
310e5dd7070Spatrick     } else if (Feature == "+retpoline-external-thunk") {
311e5dd7070Spatrick       HasRetpolineExternalThunk = true;
312e5dd7070Spatrick     } else if (Feature == "+sahf") {
313e5dd7070Spatrick       HasLAHFSAHF = true;
314e5dd7070Spatrick     } else if (Feature == "+waitpkg") {
315e5dd7070Spatrick       HasWAITPKG = true;
316e5dd7070Spatrick     } else if (Feature == "+movdiri") {
317e5dd7070Spatrick       HasMOVDIRI = true;
318e5dd7070Spatrick     } else if (Feature == "+movdir64b") {
319e5dd7070Spatrick       HasMOVDIR64B = true;
320e5dd7070Spatrick     } else if (Feature == "+pconfig") {
321e5dd7070Spatrick       HasPCONFIG = true;
322e5dd7070Spatrick     } else if (Feature == "+ptwrite") {
323e5dd7070Spatrick       HasPTWRITE = true;
324e5dd7070Spatrick     } else if (Feature == "+invpcid") {
325e5dd7070Spatrick       HasINVPCID = true;
326adae0cfdSpatrick     } else if (Feature == "+save-args") {
327adae0cfdSpatrick       HasSaveArgs = true;
328e5dd7070Spatrick     } else if (Feature == "+enqcmd") {
329e5dd7070Spatrick       HasENQCMD = true;
330a0747c9fSpatrick     } else if (Feature == "+hreset") {
331a0747c9fSpatrick       HasHRESET = true;
332ec727ea7Spatrick     } else if (Feature == "+amx-bf16") {
333ec727ea7Spatrick       HasAMXBF16 = true;
334*7a9b00ceSrobert     } else if (Feature == "+amx-fp16") {
335*7a9b00ceSrobert       HasAMXFP16 = true;
336ec727ea7Spatrick     } else if (Feature == "+amx-int8") {
337ec727ea7Spatrick       HasAMXINT8 = true;
338ec727ea7Spatrick     } else if (Feature == "+amx-tile") {
339ec727ea7Spatrick       HasAMXTILE = true;
340*7a9b00ceSrobert     } else if (Feature == "+cmpccxadd") {
341*7a9b00ceSrobert       HasCMPCCXADD = true;
342*7a9b00ceSrobert     } else if (Feature == "+raoint") {
343*7a9b00ceSrobert       HasRAOINT = true;
344*7a9b00ceSrobert     } else if (Feature == "+avxifma") {
345*7a9b00ceSrobert       HasAVXIFMA = true;
346*7a9b00ceSrobert     } else if (Feature == "+avxneconvert") {
347*7a9b00ceSrobert       HasAVXNECONVERT= true;
348a0747c9fSpatrick     } else if (Feature == "+avxvnni") {
349a0747c9fSpatrick       HasAVXVNNI = true;
350*7a9b00ceSrobert     } else if (Feature == "+avxvnniint8") {
351*7a9b00ceSrobert       HasAVXVNNIINT8 = true;
352ec727ea7Spatrick     } else if (Feature == "+serialize") {
353ec727ea7Spatrick       HasSERIALIZE = true;
354ec727ea7Spatrick     } else if (Feature == "+tsxldtrk") {
355ec727ea7Spatrick       HasTSXLDTRK = true;
356a0747c9fSpatrick     } else if (Feature == "+uintr") {
357a0747c9fSpatrick       HasUINTR = true;
358*7a9b00ceSrobert     } else if (Feature == "+crc32") {
359*7a9b00ceSrobert       HasCRC32 = true;
360*7a9b00ceSrobert     } else if (Feature == "+x87") {
361*7a9b00ceSrobert       HasX87 = true;
362e5dd7070Spatrick     }
363e5dd7070Spatrick 
364e5dd7070Spatrick     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
365e5dd7070Spatrick                            .Case("+avx512f", AVX512F)
366e5dd7070Spatrick                            .Case("+avx2", AVX2)
367e5dd7070Spatrick                            .Case("+avx", AVX)
368e5dd7070Spatrick                            .Case("+sse4.2", SSE42)
369e5dd7070Spatrick                            .Case("+sse4.1", SSE41)
370e5dd7070Spatrick                            .Case("+ssse3", SSSE3)
371e5dd7070Spatrick                            .Case("+sse3", SSE3)
372e5dd7070Spatrick                            .Case("+sse2", SSE2)
373e5dd7070Spatrick                            .Case("+sse", SSE1)
374e5dd7070Spatrick                            .Default(NoSSE);
375e5dd7070Spatrick     SSELevel = std::max(SSELevel, Level);
376e5dd7070Spatrick 
377*7a9b00ceSrobert     HasFloat16 = SSELevel >= SSE2;
378*7a9b00ceSrobert 
379*7a9b00ceSrobert     HasBFloat16 = SSELevel >= SSE2;
380*7a9b00ceSrobert 
381e5dd7070Spatrick     MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature)
382e5dd7070Spatrick                                       .Case("+3dnowa", AMD3DNowAthlon)
383e5dd7070Spatrick                                       .Case("+3dnow", AMD3DNow)
384e5dd7070Spatrick                                       .Case("+mmx", MMX)
385e5dd7070Spatrick                                       .Default(NoMMX3DNow);
386e5dd7070Spatrick     MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
387e5dd7070Spatrick 
388e5dd7070Spatrick     XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
389e5dd7070Spatrick                          .Case("+xop", XOP)
390e5dd7070Spatrick                          .Case("+fma4", FMA4)
391e5dd7070Spatrick                          .Case("+sse4a", SSE4A)
392e5dd7070Spatrick                          .Default(NoXOP);
393e5dd7070Spatrick     XOPLevel = std::max(XOPLevel, XLevel);
394e5dd7070Spatrick   }
395e5dd7070Spatrick 
396e5dd7070Spatrick   // LLVM doesn't have a separate switch for fpmath, so only accept it if it
397e5dd7070Spatrick   // matches the selected sse level.
398e5dd7070Spatrick   if ((FPMath == FP_SSE && SSELevel < SSE1) ||
399e5dd7070Spatrick       (FPMath == FP_387 && SSELevel >= SSE1)) {
400e5dd7070Spatrick     Diags.Report(diag::err_target_unsupported_fpmath)
401e5dd7070Spatrick         << (FPMath == FP_SSE ? "sse" : "387");
402e5dd7070Spatrick     return false;
403e5dd7070Spatrick   }
404e5dd7070Spatrick 
405e5dd7070Spatrick   SimdDefaultAlign =
406e5dd7070Spatrick       hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
407*7a9b00ceSrobert 
408*7a9b00ceSrobert   // FIXME: We should allow long double type on 32-bits to match with GCC.
409*7a9b00ceSrobert   // This requires backend to be able to lower f80 without x87 first.
410*7a9b00ceSrobert   if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended())
411*7a9b00ceSrobert     HasLongDouble = false;
412*7a9b00ceSrobert 
413e5dd7070Spatrick   return true;
414e5dd7070Spatrick }
415e5dd7070Spatrick 
416e5dd7070Spatrick /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
417e5dd7070Spatrick /// definitions for this particular subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const418e5dd7070Spatrick void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
419e5dd7070Spatrick                                      MacroBuilder &Builder) const {
420e5dd7070Spatrick   // Inline assembly supports X86 flag outputs.
421e5dd7070Spatrick   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
422e5dd7070Spatrick 
423e5dd7070Spatrick   std::string CodeModel = getTargetOpts().CodeModel;
424e5dd7070Spatrick   if (CodeModel == "default")
425e5dd7070Spatrick     CodeModel = "small";
426ec727ea7Spatrick   Builder.defineMacro("__code_model_" + CodeModel + "__");
427e5dd7070Spatrick 
428e5dd7070Spatrick   // Target identification.
429e5dd7070Spatrick   if (getTriple().getArch() == llvm::Triple::x86_64) {
430e5dd7070Spatrick     Builder.defineMacro("__amd64__");
431e5dd7070Spatrick     Builder.defineMacro("__amd64");
432e5dd7070Spatrick     Builder.defineMacro("__x86_64");
433e5dd7070Spatrick     Builder.defineMacro("__x86_64__");
434e5dd7070Spatrick     if (getTriple().getArchName() == "x86_64h") {
435e5dd7070Spatrick       Builder.defineMacro("__x86_64h");
436e5dd7070Spatrick       Builder.defineMacro("__x86_64h__");
437e5dd7070Spatrick     }
438e5dd7070Spatrick   } else {
439e5dd7070Spatrick     DefineStd(Builder, "i386", Opts);
440e5dd7070Spatrick   }
441e5dd7070Spatrick 
442e5dd7070Spatrick   Builder.defineMacro("__SEG_GS");
443e5dd7070Spatrick   Builder.defineMacro("__SEG_FS");
444e5dd7070Spatrick   Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))");
445e5dd7070Spatrick   Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))");
446e5dd7070Spatrick 
447e5dd7070Spatrick   // Subtarget options.
448e5dd7070Spatrick   // FIXME: We are hard-coding the tune parameters based on the CPU, but they
449e5dd7070Spatrick   // truly should be based on -mtune options.
450ec727ea7Spatrick   using namespace llvm::X86;
451e5dd7070Spatrick   switch (CPU) {
452ec727ea7Spatrick   case CK_None:
453e5dd7070Spatrick     break;
454e5dd7070Spatrick   case CK_i386:
455e5dd7070Spatrick     // The rest are coming from the i386 define above.
456e5dd7070Spatrick     Builder.defineMacro("__tune_i386__");
457e5dd7070Spatrick     break;
458e5dd7070Spatrick   case CK_i486:
459e5dd7070Spatrick   case CK_WinChipC6:
460e5dd7070Spatrick   case CK_WinChip2:
461e5dd7070Spatrick   case CK_C3:
462e5dd7070Spatrick     defineCPUMacros(Builder, "i486");
463e5dd7070Spatrick     break;
464e5dd7070Spatrick   case CK_PentiumMMX:
465e5dd7070Spatrick     Builder.defineMacro("__pentium_mmx__");
466e5dd7070Spatrick     Builder.defineMacro("__tune_pentium_mmx__");
467*7a9b00ceSrobert     [[fallthrough]];
468e5dd7070Spatrick   case CK_i586:
469e5dd7070Spatrick   case CK_Pentium:
470e5dd7070Spatrick     defineCPUMacros(Builder, "i586");
471e5dd7070Spatrick     defineCPUMacros(Builder, "pentium");
472e5dd7070Spatrick     break;
473e5dd7070Spatrick   case CK_Pentium3:
474e5dd7070Spatrick   case CK_PentiumM:
475e5dd7070Spatrick     Builder.defineMacro("__tune_pentium3__");
476*7a9b00ceSrobert     [[fallthrough]];
477e5dd7070Spatrick   case CK_Pentium2:
478e5dd7070Spatrick   case CK_C3_2:
479e5dd7070Spatrick     Builder.defineMacro("__tune_pentium2__");
480*7a9b00ceSrobert     [[fallthrough]];
481e5dd7070Spatrick   case CK_PentiumPro:
482e5dd7070Spatrick   case CK_i686:
483e5dd7070Spatrick     defineCPUMacros(Builder, "i686");
484e5dd7070Spatrick     defineCPUMacros(Builder, "pentiumpro");
485e5dd7070Spatrick     break;
486e5dd7070Spatrick   case CK_Pentium4:
487e5dd7070Spatrick     defineCPUMacros(Builder, "pentium4");
488e5dd7070Spatrick     break;
489e5dd7070Spatrick   case CK_Yonah:
490e5dd7070Spatrick   case CK_Prescott:
491e5dd7070Spatrick   case CK_Nocona:
492e5dd7070Spatrick     defineCPUMacros(Builder, "nocona");
493e5dd7070Spatrick     break;
494e5dd7070Spatrick   case CK_Core2:
495e5dd7070Spatrick   case CK_Penryn:
496e5dd7070Spatrick     defineCPUMacros(Builder, "core2");
497e5dd7070Spatrick     break;
498e5dd7070Spatrick   case CK_Bonnell:
499e5dd7070Spatrick     defineCPUMacros(Builder, "atom");
500e5dd7070Spatrick     break;
501e5dd7070Spatrick   case CK_Silvermont:
502e5dd7070Spatrick     defineCPUMacros(Builder, "slm");
503e5dd7070Spatrick     break;
504e5dd7070Spatrick   case CK_Goldmont:
505e5dd7070Spatrick     defineCPUMacros(Builder, "goldmont");
506e5dd7070Spatrick     break;
507e5dd7070Spatrick   case CK_GoldmontPlus:
508e5dd7070Spatrick     defineCPUMacros(Builder, "goldmont_plus");
509e5dd7070Spatrick     break;
510e5dd7070Spatrick   case CK_Tremont:
511e5dd7070Spatrick     defineCPUMacros(Builder, "tremont");
512e5dd7070Spatrick     break;
513e5dd7070Spatrick   case CK_Nehalem:
514e5dd7070Spatrick   case CK_Westmere:
515e5dd7070Spatrick   case CK_SandyBridge:
516e5dd7070Spatrick   case CK_IvyBridge:
517e5dd7070Spatrick   case CK_Haswell:
518e5dd7070Spatrick   case CK_Broadwell:
519e5dd7070Spatrick   case CK_SkylakeClient:
520e5dd7070Spatrick   case CK_SkylakeServer:
521e5dd7070Spatrick   case CK_Cascadelake:
522e5dd7070Spatrick   case CK_Cooperlake:
523e5dd7070Spatrick   case CK_Cannonlake:
524e5dd7070Spatrick   case CK_IcelakeClient:
525a0747c9fSpatrick   case CK_Rocketlake:
526e5dd7070Spatrick   case CK_IcelakeServer:
527e5dd7070Spatrick   case CK_Tigerlake:
528a0747c9fSpatrick   case CK_SapphireRapids:
529a0747c9fSpatrick   case CK_Alderlake:
530*7a9b00ceSrobert   case CK_Raptorlake:
531*7a9b00ceSrobert   case CK_Meteorlake:
532*7a9b00ceSrobert   case CK_Sierraforest:
533*7a9b00ceSrobert   case CK_Grandridge:
534*7a9b00ceSrobert   case CK_Graniterapids:
535*7a9b00ceSrobert   case CK_Emeraldrapids:
536e5dd7070Spatrick     // FIXME: Historically, we defined this legacy name, it would be nice to
537e5dd7070Spatrick     // remove it at some point. We've never exposed fine-grained names for
538e5dd7070Spatrick     // recent primary x86 CPUs, and we should keep it that way.
539e5dd7070Spatrick     defineCPUMacros(Builder, "corei7");
540e5dd7070Spatrick     break;
541e5dd7070Spatrick   case CK_KNL:
542e5dd7070Spatrick     defineCPUMacros(Builder, "knl");
543e5dd7070Spatrick     break;
544e5dd7070Spatrick   case CK_KNM:
545e5dd7070Spatrick     break;
546e5dd7070Spatrick   case CK_Lakemont:
547e5dd7070Spatrick     defineCPUMacros(Builder, "i586", /*Tuning*/false);
548e5dd7070Spatrick     defineCPUMacros(Builder, "pentium", /*Tuning*/false);
549e5dd7070Spatrick     Builder.defineMacro("__tune_lakemont__");
550e5dd7070Spatrick     break;
551e5dd7070Spatrick   case CK_K6_2:
552e5dd7070Spatrick     Builder.defineMacro("__k6_2__");
553e5dd7070Spatrick     Builder.defineMacro("__tune_k6_2__");
554*7a9b00ceSrobert     [[fallthrough]];
555e5dd7070Spatrick   case CK_K6_3:
556e5dd7070Spatrick     if (CPU != CK_K6_2) { // In case of fallthrough
557e5dd7070Spatrick       // FIXME: GCC may be enabling these in cases where some other k6
558e5dd7070Spatrick       // architecture is specified but -m3dnow is explicitly provided. The
559e5dd7070Spatrick       // exact semantics need to be determined and emulated here.
560e5dd7070Spatrick       Builder.defineMacro("__k6_3__");
561e5dd7070Spatrick       Builder.defineMacro("__tune_k6_3__");
562e5dd7070Spatrick     }
563*7a9b00ceSrobert     [[fallthrough]];
564e5dd7070Spatrick   case CK_K6:
565e5dd7070Spatrick     defineCPUMacros(Builder, "k6");
566e5dd7070Spatrick     break;
567e5dd7070Spatrick   case CK_Athlon:
568e5dd7070Spatrick   case CK_AthlonXP:
569e5dd7070Spatrick     defineCPUMacros(Builder, "athlon");
570e5dd7070Spatrick     if (SSELevel != NoSSE) {
571e5dd7070Spatrick       Builder.defineMacro("__athlon_sse__");
572e5dd7070Spatrick       Builder.defineMacro("__tune_athlon_sse__");
573e5dd7070Spatrick     }
574e5dd7070Spatrick     break;
575e5dd7070Spatrick   case CK_K8:
576e5dd7070Spatrick   case CK_K8SSE3:
577e5dd7070Spatrick   case CK_x86_64:
578e5dd7070Spatrick     defineCPUMacros(Builder, "k8");
579e5dd7070Spatrick     break;
580a0747c9fSpatrick   case CK_x86_64_v2:
581a0747c9fSpatrick   case CK_x86_64_v3:
582a0747c9fSpatrick   case CK_x86_64_v4:
583a0747c9fSpatrick     break;
584e5dd7070Spatrick   case CK_AMDFAM10:
585e5dd7070Spatrick     defineCPUMacros(Builder, "amdfam10");
586e5dd7070Spatrick     break;
587e5dd7070Spatrick   case CK_BTVER1:
588e5dd7070Spatrick     defineCPUMacros(Builder, "btver1");
589e5dd7070Spatrick     break;
590e5dd7070Spatrick   case CK_BTVER2:
591e5dd7070Spatrick     defineCPUMacros(Builder, "btver2");
592e5dd7070Spatrick     break;
593e5dd7070Spatrick   case CK_BDVER1:
594e5dd7070Spatrick     defineCPUMacros(Builder, "bdver1");
595e5dd7070Spatrick     break;
596e5dd7070Spatrick   case CK_BDVER2:
597e5dd7070Spatrick     defineCPUMacros(Builder, "bdver2");
598e5dd7070Spatrick     break;
599e5dd7070Spatrick   case CK_BDVER3:
600e5dd7070Spatrick     defineCPUMacros(Builder, "bdver3");
601e5dd7070Spatrick     break;
602e5dd7070Spatrick   case CK_BDVER4:
603e5dd7070Spatrick     defineCPUMacros(Builder, "bdver4");
604e5dd7070Spatrick     break;
605e5dd7070Spatrick   case CK_ZNVER1:
606e5dd7070Spatrick     defineCPUMacros(Builder, "znver1");
607e5dd7070Spatrick     break;
608e5dd7070Spatrick   case CK_ZNVER2:
609e5dd7070Spatrick     defineCPUMacros(Builder, "znver2");
610e5dd7070Spatrick     break;
611a0747c9fSpatrick   case CK_ZNVER3:
612a0747c9fSpatrick     defineCPUMacros(Builder, "znver3");
613a0747c9fSpatrick     break;
614*7a9b00ceSrobert   case CK_ZNVER4:
615*7a9b00ceSrobert     defineCPUMacros(Builder, "znver4");
616*7a9b00ceSrobert     break;
617e5dd7070Spatrick   case CK_Geode:
618e5dd7070Spatrick     defineCPUMacros(Builder, "geode");
619e5dd7070Spatrick     break;
620e5dd7070Spatrick   }
621e5dd7070Spatrick 
622e5dd7070Spatrick   // Target properties.
623e5dd7070Spatrick   Builder.defineMacro("__REGISTER_PREFIX__", "");
624e5dd7070Spatrick 
625e5dd7070Spatrick   // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
626e5dd7070Spatrick   // functions in glibc header files that use FP Stack inline asm which the
627e5dd7070Spatrick   // backend can't deal with (PR879).
628e5dd7070Spatrick   Builder.defineMacro("__NO_MATH_INLINES");
629e5dd7070Spatrick 
630e5dd7070Spatrick   if (HasAES)
631e5dd7070Spatrick     Builder.defineMacro("__AES__");
632e5dd7070Spatrick 
633e5dd7070Spatrick   if (HasVAES)
634e5dd7070Spatrick     Builder.defineMacro("__VAES__");
635e5dd7070Spatrick 
636e5dd7070Spatrick   if (HasPCLMUL)
637e5dd7070Spatrick     Builder.defineMacro("__PCLMUL__");
638e5dd7070Spatrick 
639e5dd7070Spatrick   if (HasVPCLMULQDQ)
640e5dd7070Spatrick     Builder.defineMacro("__VPCLMULQDQ__");
641e5dd7070Spatrick 
642a0747c9fSpatrick   // Note, in 32-bit mode, GCC does not define the macro if -mno-sahf. In LLVM,
643a0747c9fSpatrick   // the feature flag only applies to 64-bit mode.
644a0747c9fSpatrick   if (HasLAHFSAHF || getTriple().getArch() == llvm::Triple::x86)
645a0747c9fSpatrick     Builder.defineMacro("__LAHF_SAHF__");
646a0747c9fSpatrick 
647e5dd7070Spatrick   if (HasLZCNT)
648e5dd7070Spatrick     Builder.defineMacro("__LZCNT__");
649e5dd7070Spatrick 
650e5dd7070Spatrick   if (HasRDRND)
651e5dd7070Spatrick     Builder.defineMacro("__RDRND__");
652e5dd7070Spatrick 
653e5dd7070Spatrick   if (HasFSGSBASE)
654e5dd7070Spatrick     Builder.defineMacro("__FSGSBASE__");
655e5dd7070Spatrick 
656e5dd7070Spatrick   if (HasBMI)
657e5dd7070Spatrick     Builder.defineMacro("__BMI__");
658e5dd7070Spatrick 
659e5dd7070Spatrick   if (HasBMI2)
660e5dd7070Spatrick     Builder.defineMacro("__BMI2__");
661e5dd7070Spatrick 
662e5dd7070Spatrick   if (HasPOPCNT)
663e5dd7070Spatrick     Builder.defineMacro("__POPCNT__");
664e5dd7070Spatrick 
665e5dd7070Spatrick   if (HasRTM)
666e5dd7070Spatrick     Builder.defineMacro("__RTM__");
667e5dd7070Spatrick 
668e5dd7070Spatrick   if (HasPRFCHW)
669e5dd7070Spatrick     Builder.defineMacro("__PRFCHW__");
670e5dd7070Spatrick 
671e5dd7070Spatrick   if (HasRDSEED)
672e5dd7070Spatrick     Builder.defineMacro("__RDSEED__");
673e5dd7070Spatrick 
674e5dd7070Spatrick   if (HasADX)
675e5dd7070Spatrick     Builder.defineMacro("__ADX__");
676e5dd7070Spatrick 
677e5dd7070Spatrick   if (HasTBM)
678e5dd7070Spatrick     Builder.defineMacro("__TBM__");
679e5dd7070Spatrick 
680e5dd7070Spatrick   if (HasLWP)
681e5dd7070Spatrick     Builder.defineMacro("__LWP__");
682e5dd7070Spatrick 
683e5dd7070Spatrick   if (HasMWAITX)
684e5dd7070Spatrick     Builder.defineMacro("__MWAITX__");
685e5dd7070Spatrick 
686e5dd7070Spatrick   if (HasMOVBE)
687e5dd7070Spatrick     Builder.defineMacro("__MOVBE__");
688e5dd7070Spatrick 
689e5dd7070Spatrick   switch (XOPLevel) {
690e5dd7070Spatrick   case XOP:
691e5dd7070Spatrick     Builder.defineMacro("__XOP__");
692*7a9b00ceSrobert     [[fallthrough]];
693e5dd7070Spatrick   case FMA4:
694e5dd7070Spatrick     Builder.defineMacro("__FMA4__");
695*7a9b00ceSrobert     [[fallthrough]];
696e5dd7070Spatrick   case SSE4A:
697e5dd7070Spatrick     Builder.defineMacro("__SSE4A__");
698*7a9b00ceSrobert     [[fallthrough]];
699e5dd7070Spatrick   case NoXOP:
700e5dd7070Spatrick     break;
701e5dd7070Spatrick   }
702e5dd7070Spatrick 
703e5dd7070Spatrick   if (HasFMA)
704e5dd7070Spatrick     Builder.defineMacro("__FMA__");
705e5dd7070Spatrick 
706e5dd7070Spatrick   if (HasF16C)
707e5dd7070Spatrick     Builder.defineMacro("__F16C__");
708e5dd7070Spatrick 
709e5dd7070Spatrick   if (HasGFNI)
710e5dd7070Spatrick     Builder.defineMacro("__GFNI__");
711e5dd7070Spatrick 
712e5dd7070Spatrick   if (HasAVX512CD)
713e5dd7070Spatrick     Builder.defineMacro("__AVX512CD__");
714e5dd7070Spatrick   if (HasAVX512VPOPCNTDQ)
715e5dd7070Spatrick     Builder.defineMacro("__AVX512VPOPCNTDQ__");
716e5dd7070Spatrick   if (HasAVX512VNNI)
717e5dd7070Spatrick     Builder.defineMacro("__AVX512VNNI__");
718e5dd7070Spatrick   if (HasAVX512BF16)
719e5dd7070Spatrick     Builder.defineMacro("__AVX512BF16__");
720e5dd7070Spatrick   if (HasAVX512ER)
721e5dd7070Spatrick     Builder.defineMacro("__AVX512ER__");
722*7a9b00ceSrobert   if (HasAVX512FP16)
723*7a9b00ceSrobert     Builder.defineMacro("__AVX512FP16__");
724e5dd7070Spatrick   if (HasAVX512PF)
725e5dd7070Spatrick     Builder.defineMacro("__AVX512PF__");
726e5dd7070Spatrick   if (HasAVX512DQ)
727e5dd7070Spatrick     Builder.defineMacro("__AVX512DQ__");
728e5dd7070Spatrick   if (HasAVX512BITALG)
729e5dd7070Spatrick     Builder.defineMacro("__AVX512BITALG__");
730e5dd7070Spatrick   if (HasAVX512BW)
731e5dd7070Spatrick     Builder.defineMacro("__AVX512BW__");
732e5dd7070Spatrick   if (HasAVX512VL)
733e5dd7070Spatrick     Builder.defineMacro("__AVX512VL__");
734e5dd7070Spatrick   if (HasAVX512VBMI)
735e5dd7070Spatrick     Builder.defineMacro("__AVX512VBMI__");
736e5dd7070Spatrick   if (HasAVX512VBMI2)
737e5dd7070Spatrick     Builder.defineMacro("__AVX512VBMI2__");
738e5dd7070Spatrick   if (HasAVX512IFMA)
739e5dd7070Spatrick     Builder.defineMacro("__AVX512IFMA__");
740e5dd7070Spatrick   if (HasAVX512VP2INTERSECT)
741e5dd7070Spatrick     Builder.defineMacro("__AVX512VP2INTERSECT__");
742e5dd7070Spatrick   if (HasSHA)
743e5dd7070Spatrick     Builder.defineMacro("__SHA__");
744e5dd7070Spatrick 
745e5dd7070Spatrick   if (HasFXSR)
746e5dd7070Spatrick     Builder.defineMacro("__FXSR__");
747e5dd7070Spatrick   if (HasXSAVE)
748e5dd7070Spatrick     Builder.defineMacro("__XSAVE__");
749e5dd7070Spatrick   if (HasXSAVEOPT)
750e5dd7070Spatrick     Builder.defineMacro("__XSAVEOPT__");
751e5dd7070Spatrick   if (HasXSAVEC)
752e5dd7070Spatrick     Builder.defineMacro("__XSAVEC__");
753e5dd7070Spatrick   if (HasXSAVES)
754e5dd7070Spatrick     Builder.defineMacro("__XSAVES__");
755e5dd7070Spatrick   if (HasPKU)
756e5dd7070Spatrick     Builder.defineMacro("__PKU__");
757e5dd7070Spatrick   if (HasCLFLUSHOPT)
758e5dd7070Spatrick     Builder.defineMacro("__CLFLUSHOPT__");
759e5dd7070Spatrick   if (HasCLWB)
760e5dd7070Spatrick     Builder.defineMacro("__CLWB__");
761e5dd7070Spatrick   if (HasWBNOINVD)
762e5dd7070Spatrick     Builder.defineMacro("__WBNOINVD__");
763e5dd7070Spatrick   if (HasSHSTK)
764e5dd7070Spatrick     Builder.defineMacro("__SHSTK__");
765e5dd7070Spatrick   if (HasSGX)
766e5dd7070Spatrick     Builder.defineMacro("__SGX__");
767*7a9b00ceSrobert   if (HasPREFETCHI)
768*7a9b00ceSrobert     Builder.defineMacro("__PREFETCHI__");
769e5dd7070Spatrick   if (HasPREFETCHWT1)
770e5dd7070Spatrick     Builder.defineMacro("__PREFETCHWT1__");
771e5dd7070Spatrick   if (HasCLZERO)
772e5dd7070Spatrick     Builder.defineMacro("__CLZERO__");
773a0747c9fSpatrick   if (HasKL)
774a0747c9fSpatrick     Builder.defineMacro("__KL__");
775a0747c9fSpatrick   if (HasWIDEKL)
776a0747c9fSpatrick     Builder.defineMacro("__WIDEKL__");
777e5dd7070Spatrick   if (HasRDPID)
778e5dd7070Spatrick     Builder.defineMacro("__RDPID__");
779*7a9b00ceSrobert   if (HasRDPRU)
780*7a9b00ceSrobert     Builder.defineMacro("__RDPRU__");
781e5dd7070Spatrick   if (HasCLDEMOTE)
782e5dd7070Spatrick     Builder.defineMacro("__CLDEMOTE__");
783e5dd7070Spatrick   if (HasWAITPKG)
784e5dd7070Spatrick     Builder.defineMacro("__WAITPKG__");
785e5dd7070Spatrick   if (HasMOVDIRI)
786e5dd7070Spatrick     Builder.defineMacro("__MOVDIRI__");
787e5dd7070Spatrick   if (HasMOVDIR64B)
788e5dd7070Spatrick     Builder.defineMacro("__MOVDIR64B__");
789e5dd7070Spatrick   if (HasPCONFIG)
790e5dd7070Spatrick     Builder.defineMacro("__PCONFIG__");
791e5dd7070Spatrick   if (HasPTWRITE)
792e5dd7070Spatrick     Builder.defineMacro("__PTWRITE__");
793e5dd7070Spatrick   if (HasINVPCID)
794e5dd7070Spatrick     Builder.defineMacro("__INVPCID__");
795e5dd7070Spatrick   if (HasENQCMD)
796e5dd7070Spatrick     Builder.defineMacro("__ENQCMD__");
797a0747c9fSpatrick   if (HasHRESET)
798a0747c9fSpatrick     Builder.defineMacro("__HRESET__");
799ec727ea7Spatrick   if (HasAMXTILE)
800*7a9b00ceSrobert     Builder.defineMacro("__AMX_TILE__");
801ec727ea7Spatrick   if (HasAMXINT8)
802*7a9b00ceSrobert     Builder.defineMacro("__AMX_INT8__");
803ec727ea7Spatrick   if (HasAMXBF16)
804*7a9b00ceSrobert     Builder.defineMacro("__AMX_BF16__");
805*7a9b00ceSrobert   if (HasAMXFP16)
806*7a9b00ceSrobert     Builder.defineMacro("__AMX_FP16__");
807*7a9b00ceSrobert   if (HasCMPCCXADD)
808*7a9b00ceSrobert     Builder.defineMacro("__CMPCCXADD__");
809*7a9b00ceSrobert   if (HasRAOINT)
810*7a9b00ceSrobert     Builder.defineMacro("__RAOINT__");
811*7a9b00ceSrobert   if (HasAVXIFMA)
812*7a9b00ceSrobert     Builder.defineMacro("__AVXIFMA__");
813*7a9b00ceSrobert   if (HasAVXNECONVERT)
814*7a9b00ceSrobert     Builder.defineMacro("__AVXNECONVERT__");
815a0747c9fSpatrick   if (HasAVXVNNI)
816a0747c9fSpatrick     Builder.defineMacro("__AVXVNNI__");
817*7a9b00ceSrobert   if (HasAVXVNNIINT8)
818*7a9b00ceSrobert     Builder.defineMacro("__AVXVNNIINT8__");
819ec727ea7Spatrick   if (HasSERIALIZE)
820ec727ea7Spatrick     Builder.defineMacro("__SERIALIZE__");
821ec727ea7Spatrick   if (HasTSXLDTRK)
822ec727ea7Spatrick     Builder.defineMacro("__TSXLDTRK__");
823a0747c9fSpatrick   if (HasUINTR)
824a0747c9fSpatrick     Builder.defineMacro("__UINTR__");
825*7a9b00ceSrobert   if (HasCRC32)
826*7a9b00ceSrobert     Builder.defineMacro("__CRC32__");
827e5dd7070Spatrick 
828e5dd7070Spatrick   // Each case falls through to the previous one here.
829e5dd7070Spatrick   switch (SSELevel) {
830e5dd7070Spatrick   case AVX512F:
831e5dd7070Spatrick     Builder.defineMacro("__AVX512F__");
832*7a9b00ceSrobert     [[fallthrough]];
833e5dd7070Spatrick   case AVX2:
834e5dd7070Spatrick     Builder.defineMacro("__AVX2__");
835*7a9b00ceSrobert     [[fallthrough]];
836e5dd7070Spatrick   case AVX:
837e5dd7070Spatrick     Builder.defineMacro("__AVX__");
838*7a9b00ceSrobert     [[fallthrough]];
839e5dd7070Spatrick   case SSE42:
840e5dd7070Spatrick     Builder.defineMacro("__SSE4_2__");
841*7a9b00ceSrobert     [[fallthrough]];
842e5dd7070Spatrick   case SSE41:
843e5dd7070Spatrick     Builder.defineMacro("__SSE4_1__");
844*7a9b00ceSrobert     [[fallthrough]];
845e5dd7070Spatrick   case SSSE3:
846e5dd7070Spatrick     Builder.defineMacro("__SSSE3__");
847*7a9b00ceSrobert     [[fallthrough]];
848e5dd7070Spatrick   case SSE3:
849e5dd7070Spatrick     Builder.defineMacro("__SSE3__");
850*7a9b00ceSrobert     [[fallthrough]];
851e5dd7070Spatrick   case SSE2:
852e5dd7070Spatrick     Builder.defineMacro("__SSE2__");
853e5dd7070Spatrick     Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
854*7a9b00ceSrobert     [[fallthrough]];
855e5dd7070Spatrick   case SSE1:
856e5dd7070Spatrick     Builder.defineMacro("__SSE__");
857e5dd7070Spatrick     Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
858*7a9b00ceSrobert     [[fallthrough]];
859e5dd7070Spatrick   case NoSSE:
860e5dd7070Spatrick     break;
861e5dd7070Spatrick   }
862e5dd7070Spatrick 
863e5dd7070Spatrick   if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
864e5dd7070Spatrick     switch (SSELevel) {
865e5dd7070Spatrick     case AVX512F:
866e5dd7070Spatrick     case AVX2:
867e5dd7070Spatrick     case AVX:
868e5dd7070Spatrick     case SSE42:
869e5dd7070Spatrick     case SSE41:
870e5dd7070Spatrick     case SSSE3:
871e5dd7070Spatrick     case SSE3:
872e5dd7070Spatrick     case SSE2:
873e5dd7070Spatrick       Builder.defineMacro("_M_IX86_FP", Twine(2));
874e5dd7070Spatrick       break;
875e5dd7070Spatrick     case SSE1:
876e5dd7070Spatrick       Builder.defineMacro("_M_IX86_FP", Twine(1));
877e5dd7070Spatrick       break;
878e5dd7070Spatrick     default:
879e5dd7070Spatrick       Builder.defineMacro("_M_IX86_FP", Twine(0));
880e5dd7070Spatrick       break;
881e5dd7070Spatrick     }
882e5dd7070Spatrick   }
883e5dd7070Spatrick 
884e5dd7070Spatrick   // Each case falls through to the previous one here.
885e5dd7070Spatrick   switch (MMX3DNowLevel) {
886e5dd7070Spatrick   case AMD3DNowAthlon:
887e5dd7070Spatrick     Builder.defineMacro("__3dNOW_A__");
888*7a9b00ceSrobert     [[fallthrough]];
889e5dd7070Spatrick   case AMD3DNow:
890e5dd7070Spatrick     Builder.defineMacro("__3dNOW__");
891*7a9b00ceSrobert     [[fallthrough]];
892e5dd7070Spatrick   case MMX:
893e5dd7070Spatrick     Builder.defineMacro("__MMX__");
894*7a9b00ceSrobert     [[fallthrough]];
895e5dd7070Spatrick   case NoMMX3DNow:
896e5dd7070Spatrick     break;
897e5dd7070Spatrick   }
898e5dd7070Spatrick 
899ec727ea7Spatrick   if (CPU >= CK_i486 || CPU == CK_None) {
900e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
901e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
902e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
903e5dd7070Spatrick   }
904e5dd7070Spatrick   if (HasCX8)
905e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
906e5dd7070Spatrick   if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)
907e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
908e5dd7070Spatrick 
909e5dd7070Spatrick   if (HasFloat128)
910e5dd7070Spatrick     Builder.defineMacro("__SIZEOF_FLOAT128__", "16");
911e5dd7070Spatrick }
912e5dd7070Spatrick 
isValidFeatureName(StringRef Name) const913e5dd7070Spatrick bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
914e5dd7070Spatrick   return llvm::StringSwitch<bool>(Name)
915e5dd7070Spatrick       .Case("3dnow", true)
916e5dd7070Spatrick       .Case("3dnowa", true)
917e5dd7070Spatrick       .Case("adx", true)
918e5dd7070Spatrick       .Case("aes", true)
919ec727ea7Spatrick       .Case("amx-bf16", true)
920*7a9b00ceSrobert       .Case("amx-fp16", true)
921ec727ea7Spatrick       .Case("amx-int8", true)
922ec727ea7Spatrick       .Case("amx-tile", true)
923e5dd7070Spatrick       .Case("avx", true)
924e5dd7070Spatrick       .Case("avx2", true)
925e5dd7070Spatrick       .Case("avx512f", true)
926e5dd7070Spatrick       .Case("avx512cd", true)
927e5dd7070Spatrick       .Case("avx512vpopcntdq", true)
928e5dd7070Spatrick       .Case("avx512vnni", true)
929e5dd7070Spatrick       .Case("avx512bf16", true)
930e5dd7070Spatrick       .Case("avx512er", true)
931*7a9b00ceSrobert       .Case("avx512fp16", true)
932e5dd7070Spatrick       .Case("avx512pf", true)
933e5dd7070Spatrick       .Case("avx512dq", true)
934e5dd7070Spatrick       .Case("avx512bitalg", true)
935e5dd7070Spatrick       .Case("avx512bw", true)
936e5dd7070Spatrick       .Case("avx512vl", true)
937e5dd7070Spatrick       .Case("avx512vbmi", true)
938e5dd7070Spatrick       .Case("avx512vbmi2", true)
939e5dd7070Spatrick       .Case("avx512ifma", true)
940e5dd7070Spatrick       .Case("avx512vp2intersect", true)
941*7a9b00ceSrobert       .Case("avxifma", true)
942*7a9b00ceSrobert       .Case("avxneconvert", true)
943a0747c9fSpatrick       .Case("avxvnni", true)
944*7a9b00ceSrobert       .Case("avxvnniint8", true)
945e5dd7070Spatrick       .Case("bmi", true)
946e5dd7070Spatrick       .Case("bmi2", true)
947e5dd7070Spatrick       .Case("cldemote", true)
948e5dd7070Spatrick       .Case("clflushopt", true)
949e5dd7070Spatrick       .Case("clwb", true)
950e5dd7070Spatrick       .Case("clzero", true)
951*7a9b00ceSrobert       .Case("cmpccxadd", true)
952*7a9b00ceSrobert       .Case("crc32", true)
953e5dd7070Spatrick       .Case("cx16", true)
954e5dd7070Spatrick       .Case("enqcmd", true)
955e5dd7070Spatrick       .Case("f16c", true)
956e5dd7070Spatrick       .Case("fma", true)
957e5dd7070Spatrick       .Case("fma4", true)
958e5dd7070Spatrick       .Case("fsgsbase", true)
959e5dd7070Spatrick       .Case("fxsr", true)
960a0747c9fSpatrick       .Case("general-regs-only", true)
961e5dd7070Spatrick       .Case("gfni", true)
962a0747c9fSpatrick       .Case("hreset", true)
963e5dd7070Spatrick       .Case("invpcid", true)
964a0747c9fSpatrick       .Case("kl", true)
965a0747c9fSpatrick       .Case("widekl", true)
966e5dd7070Spatrick       .Case("lwp", true)
967e5dd7070Spatrick       .Case("lzcnt", true)
968e5dd7070Spatrick       .Case("mmx", true)
969e5dd7070Spatrick       .Case("movbe", true)
970e5dd7070Spatrick       .Case("movdiri", true)
971e5dd7070Spatrick       .Case("movdir64b", true)
972e5dd7070Spatrick       .Case("mwaitx", true)
973e5dd7070Spatrick       .Case("pclmul", true)
974e5dd7070Spatrick       .Case("pconfig", true)
975e5dd7070Spatrick       .Case("pku", true)
976e5dd7070Spatrick       .Case("popcnt", true)
977*7a9b00ceSrobert       .Case("prefetchi", true)
978e5dd7070Spatrick       .Case("prefetchwt1", true)
979e5dd7070Spatrick       .Case("prfchw", true)
980e5dd7070Spatrick       .Case("ptwrite", true)
981*7a9b00ceSrobert       .Case("raoint", true)
982e5dd7070Spatrick       .Case("rdpid", true)
983*7a9b00ceSrobert       .Case("rdpru", true)
984e5dd7070Spatrick       .Case("rdrnd", true)
985e5dd7070Spatrick       .Case("rdseed", true)
986e5dd7070Spatrick       .Case("rtm", true)
987e5dd7070Spatrick       .Case("sahf", true)
988ec727ea7Spatrick       .Case("serialize", true)
989e5dd7070Spatrick       .Case("sgx", true)
990e5dd7070Spatrick       .Case("sha", true)
991e5dd7070Spatrick       .Case("shstk", true)
992e5dd7070Spatrick       .Case("sse", true)
993e5dd7070Spatrick       .Case("sse2", true)
994e5dd7070Spatrick       .Case("sse3", true)
995e5dd7070Spatrick       .Case("ssse3", true)
996e5dd7070Spatrick       .Case("sse4", true)
997e5dd7070Spatrick       .Case("sse4.1", true)
998e5dd7070Spatrick       .Case("sse4.2", true)
999e5dd7070Spatrick       .Case("sse4a", true)
1000e5dd7070Spatrick       .Case("tbm", true)
1001ec727ea7Spatrick       .Case("tsxldtrk", true)
1002a0747c9fSpatrick       .Case("uintr", true)
1003e5dd7070Spatrick       .Case("vaes", true)
1004e5dd7070Spatrick       .Case("vpclmulqdq", true)
1005e5dd7070Spatrick       .Case("wbnoinvd", true)
1006e5dd7070Spatrick       .Case("waitpkg", true)
1007e5dd7070Spatrick       .Case("x87", true)
1008e5dd7070Spatrick       .Case("xop", true)
1009e5dd7070Spatrick       .Case("xsave", true)
1010e5dd7070Spatrick       .Case("xsavec", true)
1011e5dd7070Spatrick       .Case("xsaves", true)
1012e5dd7070Spatrick       .Case("xsaveopt", true)
1013e5dd7070Spatrick       .Default(false);
1014e5dd7070Spatrick }
1015e5dd7070Spatrick 
hasFeature(StringRef Feature) const1016e5dd7070Spatrick bool X86TargetInfo::hasFeature(StringRef Feature) const {
1017e5dd7070Spatrick   return llvm::StringSwitch<bool>(Feature)
1018e5dd7070Spatrick       .Case("adx", HasADX)
1019e5dd7070Spatrick       .Case("aes", HasAES)
1020ec727ea7Spatrick       .Case("amx-bf16", HasAMXBF16)
1021*7a9b00ceSrobert       .Case("amx-fp16", HasAMXFP16)
1022ec727ea7Spatrick       .Case("amx-int8", HasAMXINT8)
1023ec727ea7Spatrick       .Case("amx-tile", HasAMXTILE)
1024e5dd7070Spatrick       .Case("avx", SSELevel >= AVX)
1025e5dd7070Spatrick       .Case("avx2", SSELevel >= AVX2)
1026e5dd7070Spatrick       .Case("avx512f", SSELevel >= AVX512F)
1027e5dd7070Spatrick       .Case("avx512cd", HasAVX512CD)
1028e5dd7070Spatrick       .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ)
1029e5dd7070Spatrick       .Case("avx512vnni", HasAVX512VNNI)
1030e5dd7070Spatrick       .Case("avx512bf16", HasAVX512BF16)
1031e5dd7070Spatrick       .Case("avx512er", HasAVX512ER)
1032*7a9b00ceSrobert       .Case("avx512fp16", HasAVX512FP16)
1033e5dd7070Spatrick       .Case("avx512pf", HasAVX512PF)
1034e5dd7070Spatrick       .Case("avx512dq", HasAVX512DQ)
1035e5dd7070Spatrick       .Case("avx512bitalg", HasAVX512BITALG)
1036e5dd7070Spatrick       .Case("avx512bw", HasAVX512BW)
1037e5dd7070Spatrick       .Case("avx512vl", HasAVX512VL)
1038e5dd7070Spatrick       .Case("avx512vbmi", HasAVX512VBMI)
1039e5dd7070Spatrick       .Case("avx512vbmi2", HasAVX512VBMI2)
1040e5dd7070Spatrick       .Case("avx512ifma", HasAVX512IFMA)
1041e5dd7070Spatrick       .Case("avx512vp2intersect", HasAVX512VP2INTERSECT)
1042*7a9b00ceSrobert       .Case("avxifma", HasAVXIFMA)
1043*7a9b00ceSrobert       .Case("avxneconvert", HasAVXNECONVERT)
1044*7a9b00ceSrobert       .Case("avxvnni", HasAVXVNNI)
1045*7a9b00ceSrobert       .Case("avxvnniint8", HasAVXVNNIINT8)
1046e5dd7070Spatrick       .Case("bmi", HasBMI)
1047e5dd7070Spatrick       .Case("bmi2", HasBMI2)
1048e5dd7070Spatrick       .Case("cldemote", HasCLDEMOTE)
1049e5dd7070Spatrick       .Case("clflushopt", HasCLFLUSHOPT)
1050e5dd7070Spatrick       .Case("clwb", HasCLWB)
1051e5dd7070Spatrick       .Case("clzero", HasCLZERO)
1052*7a9b00ceSrobert       .Case("cmpccxadd", HasCMPCCXADD)
1053*7a9b00ceSrobert       .Case("crc32", HasCRC32)
1054e5dd7070Spatrick       .Case("cx8", HasCX8)
1055e5dd7070Spatrick       .Case("cx16", HasCX16)
1056e5dd7070Spatrick       .Case("enqcmd", HasENQCMD)
1057e5dd7070Spatrick       .Case("f16c", HasF16C)
1058e5dd7070Spatrick       .Case("fma", HasFMA)
1059e5dd7070Spatrick       .Case("fma4", XOPLevel >= FMA4)
1060e5dd7070Spatrick       .Case("fsgsbase", HasFSGSBASE)
1061e5dd7070Spatrick       .Case("fxsr", HasFXSR)
1062e5dd7070Spatrick       .Case("gfni", HasGFNI)
1063a0747c9fSpatrick       .Case("hreset", HasHRESET)
1064e5dd7070Spatrick       .Case("invpcid", HasINVPCID)
1065a0747c9fSpatrick       .Case("kl", HasKL)
1066a0747c9fSpatrick       .Case("widekl", HasWIDEKL)
1067e5dd7070Spatrick       .Case("lwp", HasLWP)
1068e5dd7070Spatrick       .Case("lzcnt", HasLZCNT)
1069e5dd7070Spatrick       .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
1070e5dd7070Spatrick       .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
1071e5dd7070Spatrick       .Case("mmx", MMX3DNowLevel >= MMX)
1072e5dd7070Spatrick       .Case("movbe", HasMOVBE)
1073e5dd7070Spatrick       .Case("movdiri", HasMOVDIRI)
1074e5dd7070Spatrick       .Case("movdir64b", HasMOVDIR64B)
1075adae0cfdSpatrick       .Case("save-args", HasSaveArgs)
1076e5dd7070Spatrick       .Case("mwaitx", HasMWAITX)
1077e5dd7070Spatrick       .Case("pclmul", HasPCLMUL)
1078e5dd7070Spatrick       .Case("pconfig", HasPCONFIG)
1079e5dd7070Spatrick       .Case("pku", HasPKU)
1080e5dd7070Spatrick       .Case("popcnt", HasPOPCNT)
1081*7a9b00ceSrobert       .Case("prefetchi", HasPREFETCHI)
1082e5dd7070Spatrick       .Case("prefetchwt1", HasPREFETCHWT1)
1083e5dd7070Spatrick       .Case("prfchw", HasPRFCHW)
1084e5dd7070Spatrick       .Case("ptwrite", HasPTWRITE)
1085*7a9b00ceSrobert       .Case("raoint", HasRAOINT)
1086e5dd7070Spatrick       .Case("rdpid", HasRDPID)
1087*7a9b00ceSrobert       .Case("rdpru", HasRDPRU)
1088e5dd7070Spatrick       .Case("rdrnd", HasRDRND)
1089e5dd7070Spatrick       .Case("rdseed", HasRDSEED)
1090e5dd7070Spatrick       .Case("retpoline-external-thunk", HasRetpolineExternalThunk)
1091e5dd7070Spatrick       .Case("rtm", HasRTM)
1092e5dd7070Spatrick       .Case("sahf", HasLAHFSAHF)
1093ec727ea7Spatrick       .Case("serialize", HasSERIALIZE)
1094e5dd7070Spatrick       .Case("sgx", HasSGX)
1095e5dd7070Spatrick       .Case("sha", HasSHA)
1096e5dd7070Spatrick       .Case("shstk", HasSHSTK)
1097e5dd7070Spatrick       .Case("sse", SSELevel >= SSE1)
1098e5dd7070Spatrick       .Case("sse2", SSELevel >= SSE2)
1099e5dd7070Spatrick       .Case("sse3", SSELevel >= SSE3)
1100e5dd7070Spatrick       .Case("ssse3", SSELevel >= SSSE3)
1101e5dd7070Spatrick       .Case("sse4.1", SSELevel >= SSE41)
1102e5dd7070Spatrick       .Case("sse4.2", SSELevel >= SSE42)
1103e5dd7070Spatrick       .Case("sse4a", XOPLevel >= SSE4A)
1104e5dd7070Spatrick       .Case("tbm", HasTBM)
1105ec727ea7Spatrick       .Case("tsxldtrk", HasTSXLDTRK)
1106a0747c9fSpatrick       .Case("uintr", HasUINTR)
1107e5dd7070Spatrick       .Case("vaes", HasVAES)
1108e5dd7070Spatrick       .Case("vpclmulqdq", HasVPCLMULQDQ)
1109e5dd7070Spatrick       .Case("wbnoinvd", HasWBNOINVD)
1110e5dd7070Spatrick       .Case("waitpkg", HasWAITPKG)
1111e5dd7070Spatrick       .Case("x86", true)
1112e5dd7070Spatrick       .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
1113e5dd7070Spatrick       .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
1114*7a9b00ceSrobert       .Case("x87", HasX87)
1115e5dd7070Spatrick       .Case("xop", XOPLevel >= XOP)
1116e5dd7070Spatrick       .Case("xsave", HasXSAVE)
1117e5dd7070Spatrick       .Case("xsavec", HasXSAVEC)
1118e5dd7070Spatrick       .Case("xsaves", HasXSAVES)
1119e5dd7070Spatrick       .Case("xsaveopt", HasXSAVEOPT)
1120e5dd7070Spatrick       .Default(false);
1121e5dd7070Spatrick }
1122e5dd7070Spatrick 
1123e5dd7070Spatrick // We can't use a generic validation scheme for the features accepted here
1124e5dd7070Spatrick // versus subtarget features accepted in the target attribute because the
1125e5dd7070Spatrick // bitfield structure that's initialized in the runtime only supports the
1126e5dd7070Spatrick // below currently rather than the full range of subtarget features. (See
1127e5dd7070Spatrick // X86TargetInfo::hasFeature for a somewhat comprehensive list).
validateCpuSupports(StringRef FeatureStr) const1128e5dd7070Spatrick bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
1129e5dd7070Spatrick   return llvm::StringSwitch<bool>(FeatureStr)
1130*7a9b00ceSrobert #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) .Case(STR, true)
1131*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1132e5dd7070Spatrick       .Default(false);
1133e5dd7070Spatrick }
1134e5dd7070Spatrick 
getFeature(StringRef Name)1135e5dd7070Spatrick static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {
1136e5dd7070Spatrick   return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)
1137*7a9b00ceSrobert #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY)                                \
1138*7a9b00ceSrobert   .Case(STR, llvm::X86::FEATURE_##ENUM)
1139*7a9b00ceSrobert 
1140*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1141e5dd7070Spatrick       ;
1142e5dd7070Spatrick   // Note, this function should only be used after ensuring the value is
1143e5dd7070Spatrick   // correct, so it asserts if the value is out of range.
1144e5dd7070Spatrick }
1145e5dd7070Spatrick 
multiVersionSortPriority(StringRef Name) const1146e5dd7070Spatrick unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
1147e5dd7070Spatrick   // Valid CPUs have a 'key feature' that compares just better than its key
1148e5dd7070Spatrick   // feature.
1149ec727ea7Spatrick   using namespace llvm::X86;
1150ec727ea7Spatrick   CPUKind Kind = parseArchX86(Name);
1151ec727ea7Spatrick   if (Kind != CK_None) {
1152ec727ea7Spatrick     ProcessorFeatures KeyFeature = getKeyFeature(Kind);
1153ec727ea7Spatrick     return (getFeaturePriority(KeyFeature) << 1) + 1;
1154e5dd7070Spatrick   }
1155e5dd7070Spatrick 
1156e5dd7070Spatrick   // Now we know we have a feature, so get its priority and shift it a few so
1157e5dd7070Spatrick   // that we have sufficient room for the CPUs (above).
1158e5dd7070Spatrick   return getFeaturePriority(getFeature(Name)) << 1;
1159e5dd7070Spatrick }
1160e5dd7070Spatrick 
validateCPUSpecificCPUDispatch(StringRef Name) const1161e5dd7070Spatrick bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const {
1162e5dd7070Spatrick   return llvm::StringSwitch<bool>(Name)
1163*7a9b00ceSrobert #define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, true)
1164*7a9b00ceSrobert #define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, true)
1165*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1166e5dd7070Spatrick       .Default(false);
1167e5dd7070Spatrick }
1168e5dd7070Spatrick 
CPUSpecificCPUDispatchNameDealias(StringRef Name)1169e5dd7070Spatrick static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) {
1170e5dd7070Spatrick   return llvm::StringSwitch<StringRef>(Name)
1171*7a9b00ceSrobert #define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, NAME)
1172*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1173e5dd7070Spatrick       .Default(Name);
1174e5dd7070Spatrick }
1175e5dd7070Spatrick 
CPUSpecificManglingCharacter(StringRef Name) const1176e5dd7070Spatrick char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const {
1177e5dd7070Spatrick   return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name))
1178*7a9b00ceSrobert #define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, MANGLING)
1179*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1180e5dd7070Spatrick       .Default(0);
1181e5dd7070Spatrick }
1182e5dd7070Spatrick 
getCPUSpecificCPUDispatchFeatures(StringRef Name,llvm::SmallVectorImpl<StringRef> & Features) const1183e5dd7070Spatrick void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(
1184e5dd7070Spatrick     StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
1185e5dd7070Spatrick   StringRef WholeList =
1186e5dd7070Spatrick       llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name))
1187*7a9b00ceSrobert #define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, FEATURES)
1188*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1189e5dd7070Spatrick           .Default("");
1190e5dd7070Spatrick   WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1191e5dd7070Spatrick }
1192e5dd7070Spatrick 
getCPUSpecificTuneName(StringRef Name) const1193*7a9b00ceSrobert StringRef X86TargetInfo::getCPUSpecificTuneName(StringRef Name) const {
1194*7a9b00ceSrobert   return llvm::StringSwitch<StringRef>(Name)
1195*7a9b00ceSrobert #define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, TUNE_NAME)
1196*7a9b00ceSrobert #define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, TUNE_NAME)
1197*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1198*7a9b00ceSrobert       .Default("");
1199*7a9b00ceSrobert }
1200*7a9b00ceSrobert 
1201e5dd7070Spatrick // We can't use a generic validation scheme for the cpus accepted here
1202e5dd7070Spatrick // versus subtarget cpus accepted in the target attribute because the
1203e5dd7070Spatrick // variables intitialized by the runtime only support the below currently
1204e5dd7070Spatrick // rather than the full range of cpus.
validateCpuIs(StringRef FeatureStr) const1205e5dd7070Spatrick bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
1206e5dd7070Spatrick   return llvm::StringSwitch<bool>(FeatureStr)
1207e5dd7070Spatrick #define X86_VENDOR(ENUM, STRING) .Case(STRING, true)
1208ec727ea7Spatrick #define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
1209ec727ea7Spatrick #define X86_CPU_TYPE(ENUM, STR) .Case(STR, true)
1210*7a9b00ceSrobert #define X86_CPU_SUBTYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
1211ec727ea7Spatrick #define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true)
1212*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1213e5dd7070Spatrick       .Default(false);
1214e5dd7070Spatrick }
1215e5dd7070Spatrick 
matchAsmCCConstraint(const char * & Name)1216e5dd7070Spatrick static unsigned matchAsmCCConstraint(const char *&Name) {
1217e5dd7070Spatrick   auto RV = llvm::StringSwitch<unsigned>(Name)
1218e5dd7070Spatrick                 .Case("@cca", 4)
1219e5dd7070Spatrick                 .Case("@ccae", 5)
1220e5dd7070Spatrick                 .Case("@ccb", 4)
1221e5dd7070Spatrick                 .Case("@ccbe", 5)
1222e5dd7070Spatrick                 .Case("@ccc", 4)
1223e5dd7070Spatrick                 .Case("@cce", 4)
1224e5dd7070Spatrick                 .Case("@ccz", 4)
1225e5dd7070Spatrick                 .Case("@ccg", 4)
1226e5dd7070Spatrick                 .Case("@ccge", 5)
1227e5dd7070Spatrick                 .Case("@ccl", 4)
1228e5dd7070Spatrick                 .Case("@ccle", 5)
1229e5dd7070Spatrick                 .Case("@ccna", 5)
1230e5dd7070Spatrick                 .Case("@ccnae", 6)
1231e5dd7070Spatrick                 .Case("@ccnb", 5)
1232e5dd7070Spatrick                 .Case("@ccnbe", 6)
1233e5dd7070Spatrick                 .Case("@ccnc", 5)
1234e5dd7070Spatrick                 .Case("@ccne", 5)
1235e5dd7070Spatrick                 .Case("@ccnz", 5)
1236e5dd7070Spatrick                 .Case("@ccng", 5)
1237e5dd7070Spatrick                 .Case("@ccnge", 6)
1238e5dd7070Spatrick                 .Case("@ccnl", 5)
1239e5dd7070Spatrick                 .Case("@ccnle", 6)
1240e5dd7070Spatrick                 .Case("@ccno", 5)
1241e5dd7070Spatrick                 .Case("@ccnp", 5)
1242e5dd7070Spatrick                 .Case("@ccns", 5)
1243e5dd7070Spatrick                 .Case("@cco", 4)
1244e5dd7070Spatrick                 .Case("@ccp", 4)
1245e5dd7070Spatrick                 .Case("@ccs", 4)
1246e5dd7070Spatrick                 .Default(0);
1247e5dd7070Spatrick   return RV;
1248e5dd7070Spatrick }
1249e5dd7070Spatrick 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1250e5dd7070Spatrick bool X86TargetInfo::validateAsmConstraint(
1251e5dd7070Spatrick     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1252e5dd7070Spatrick   switch (*Name) {
1253e5dd7070Spatrick   default:
1254e5dd7070Spatrick     return false;
1255e5dd7070Spatrick   // Constant constraints.
1256e5dd7070Spatrick   case 'e': // 32-bit signed integer constant for use with sign-extending x86_64
1257e5dd7070Spatrick             // instructions.
1258e5dd7070Spatrick   case 'Z': // 32-bit unsigned integer constant for use with zero-extending
1259e5dd7070Spatrick             // x86_64 instructions.
1260e5dd7070Spatrick   case 's':
1261e5dd7070Spatrick     Info.setRequiresImmediate();
1262e5dd7070Spatrick     return true;
1263e5dd7070Spatrick   case 'I':
1264e5dd7070Spatrick     Info.setRequiresImmediate(0, 31);
1265e5dd7070Spatrick     return true;
1266e5dd7070Spatrick   case 'J':
1267e5dd7070Spatrick     Info.setRequiresImmediate(0, 63);
1268e5dd7070Spatrick     return true;
1269e5dd7070Spatrick   case 'K':
1270e5dd7070Spatrick     Info.setRequiresImmediate(-128, 127);
1271e5dd7070Spatrick     return true;
1272e5dd7070Spatrick   case 'L':
1273e5dd7070Spatrick     Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)});
1274e5dd7070Spatrick     return true;
1275e5dd7070Spatrick   case 'M':
1276e5dd7070Spatrick     Info.setRequiresImmediate(0, 3);
1277e5dd7070Spatrick     return true;
1278e5dd7070Spatrick   case 'N':
1279e5dd7070Spatrick     Info.setRequiresImmediate(0, 255);
1280e5dd7070Spatrick     return true;
1281e5dd7070Spatrick   case 'O':
1282e5dd7070Spatrick     Info.setRequiresImmediate(0, 127);
1283e5dd7070Spatrick     return true;
1284e5dd7070Spatrick   // Register constraints.
1285e5dd7070Spatrick   case 'Y': // 'Y' is the first character for several 2-character constraints.
1286e5dd7070Spatrick     // Shift the pointer to the second character of the constraint.
1287e5dd7070Spatrick     Name++;
1288e5dd7070Spatrick     switch (*Name) {
1289e5dd7070Spatrick     default:
1290e5dd7070Spatrick       return false;
1291ec727ea7Spatrick     case 'z': // First SSE register.
1292e5dd7070Spatrick     case '2':
1293e5dd7070Spatrick     case 't': // Any SSE register, when SSE2 is enabled.
1294e5dd7070Spatrick     case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1295e5dd7070Spatrick     case 'm': // Any MMX register, when inter-unit moves enabled.
1296e5dd7070Spatrick     case 'k': // AVX512 arch mask registers: k1-k7.
1297e5dd7070Spatrick       Info.setAllowsRegister();
1298e5dd7070Spatrick       return true;
1299e5dd7070Spatrick     }
1300e5dd7070Spatrick   case 'f': // Any x87 floating point stack register.
1301e5dd7070Spatrick     // Constraint 'f' cannot be used for output operands.
1302e5dd7070Spatrick     if (Info.ConstraintStr[0] == '=')
1303e5dd7070Spatrick       return false;
1304e5dd7070Spatrick     Info.setAllowsRegister();
1305e5dd7070Spatrick     return true;
1306e5dd7070Spatrick   case 'a': // eax.
1307e5dd7070Spatrick   case 'b': // ebx.
1308e5dd7070Spatrick   case 'c': // ecx.
1309e5dd7070Spatrick   case 'd': // edx.
1310e5dd7070Spatrick   case 'S': // esi.
1311e5dd7070Spatrick   case 'D': // edi.
1312e5dd7070Spatrick   case 'A': // edx:eax.
1313e5dd7070Spatrick   case 't': // Top of floating point stack.
1314e5dd7070Spatrick   case 'u': // Second from top of floating point stack.
1315e5dd7070Spatrick   case 'q': // Any register accessible as [r]l: a, b, c, and d.
1316e5dd7070Spatrick   case 'y': // Any MMX register.
1317e5dd7070Spatrick   case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)
1318e5dd7070Spatrick   case 'x': // Any SSE register.
1319e5dd7070Spatrick   case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0
1320e5dd7070Spatrick             // for intermideate k reg operations).
1321e5dd7070Spatrick   case 'Q': // Any register accessible as [r]h: a, b, c, and d.
1322e5dd7070Spatrick   case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1323e5dd7070Spatrick   case 'l': // "Index" registers: any general register that can be used as an
1324e5dd7070Spatrick             // index in a base+index memory access.
1325e5dd7070Spatrick     Info.setAllowsRegister();
1326e5dd7070Spatrick     return true;
1327e5dd7070Spatrick   // Floating point constant constraints.
1328e5dd7070Spatrick   case 'C': // SSE floating point constant.
1329e5dd7070Spatrick   case 'G': // x87 floating point constant.
1330e5dd7070Spatrick     return true;
1331e5dd7070Spatrick   case '@':
1332e5dd7070Spatrick     // CC condition changes.
1333e5dd7070Spatrick     if (auto Len = matchAsmCCConstraint(Name)) {
1334e5dd7070Spatrick       Name += Len - 1;
1335e5dd7070Spatrick       Info.setAllowsRegister();
1336e5dd7070Spatrick       return true;
1337e5dd7070Spatrick     }
1338e5dd7070Spatrick     return false;
1339e5dd7070Spatrick   }
1340e5dd7070Spatrick }
1341e5dd7070Spatrick 
1342ec727ea7Spatrick // Below is based on the following information:
1343ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1344ec727ea7Spatrick // |           Processor Name           | Cache Line Size (Bytes) |                                                                            Source                                                                            |
1345ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1346ec727ea7Spatrick // | i386                               |                      64 | https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf                                          |
1347ec727ea7Spatrick // | i486                               |                      16 | "four doublewords" (doubleword = 32 bits, 4 bits * 32 bits = 16 bytes) https://en.wikichip.org/w/images/d/d3/i486_MICROPROCESSOR_HARDWARE_REFERENCE_MANUAL_%281990%29.pdf and http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.126.4216&rep=rep1&type=pdf (page 29) |
1348ec727ea7Spatrick // | i586/Pentium MMX                   |                      32 | https://www.7-cpu.com/cpu/P-MMX.html                                                                                                                         |
1349ec727ea7Spatrick // | i686/Pentium                       |                      32 | https://www.7-cpu.com/cpu/P6.html                                                                                                                            |
1350ec727ea7Spatrick // | Netburst/Pentium4                  |                      64 | https://www.7-cpu.com/cpu/P4-180.html                                                                                                                        |
1351ec727ea7Spatrick // | Atom                               |                      64 | https://www.7-cpu.com/cpu/Atom.html                                                                                                                          |
1352ec727ea7Spatrick // | Westmere                           |                      64 | https://en.wikichip.org/wiki/intel/microarchitectures/sandy_bridge_(client) "Cache Architecture"                                                             |
1353ec727ea7Spatrick // | Sandy Bridge                       |                      64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html                                                                    |
1354ec727ea7Spatrick // | Ivy Bridge                         |                      64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html                                                      |
1355ec727ea7Spatrick // | Haswell                            |                      64 | https://www.7-cpu.com/cpu/Haswell.html                                                                                                                       |
1356ec727ea7Spatrick // | Boadwell                           |                      64 | https://www.7-cpu.com/cpu/Broadwell.html                                                                                                                     |
1357ec727ea7Spatrick // | Skylake (including skylake-avx512) |                      64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy"                                                                       |
1358ec727ea7Spatrick // | Cascade Lake                       |                      64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy"                                                                  |
1359ec727ea7Spatrick // | Skylake                            |                      64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy"                                                                           |
1360ec727ea7Spatrick // | Ice Lake                           |                      64 | https://www.7-cpu.com/cpu/Ice_Lake.html                                                                                                                      |
1361ec727ea7Spatrick // | Knights Landing                    |                      64 | https://software.intel.com/en-us/articles/intel-xeon-phi-processor-7200-family-memory-management-optimizations "The Intel® Xeon Phi™ Processor Architecture" |
1362ec727ea7Spatrick // | Knights Mill                       |                      64 | https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf?countrylabel=Colombia "2.5.5.2 L1 DCache "       |
1363ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
getCPUCacheLineSize() const1364*7a9b00ceSrobert std::optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
1365ec727ea7Spatrick   using namespace llvm::X86;
1366ec727ea7Spatrick   switch (CPU) {
1367ec727ea7Spatrick     // i386
1368ec727ea7Spatrick     case CK_i386:
1369ec727ea7Spatrick     // i486
1370ec727ea7Spatrick     case CK_i486:
1371ec727ea7Spatrick     case CK_WinChipC6:
1372ec727ea7Spatrick     case CK_WinChip2:
1373ec727ea7Spatrick     case CK_C3:
1374ec727ea7Spatrick     // Lakemont
1375ec727ea7Spatrick     case CK_Lakemont:
1376ec727ea7Spatrick       return 16;
1377ec727ea7Spatrick 
1378ec727ea7Spatrick     // i586
1379ec727ea7Spatrick     case CK_i586:
1380ec727ea7Spatrick     case CK_Pentium:
1381ec727ea7Spatrick     case CK_PentiumMMX:
1382ec727ea7Spatrick     // i686
1383ec727ea7Spatrick     case CK_PentiumPro:
1384ec727ea7Spatrick     case CK_i686:
1385ec727ea7Spatrick     case CK_Pentium2:
1386ec727ea7Spatrick     case CK_Pentium3:
1387ec727ea7Spatrick     case CK_PentiumM:
1388ec727ea7Spatrick     case CK_C3_2:
1389ec727ea7Spatrick     // K6
1390ec727ea7Spatrick     case CK_K6:
1391ec727ea7Spatrick     case CK_K6_2:
1392ec727ea7Spatrick     case CK_K6_3:
1393ec727ea7Spatrick     // Geode
1394ec727ea7Spatrick     case CK_Geode:
1395ec727ea7Spatrick       return 32;
1396ec727ea7Spatrick 
1397ec727ea7Spatrick     // Netburst
1398ec727ea7Spatrick     case CK_Pentium4:
1399ec727ea7Spatrick     case CK_Prescott:
1400ec727ea7Spatrick     case CK_Nocona:
1401ec727ea7Spatrick     // Atom
1402ec727ea7Spatrick     case CK_Bonnell:
1403ec727ea7Spatrick     case CK_Silvermont:
1404ec727ea7Spatrick     case CK_Goldmont:
1405ec727ea7Spatrick     case CK_GoldmontPlus:
1406ec727ea7Spatrick     case CK_Tremont:
1407ec727ea7Spatrick 
1408ec727ea7Spatrick     case CK_Westmere:
1409ec727ea7Spatrick     case CK_SandyBridge:
1410ec727ea7Spatrick     case CK_IvyBridge:
1411ec727ea7Spatrick     case CK_Haswell:
1412ec727ea7Spatrick     case CK_Broadwell:
1413ec727ea7Spatrick     case CK_SkylakeClient:
1414ec727ea7Spatrick     case CK_SkylakeServer:
1415ec727ea7Spatrick     case CK_Cascadelake:
1416ec727ea7Spatrick     case CK_Nehalem:
1417ec727ea7Spatrick     case CK_Cooperlake:
1418ec727ea7Spatrick     case CK_Cannonlake:
1419ec727ea7Spatrick     case CK_Tigerlake:
1420a0747c9fSpatrick     case CK_SapphireRapids:
1421ec727ea7Spatrick     case CK_IcelakeClient:
1422a0747c9fSpatrick     case CK_Rocketlake:
1423ec727ea7Spatrick     case CK_IcelakeServer:
1424a0747c9fSpatrick     case CK_Alderlake:
1425*7a9b00ceSrobert     case CK_Raptorlake:
1426*7a9b00ceSrobert     case CK_Meteorlake:
1427*7a9b00ceSrobert     case CK_Sierraforest:
1428*7a9b00ceSrobert     case CK_Grandridge:
1429*7a9b00ceSrobert     case CK_Graniterapids:
1430*7a9b00ceSrobert     case CK_Emeraldrapids:
1431ec727ea7Spatrick     case CK_KNL:
1432ec727ea7Spatrick     case CK_KNM:
1433ec727ea7Spatrick     // K7
1434ec727ea7Spatrick     case CK_Athlon:
1435ec727ea7Spatrick     case CK_AthlonXP:
1436ec727ea7Spatrick     // K8
1437ec727ea7Spatrick     case CK_K8:
1438ec727ea7Spatrick     case CK_K8SSE3:
1439ec727ea7Spatrick     case CK_AMDFAM10:
1440ec727ea7Spatrick     // Bobcat
1441ec727ea7Spatrick     case CK_BTVER1:
1442ec727ea7Spatrick     case CK_BTVER2:
1443ec727ea7Spatrick     // Bulldozer
1444ec727ea7Spatrick     case CK_BDVER1:
1445ec727ea7Spatrick     case CK_BDVER2:
1446ec727ea7Spatrick     case CK_BDVER3:
1447ec727ea7Spatrick     case CK_BDVER4:
1448ec727ea7Spatrick     // Zen
1449ec727ea7Spatrick     case CK_ZNVER1:
1450ec727ea7Spatrick     case CK_ZNVER2:
1451a0747c9fSpatrick     case CK_ZNVER3:
1452*7a9b00ceSrobert     case CK_ZNVER4:
1453ec727ea7Spatrick     // Deprecated
1454ec727ea7Spatrick     case CK_x86_64:
1455a0747c9fSpatrick     case CK_x86_64_v2:
1456a0747c9fSpatrick     case CK_x86_64_v3:
1457a0747c9fSpatrick     case CK_x86_64_v4:
1458ec727ea7Spatrick     case CK_Yonah:
1459ec727ea7Spatrick     case CK_Penryn:
1460ec727ea7Spatrick     case CK_Core2:
1461ec727ea7Spatrick       return 64;
1462ec727ea7Spatrick 
1463ec727ea7Spatrick     // The following currently have unknown cache line sizes (but they are probably all 64):
1464ec727ea7Spatrick     // Core
1465ec727ea7Spatrick     case CK_None:
1466*7a9b00ceSrobert       return std::nullopt;
1467ec727ea7Spatrick   }
1468ec727ea7Spatrick   llvm_unreachable("Unknown CPU kind");
1469ec727ea7Spatrick }
1470ec727ea7Spatrick 
validateOutputSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1471e5dd7070Spatrick bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
1472e5dd7070Spatrick                                        StringRef Constraint,
1473e5dd7070Spatrick                                        unsigned Size) const {
1474e5dd7070Spatrick   // Strip off constraint modifiers.
1475e5dd7070Spatrick   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1476e5dd7070Spatrick     Constraint = Constraint.substr(1);
1477e5dd7070Spatrick 
1478e5dd7070Spatrick   return validateOperandSize(FeatureMap, Constraint, Size);
1479e5dd7070Spatrick }
1480e5dd7070Spatrick 
validateInputSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1481e5dd7070Spatrick bool X86TargetInfo::validateInputSize(const llvm::StringMap<bool> &FeatureMap,
1482e5dd7070Spatrick                                       StringRef Constraint,
1483e5dd7070Spatrick                                       unsigned Size) const {
1484e5dd7070Spatrick   return validateOperandSize(FeatureMap, Constraint, Size);
1485e5dd7070Spatrick }
1486e5dd7070Spatrick 
validateOperandSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1487e5dd7070Spatrick bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
1488e5dd7070Spatrick                                         StringRef Constraint,
1489e5dd7070Spatrick                                         unsigned Size) const {
1490e5dd7070Spatrick   switch (Constraint[0]) {
1491e5dd7070Spatrick   default:
1492e5dd7070Spatrick     break;
1493e5dd7070Spatrick   case 'k':
1494e5dd7070Spatrick   // Registers k0-k7 (AVX512) size limit is 64 bit.
1495e5dd7070Spatrick   case 'y':
1496e5dd7070Spatrick     return Size <= 64;
1497e5dd7070Spatrick   case 'f':
1498e5dd7070Spatrick   case 't':
1499e5dd7070Spatrick   case 'u':
1500e5dd7070Spatrick     return Size <= 128;
1501e5dd7070Spatrick   case 'Y':
1502e5dd7070Spatrick     // 'Y' is the first character for several 2-character constraints.
1503e5dd7070Spatrick     switch (Constraint[1]) {
1504e5dd7070Spatrick     default:
1505e5dd7070Spatrick       return false;
1506e5dd7070Spatrick     case 'm':
1507e5dd7070Spatrick       // 'Ym' is synonymous with 'y'.
1508e5dd7070Spatrick     case 'k':
1509e5dd7070Spatrick       return Size <= 64;
1510e5dd7070Spatrick     case 'z':
1511ec727ea7Spatrick       // XMM0/YMM/ZMM0
1512a0747c9fSpatrick       if (hasFeatureEnabled(FeatureMap, "avx512f"))
1513ec727ea7Spatrick         // ZMM0 can be used if target supports AVX512F.
1514ec727ea7Spatrick         return Size <= 512U;
1515a0747c9fSpatrick       else if (hasFeatureEnabled(FeatureMap, "avx"))
1516ec727ea7Spatrick         // YMM0 can be used if target supports AVX.
1517ec727ea7Spatrick         return Size <= 256U;
1518a0747c9fSpatrick       else if (hasFeatureEnabled(FeatureMap, "sse"))
1519e5dd7070Spatrick         return Size <= 128U;
1520e5dd7070Spatrick       return false;
1521e5dd7070Spatrick     case 'i':
1522e5dd7070Spatrick     case 't':
1523e5dd7070Spatrick     case '2':
1524e5dd7070Spatrick       // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled.
1525e5dd7070Spatrick       if (SSELevel < SSE2)
1526e5dd7070Spatrick         return false;
1527e5dd7070Spatrick       break;
1528e5dd7070Spatrick     }
1529ec727ea7Spatrick     break;
1530e5dd7070Spatrick   case 'v':
1531e5dd7070Spatrick   case 'x':
1532a0747c9fSpatrick     if (hasFeatureEnabled(FeatureMap, "avx512f"))
1533e5dd7070Spatrick       // 512-bit zmm registers can be used if target supports AVX512F.
1534e5dd7070Spatrick       return Size <= 512U;
1535a0747c9fSpatrick     else if (hasFeatureEnabled(FeatureMap, "avx"))
1536e5dd7070Spatrick       // 256-bit ymm registers can be used if target supports AVX.
1537e5dd7070Spatrick       return Size <= 256U;
1538e5dd7070Spatrick     return Size <= 128U;
1539e5dd7070Spatrick 
1540e5dd7070Spatrick   }
1541e5dd7070Spatrick 
1542e5dd7070Spatrick   return true;
1543e5dd7070Spatrick }
1544e5dd7070Spatrick 
convertConstraint(const char * & Constraint) const1545e5dd7070Spatrick std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
1546e5dd7070Spatrick   switch (*Constraint) {
1547e5dd7070Spatrick   case '@':
1548e5dd7070Spatrick     if (auto Len = matchAsmCCConstraint(Constraint)) {
1549e5dd7070Spatrick       std::string Converted = "{" + std::string(Constraint, Len) + "}";
1550e5dd7070Spatrick       Constraint += Len - 1;
1551e5dd7070Spatrick       return Converted;
1552e5dd7070Spatrick     }
1553e5dd7070Spatrick     return std::string(1, *Constraint);
1554e5dd7070Spatrick   case 'a':
1555e5dd7070Spatrick     return std::string("{ax}");
1556e5dd7070Spatrick   case 'b':
1557e5dd7070Spatrick     return std::string("{bx}");
1558e5dd7070Spatrick   case 'c':
1559e5dd7070Spatrick     return std::string("{cx}");
1560e5dd7070Spatrick   case 'd':
1561e5dd7070Spatrick     return std::string("{dx}");
1562e5dd7070Spatrick   case 'S':
1563e5dd7070Spatrick     return std::string("{si}");
1564e5dd7070Spatrick   case 'D':
1565e5dd7070Spatrick     return std::string("{di}");
1566*7a9b00ceSrobert   case 'p': // Keep 'p' constraint (address).
1567*7a9b00ceSrobert     return std::string("p");
1568e5dd7070Spatrick   case 't': // top of floating point stack.
1569e5dd7070Spatrick     return std::string("{st}");
1570e5dd7070Spatrick   case 'u':                        // second from top of floating point stack.
1571e5dd7070Spatrick     return std::string("{st(1)}"); // second from top of floating point stack.
1572e5dd7070Spatrick   case 'Y':
1573e5dd7070Spatrick     switch (Constraint[1]) {
1574e5dd7070Spatrick     default:
1575e5dd7070Spatrick       // Break from inner switch and fall through (copy single char),
1576e5dd7070Spatrick       // continue parsing after copying the current constraint into
1577e5dd7070Spatrick       // the return string.
1578e5dd7070Spatrick       break;
1579e5dd7070Spatrick     case 'k':
1580e5dd7070Spatrick     case 'm':
1581e5dd7070Spatrick     case 'i':
1582e5dd7070Spatrick     case 't':
1583e5dd7070Spatrick     case 'z':
1584e5dd7070Spatrick     case '2':
1585e5dd7070Spatrick       // "^" hints llvm that this is a 2 letter constraint.
1586e5dd7070Spatrick       // "Constraint++" is used to promote the string iterator
1587e5dd7070Spatrick       // to the next constraint.
1588e5dd7070Spatrick       return std::string("^") + std::string(Constraint++, 2);
1589e5dd7070Spatrick     }
1590*7a9b00ceSrobert     [[fallthrough]];
1591e5dd7070Spatrick   default:
1592e5dd7070Spatrick     return std::string(1, *Constraint);
1593e5dd7070Spatrick   }
1594e5dd7070Spatrick }
1595e5dd7070Spatrick 
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const1596e5dd7070Spatrick void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
1597ec727ea7Spatrick   bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
1598ec727ea7Spatrick   llvm::X86::fillValidCPUArchList(Values, Only64Bit);
1599e5dd7070Spatrick }
1600e5dd7070Spatrick 
fillValidTuneCPUList(SmallVectorImpl<StringRef> & Values) const1601a0747c9fSpatrick void X86TargetInfo::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const {
1602a0747c9fSpatrick   llvm::X86::fillValidTuneCPUList(Values);
1603a0747c9fSpatrick }
1604a0747c9fSpatrick 
getGCCRegNames() const1605e5dd7070Spatrick ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {
1606*7a9b00ceSrobert   return llvm::ArrayRef(GCCRegNames);
1607e5dd7070Spatrick }
1608e5dd7070Spatrick 
getGCCAddlRegNames() const1609e5dd7070Spatrick ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
1610*7a9b00ceSrobert   return llvm::ArrayRef(AddlRegNames);
1611e5dd7070Spatrick }
1612e5dd7070Spatrick 
getTargetBuiltins() const1613e5dd7070Spatrick ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
1614*7a9b00ceSrobert   return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
1615e5dd7070Spatrick                                             Builtin::FirstTSBuiltin + 1);
1616e5dd7070Spatrick }
1617e5dd7070Spatrick 
getTargetBuiltins() const1618e5dd7070Spatrick ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
1619*7a9b00ceSrobert   return llvm::ArrayRef(BuiltinInfoX86,
1620e5dd7070Spatrick                         X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
1621e5dd7070Spatrick }
1622