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