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