106f32e7eSjoerg //===--- X86.cpp - Implement X86 target feature support -------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file implements X86 TargetInfo objects.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg 
1306f32e7eSjoerg #include "X86.h"
1406f32e7eSjoerg #include "clang/Basic/Builtins.h"
1506f32e7eSjoerg #include "clang/Basic/Diagnostic.h"
1606f32e7eSjoerg #include "clang/Basic/TargetBuiltins.h"
1706f32e7eSjoerg #include "llvm/ADT/StringExtras.h"
1806f32e7eSjoerg #include "llvm/ADT/StringRef.h"
1906f32e7eSjoerg #include "llvm/ADT/StringSwitch.h"
20*13fbcb42Sjoerg #include "llvm/Support/X86TargetParser.h"
2106f32e7eSjoerg 
2206f32e7eSjoerg namespace clang {
2306f32e7eSjoerg namespace targets {
2406f32e7eSjoerg 
2506f32e7eSjoerg const Builtin::Info BuiltinInfoX86[] = {
2606f32e7eSjoerg #define BUILTIN(ID, TYPE, ATTRS)                                               \
2706f32e7eSjoerg   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
2806f32e7eSjoerg #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
2906f32e7eSjoerg   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
3006f32e7eSjoerg #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
3106f32e7eSjoerg   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
3206f32e7eSjoerg #include "clang/Basic/BuiltinsX86.def"
3306f32e7eSjoerg 
3406f32e7eSjoerg #define BUILTIN(ID, TYPE, ATTRS)                                               \
3506f32e7eSjoerg   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
3606f32e7eSjoerg #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
3706f32e7eSjoerg   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
3806f32e7eSjoerg #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
3906f32e7eSjoerg   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
4006f32e7eSjoerg #include "clang/Basic/BuiltinsX86_64.def"
4106f32e7eSjoerg };
4206f32e7eSjoerg 
4306f32e7eSjoerg static const char *const GCCRegNames[] = {
4406f32e7eSjoerg     "ax",    "dx",    "cx",    "bx",    "si",      "di",    "bp",    "sp",
4506f32e7eSjoerg     "st",    "st(1)", "st(2)", "st(3)", "st(4)",   "st(5)", "st(6)", "st(7)",
4606f32e7eSjoerg     "argp",  "flags", "fpcr",  "fpsr",  "dirflag", "frame", "xmm0",  "xmm1",
4706f32e7eSjoerg     "xmm2",  "xmm3",  "xmm4",  "xmm5",  "xmm6",    "xmm7",  "mm0",   "mm1",
4806f32e7eSjoerg     "mm2",   "mm3",   "mm4",   "mm5",   "mm6",     "mm7",   "r8",    "r9",
4906f32e7eSjoerg     "r10",   "r11",   "r12",   "r13",   "r14",     "r15",   "xmm8",  "xmm9",
5006f32e7eSjoerg     "xmm10", "xmm11", "xmm12", "xmm13", "xmm14",   "xmm15", "ymm0",  "ymm1",
5106f32e7eSjoerg     "ymm2",  "ymm3",  "ymm4",  "ymm5",  "ymm6",    "ymm7",  "ymm8",  "ymm9",
5206f32e7eSjoerg     "ymm10", "ymm11", "ymm12", "ymm13", "ymm14",   "ymm15", "xmm16", "xmm17",
5306f32e7eSjoerg     "xmm18", "xmm19", "xmm20", "xmm21", "xmm22",   "xmm23", "xmm24", "xmm25",
5406f32e7eSjoerg     "xmm26", "xmm27", "xmm28", "xmm29", "xmm30",   "xmm31", "ymm16", "ymm17",
5506f32e7eSjoerg     "ymm18", "ymm19", "ymm20", "ymm21", "ymm22",   "ymm23", "ymm24", "ymm25",
5606f32e7eSjoerg     "ymm26", "ymm27", "ymm28", "ymm29", "ymm30",   "ymm31", "zmm0",  "zmm1",
5706f32e7eSjoerg     "zmm2",  "zmm3",  "zmm4",  "zmm5",  "zmm6",    "zmm7",  "zmm8",  "zmm9",
5806f32e7eSjoerg     "zmm10", "zmm11", "zmm12", "zmm13", "zmm14",   "zmm15", "zmm16", "zmm17",
5906f32e7eSjoerg     "zmm18", "zmm19", "zmm20", "zmm21", "zmm22",   "zmm23", "zmm24", "zmm25",
6006f32e7eSjoerg     "zmm26", "zmm27", "zmm28", "zmm29", "zmm30",   "zmm31", "k0",    "k1",
6106f32e7eSjoerg     "k2",    "k3",    "k4",    "k5",    "k6",      "k7",
6206f32e7eSjoerg     "cr0",   "cr2",   "cr3",   "cr4",   "cr8",
6306f32e7eSjoerg     "dr0",   "dr1",   "dr2",   "dr3",   "dr6",     "dr7",
6406f32e7eSjoerg     "bnd0",  "bnd1",  "bnd2",  "bnd3",
65*13fbcb42Sjoerg     "tmm0",  "tmm1",  "tmm2",  "tmm3",  "tmm4",    "tmm5",  "tmm6",  "tmm7",
6606f32e7eSjoerg };
6706f32e7eSjoerg 
6806f32e7eSjoerg const TargetInfo::AddlRegName AddlRegNames[] = {
6906f32e7eSjoerg     {{"al", "ah", "eax", "rax"}, 0},
7006f32e7eSjoerg     {{"bl", "bh", "ebx", "rbx"}, 3},
7106f32e7eSjoerg     {{"cl", "ch", "ecx", "rcx"}, 2},
7206f32e7eSjoerg     {{"dl", "dh", "edx", "rdx"}, 1},
7306f32e7eSjoerg     {{"esi", "rsi"}, 4},
7406f32e7eSjoerg     {{"edi", "rdi"}, 5},
7506f32e7eSjoerg     {{"esp", "rsp"}, 7},
7606f32e7eSjoerg     {{"ebp", "rbp"}, 6},
7706f32e7eSjoerg     {{"r8d", "r8w", "r8b"}, 38},
7806f32e7eSjoerg     {{"r9d", "r9w", "r9b"}, 39},
7906f32e7eSjoerg     {{"r10d", "r10w", "r10b"}, 40},
8006f32e7eSjoerg     {{"r11d", "r11w", "r11b"}, 41},
8106f32e7eSjoerg     {{"r12d", "r12w", "r12b"}, 42},
8206f32e7eSjoerg     {{"r13d", "r13w", "r13b"}, 43},
8306f32e7eSjoerg     {{"r14d", "r14w", "r14b"}, 44},
8406f32e7eSjoerg     {{"r15d", "r15w", "r15b"}, 45},
8506f32e7eSjoerg };
8606f32e7eSjoerg 
8706f32e7eSjoerg } // namespace targets
8806f32e7eSjoerg } // namespace clang
8906f32e7eSjoerg 
9006f32e7eSjoerg using namespace clang;
9106f32e7eSjoerg using namespace clang::targets;
9206f32e7eSjoerg 
setFPMath(StringRef Name)9306f32e7eSjoerg bool X86TargetInfo::setFPMath(StringRef Name) {
9406f32e7eSjoerg   if (Name == "387") {
9506f32e7eSjoerg     FPMath = FP_387;
9606f32e7eSjoerg     return true;
9706f32e7eSjoerg   }
9806f32e7eSjoerg   if (Name == "sse") {
9906f32e7eSjoerg     FPMath = FP_SSE;
10006f32e7eSjoerg     return true;
10106f32e7eSjoerg   }
10206f32e7eSjoerg   return false;
10306f32e7eSjoerg }
10406f32e7eSjoerg 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const10506f32e7eSjoerg bool X86TargetInfo::initFeatureMap(
10606f32e7eSjoerg     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
10706f32e7eSjoerg     const std::vector<std::string> &FeaturesVec) const {
10806f32e7eSjoerg   // FIXME: This *really* should not be here.
10906f32e7eSjoerg   // X86_64 always has SSE2.
11006f32e7eSjoerg   if (getTriple().getArch() == llvm::Triple::x86_64)
111*13fbcb42Sjoerg     setFeatureEnabled(Features, "sse2", true);
11206f32e7eSjoerg 
113*13fbcb42Sjoerg   using namespace llvm::X86;
11406f32e7eSjoerg 
115*13fbcb42Sjoerg   SmallVector<StringRef, 16> CPUFeatures;
116*13fbcb42Sjoerg   getFeaturesForCPU(CPU, CPUFeatures);
117*13fbcb42Sjoerg   for (auto &F : CPUFeatures)
118*13fbcb42Sjoerg     setFeatureEnabled(Features, F, true);
11906f32e7eSjoerg 
12006f32e7eSjoerg   if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec))
12106f32e7eSjoerg     return false;
12206f32e7eSjoerg 
12306f32e7eSjoerg   // Can't do this earlier because we need to be able to explicitly enable
12406f32e7eSjoerg   // or disable these features and the things that they depend upon.
12506f32e7eSjoerg 
12606f32e7eSjoerg   // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
12706f32e7eSjoerg   auto I = Features.find("sse4.2");
12806f32e7eSjoerg   if (I != Features.end() && I->getValue() &&
12906f32e7eSjoerg       llvm::find(FeaturesVec, "-popcnt") == FeaturesVec.end())
13006f32e7eSjoerg     Features["popcnt"] = true;
13106f32e7eSjoerg 
13206f32e7eSjoerg   // Additionally, if SSE is enabled and mmx is not explicitly disabled,
13306f32e7eSjoerg   // then enable MMX.
13406f32e7eSjoerg   I = Features.find("sse");
13506f32e7eSjoerg   if (I != Features.end() && I->getValue() &&
13606f32e7eSjoerg       llvm::find(FeaturesVec, "-mmx") == FeaturesVec.end())
13706f32e7eSjoerg     Features["mmx"] = true;
13806f32e7eSjoerg 
139*13fbcb42Sjoerg   // Enable xsave if avx is enabled and xsave is not explicitly disabled.
140*13fbcb42Sjoerg   I = Features.find("avx");
141*13fbcb42Sjoerg   if (I != Features.end() && I->getValue() &&
142*13fbcb42Sjoerg       llvm::find(FeaturesVec, "-xsave") == FeaturesVec.end())
143*13fbcb42Sjoerg     Features["xsave"] = true;
144*13fbcb42Sjoerg 
14506f32e7eSjoerg   return true;
14606f32e7eSjoerg }
14706f32e7eSjoerg 
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const148*13fbcb42Sjoerg void X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
149*13fbcb42Sjoerg                                       StringRef Name, bool Enabled) const {
150*13fbcb42Sjoerg   if (Name == "sse4") {
15106f32e7eSjoerg     // We can get here via the __target__ attribute since that's not controlled
15206f32e7eSjoerg     // via the -msse4/-mno-sse4 command line alias. Handle this the same way
15306f32e7eSjoerg     // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if
15406f32e7eSjoerg     // disabled.
15506f32e7eSjoerg     if (Enabled)
156*13fbcb42Sjoerg       Name = "sse4.2";
15706f32e7eSjoerg     else
158*13fbcb42Sjoerg       Name = "sse4.1";
15906f32e7eSjoerg   }
160*13fbcb42Sjoerg 
161*13fbcb42Sjoerg   Features[Name] = Enabled;
162*13fbcb42Sjoerg   llvm::X86::updateImpliedFeatures(Name, Enabled, Features);
16306f32e7eSjoerg }
16406f32e7eSjoerg 
16506f32e7eSjoerg /// handleTargetFeatures - Perform initialization based on the user
16606f32e7eSjoerg /// configured set of features.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)16706f32e7eSjoerg bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
16806f32e7eSjoerg                                          DiagnosticsEngine &Diags) {
16906f32e7eSjoerg   for (const auto &Feature : Features) {
17006f32e7eSjoerg     if (Feature[0] != '+')
17106f32e7eSjoerg       continue;
17206f32e7eSjoerg 
17306f32e7eSjoerg     if (Feature == "+aes") {
17406f32e7eSjoerg       HasAES = true;
17506f32e7eSjoerg     } else if (Feature == "+vaes") {
17606f32e7eSjoerg       HasVAES = true;
17706f32e7eSjoerg     } else if (Feature == "+pclmul") {
17806f32e7eSjoerg       HasPCLMUL = true;
17906f32e7eSjoerg     } else if (Feature == "+vpclmulqdq") {
18006f32e7eSjoerg       HasVPCLMULQDQ = true;
18106f32e7eSjoerg     } else if (Feature == "+lzcnt") {
18206f32e7eSjoerg       HasLZCNT = true;
18306f32e7eSjoerg     } else if (Feature == "+rdrnd") {
18406f32e7eSjoerg       HasRDRND = true;
18506f32e7eSjoerg     } else if (Feature == "+fsgsbase") {
18606f32e7eSjoerg       HasFSGSBASE = true;
18706f32e7eSjoerg     } else if (Feature == "+bmi") {
18806f32e7eSjoerg       HasBMI = true;
18906f32e7eSjoerg     } else if (Feature == "+bmi2") {
19006f32e7eSjoerg       HasBMI2 = true;
19106f32e7eSjoerg     } else if (Feature == "+popcnt") {
19206f32e7eSjoerg       HasPOPCNT = true;
19306f32e7eSjoerg     } else if (Feature == "+rtm") {
19406f32e7eSjoerg       HasRTM = true;
19506f32e7eSjoerg     } else if (Feature == "+prfchw") {
19606f32e7eSjoerg       HasPRFCHW = true;
19706f32e7eSjoerg     } else if (Feature == "+rdseed") {
19806f32e7eSjoerg       HasRDSEED = true;
19906f32e7eSjoerg     } else if (Feature == "+adx") {
20006f32e7eSjoerg       HasADX = true;
20106f32e7eSjoerg     } else if (Feature == "+tbm") {
20206f32e7eSjoerg       HasTBM = true;
20306f32e7eSjoerg     } else if (Feature == "+lwp") {
20406f32e7eSjoerg       HasLWP = true;
20506f32e7eSjoerg     } else if (Feature == "+fma") {
20606f32e7eSjoerg       HasFMA = true;
20706f32e7eSjoerg     } else if (Feature == "+f16c") {
20806f32e7eSjoerg       HasF16C = true;
20906f32e7eSjoerg     } else if (Feature == "+gfni") {
21006f32e7eSjoerg       HasGFNI = true;
21106f32e7eSjoerg     } else if (Feature == "+avx512cd") {
21206f32e7eSjoerg       HasAVX512CD = true;
21306f32e7eSjoerg     } else if (Feature == "+avx512vpopcntdq") {
21406f32e7eSjoerg       HasAVX512VPOPCNTDQ = true;
21506f32e7eSjoerg     } else if (Feature == "+avx512vnni") {
21606f32e7eSjoerg       HasAVX512VNNI = true;
21706f32e7eSjoerg     } else if (Feature == "+avx512bf16") {
21806f32e7eSjoerg       HasAVX512BF16 = true;
21906f32e7eSjoerg     } else if (Feature == "+avx512er") {
22006f32e7eSjoerg       HasAVX512ER = true;
22106f32e7eSjoerg     } else if (Feature == "+avx512pf") {
22206f32e7eSjoerg       HasAVX512PF = true;
22306f32e7eSjoerg     } else if (Feature == "+avx512dq") {
22406f32e7eSjoerg       HasAVX512DQ = true;
22506f32e7eSjoerg     } else if (Feature == "+avx512bitalg") {
22606f32e7eSjoerg       HasAVX512BITALG = true;
22706f32e7eSjoerg     } else if (Feature == "+avx512bw") {
22806f32e7eSjoerg       HasAVX512BW = true;
22906f32e7eSjoerg     } else if (Feature == "+avx512vl") {
23006f32e7eSjoerg       HasAVX512VL = true;
23106f32e7eSjoerg     } else if (Feature == "+avx512vbmi") {
23206f32e7eSjoerg       HasAVX512VBMI = true;
23306f32e7eSjoerg     } else if (Feature == "+avx512vbmi2") {
23406f32e7eSjoerg       HasAVX512VBMI2 = true;
23506f32e7eSjoerg     } else if (Feature == "+avx512ifma") {
23606f32e7eSjoerg       HasAVX512IFMA = true;
23706f32e7eSjoerg     } else if (Feature == "+avx512vp2intersect") {
23806f32e7eSjoerg       HasAVX512VP2INTERSECT = true;
23906f32e7eSjoerg     } else if (Feature == "+sha") {
24006f32e7eSjoerg       HasSHA = true;
24106f32e7eSjoerg     } else if (Feature == "+shstk") {
24206f32e7eSjoerg       HasSHSTK = true;
24306f32e7eSjoerg     } else if (Feature == "+movbe") {
24406f32e7eSjoerg       HasMOVBE = true;
24506f32e7eSjoerg     } else if (Feature == "+sgx") {
24606f32e7eSjoerg       HasSGX = true;
24706f32e7eSjoerg     } else if (Feature == "+cx8") {
24806f32e7eSjoerg       HasCX8 = true;
24906f32e7eSjoerg     } else if (Feature == "+cx16") {
25006f32e7eSjoerg       HasCX16 = true;
25106f32e7eSjoerg     } else if (Feature == "+fxsr") {
25206f32e7eSjoerg       HasFXSR = true;
25306f32e7eSjoerg     } else if (Feature == "+xsave") {
25406f32e7eSjoerg       HasXSAVE = true;
25506f32e7eSjoerg     } else if (Feature == "+xsaveopt") {
25606f32e7eSjoerg       HasXSAVEOPT = true;
25706f32e7eSjoerg     } else if (Feature == "+xsavec") {
25806f32e7eSjoerg       HasXSAVEC = true;
25906f32e7eSjoerg     } else if (Feature == "+xsaves") {
26006f32e7eSjoerg       HasXSAVES = true;
26106f32e7eSjoerg     } else if (Feature == "+mwaitx") {
26206f32e7eSjoerg       HasMWAITX = true;
26306f32e7eSjoerg     } else if (Feature == "+pku") {
26406f32e7eSjoerg       HasPKU = true;
26506f32e7eSjoerg     } else if (Feature == "+clflushopt") {
26606f32e7eSjoerg       HasCLFLUSHOPT = true;
26706f32e7eSjoerg     } else if (Feature == "+clwb") {
26806f32e7eSjoerg       HasCLWB = true;
26906f32e7eSjoerg     } else if (Feature == "+wbnoinvd") {
27006f32e7eSjoerg       HasWBNOINVD = true;
27106f32e7eSjoerg     } else if (Feature == "+prefetchwt1") {
27206f32e7eSjoerg       HasPREFETCHWT1 = true;
27306f32e7eSjoerg     } else if (Feature == "+clzero") {
27406f32e7eSjoerg       HasCLZERO = true;
27506f32e7eSjoerg     } else if (Feature == "+cldemote") {
27606f32e7eSjoerg       HasCLDEMOTE = true;
27706f32e7eSjoerg     } else if (Feature == "+rdpid") {
27806f32e7eSjoerg       HasRDPID = true;
279*13fbcb42Sjoerg     } else if (Feature == "+kl") {
280*13fbcb42Sjoerg       HasKL = true;
281*13fbcb42Sjoerg     } else if (Feature == "+widekl") {
282*13fbcb42Sjoerg       HasWIDEKL = true;
28306f32e7eSjoerg     } else if (Feature == "+retpoline-external-thunk") {
28406f32e7eSjoerg       HasRetpolineExternalThunk = true;
28506f32e7eSjoerg     } else if (Feature == "+sahf") {
28606f32e7eSjoerg       HasLAHFSAHF = true;
28706f32e7eSjoerg     } else if (Feature == "+waitpkg") {
28806f32e7eSjoerg       HasWAITPKG = true;
28906f32e7eSjoerg     } else if (Feature == "+movdiri") {
29006f32e7eSjoerg       HasMOVDIRI = true;
29106f32e7eSjoerg     } else if (Feature == "+movdir64b") {
29206f32e7eSjoerg       HasMOVDIR64B = true;
29306f32e7eSjoerg     } else if (Feature == "+pconfig") {
29406f32e7eSjoerg       HasPCONFIG = true;
29506f32e7eSjoerg     } else if (Feature == "+ptwrite") {
29606f32e7eSjoerg       HasPTWRITE = true;
29706f32e7eSjoerg     } else if (Feature == "+invpcid") {
29806f32e7eSjoerg       HasINVPCID = true;
29906f32e7eSjoerg     } else if (Feature == "+enqcmd") {
30006f32e7eSjoerg       HasENQCMD = true;
301*13fbcb42Sjoerg     } else if (Feature == "+hreset") {
302*13fbcb42Sjoerg       HasHRESET = true;
303*13fbcb42Sjoerg     } else if (Feature == "+amx-bf16") {
304*13fbcb42Sjoerg       HasAMXBF16 = true;
305*13fbcb42Sjoerg     } else if (Feature == "+amx-int8") {
306*13fbcb42Sjoerg       HasAMXINT8 = true;
307*13fbcb42Sjoerg     } else if (Feature == "+amx-tile") {
308*13fbcb42Sjoerg       HasAMXTILE = true;
309*13fbcb42Sjoerg     } else if (Feature == "+avxvnni") {
310*13fbcb42Sjoerg       HasAVXVNNI = true;
311*13fbcb42Sjoerg     } else if (Feature == "+serialize") {
312*13fbcb42Sjoerg       HasSERIALIZE = true;
313*13fbcb42Sjoerg     } else if (Feature == "+tsxldtrk") {
314*13fbcb42Sjoerg       HasTSXLDTRK = true;
315*13fbcb42Sjoerg     } else if (Feature == "+uintr") {
316*13fbcb42Sjoerg       HasUINTR = true;
31706f32e7eSjoerg     }
31806f32e7eSjoerg 
31906f32e7eSjoerg     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
32006f32e7eSjoerg                            .Case("+avx512f", AVX512F)
32106f32e7eSjoerg                            .Case("+avx2", AVX2)
32206f32e7eSjoerg                            .Case("+avx", AVX)
32306f32e7eSjoerg                            .Case("+sse4.2", SSE42)
32406f32e7eSjoerg                            .Case("+sse4.1", SSE41)
32506f32e7eSjoerg                            .Case("+ssse3", SSSE3)
32606f32e7eSjoerg                            .Case("+sse3", SSE3)
32706f32e7eSjoerg                            .Case("+sse2", SSE2)
32806f32e7eSjoerg                            .Case("+sse", SSE1)
32906f32e7eSjoerg                            .Default(NoSSE);
33006f32e7eSjoerg     SSELevel = std::max(SSELevel, Level);
33106f32e7eSjoerg 
33206f32e7eSjoerg     MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature)
33306f32e7eSjoerg                                       .Case("+3dnowa", AMD3DNowAthlon)
33406f32e7eSjoerg                                       .Case("+3dnow", AMD3DNow)
33506f32e7eSjoerg                                       .Case("+mmx", MMX)
33606f32e7eSjoerg                                       .Default(NoMMX3DNow);
33706f32e7eSjoerg     MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
33806f32e7eSjoerg 
33906f32e7eSjoerg     XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
34006f32e7eSjoerg                          .Case("+xop", XOP)
34106f32e7eSjoerg                          .Case("+fma4", FMA4)
34206f32e7eSjoerg                          .Case("+sse4a", SSE4A)
34306f32e7eSjoerg                          .Default(NoXOP);
34406f32e7eSjoerg     XOPLevel = std::max(XOPLevel, XLevel);
34506f32e7eSjoerg   }
34606f32e7eSjoerg 
34706f32e7eSjoerg   // LLVM doesn't have a separate switch for fpmath, so only accept it if it
34806f32e7eSjoerg   // matches the selected sse level.
34906f32e7eSjoerg   if ((FPMath == FP_SSE && SSELevel < SSE1) ||
35006f32e7eSjoerg       (FPMath == FP_387 && SSELevel >= SSE1)) {
35106f32e7eSjoerg     Diags.Report(diag::err_target_unsupported_fpmath)
35206f32e7eSjoerg         << (FPMath == FP_SSE ? "sse" : "387");
35306f32e7eSjoerg     return false;
35406f32e7eSjoerg   }
35506f32e7eSjoerg 
35606f32e7eSjoerg   SimdDefaultAlign =
35706f32e7eSjoerg       hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
35806f32e7eSjoerg   return true;
35906f32e7eSjoerg }
36006f32e7eSjoerg 
36106f32e7eSjoerg /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
36206f32e7eSjoerg /// definitions for this particular subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const36306f32e7eSjoerg void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
36406f32e7eSjoerg                                      MacroBuilder &Builder) const {
36506f32e7eSjoerg   // Inline assembly supports X86 flag outputs.
36606f32e7eSjoerg   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
36706f32e7eSjoerg 
36806f32e7eSjoerg   std::string CodeModel = getTargetOpts().CodeModel;
36906f32e7eSjoerg   if (CodeModel == "default")
37006f32e7eSjoerg     CodeModel = "small";
371*13fbcb42Sjoerg   Builder.defineMacro("__code_model_" + CodeModel + "__");
37206f32e7eSjoerg 
37306f32e7eSjoerg   // Target identification.
37406f32e7eSjoerg   if (getTriple().getArch() == llvm::Triple::x86_64) {
37506f32e7eSjoerg     Builder.defineMacro("__amd64__");
37606f32e7eSjoerg     Builder.defineMacro("__amd64");
37706f32e7eSjoerg     Builder.defineMacro("__x86_64");
37806f32e7eSjoerg     Builder.defineMacro("__x86_64__");
37906f32e7eSjoerg     if (getTriple().getArchName() == "x86_64h") {
38006f32e7eSjoerg       Builder.defineMacro("__x86_64h");
38106f32e7eSjoerg       Builder.defineMacro("__x86_64h__");
38206f32e7eSjoerg     }
38306f32e7eSjoerg   } else {
38406f32e7eSjoerg     DefineStd(Builder, "i386", Opts);
38506f32e7eSjoerg   }
38606f32e7eSjoerg 
38706f32e7eSjoerg   Builder.defineMacro("__SEG_GS");
38806f32e7eSjoerg   Builder.defineMacro("__SEG_FS");
38906f32e7eSjoerg   Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))");
39006f32e7eSjoerg   Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))");
39106f32e7eSjoerg 
39206f32e7eSjoerg   // Subtarget options.
39306f32e7eSjoerg   // FIXME: We are hard-coding the tune parameters based on the CPU, but they
39406f32e7eSjoerg   // truly should be based on -mtune options.
395*13fbcb42Sjoerg   using namespace llvm::X86;
39606f32e7eSjoerg   switch (CPU) {
397*13fbcb42Sjoerg   case CK_None:
39806f32e7eSjoerg     break;
39906f32e7eSjoerg   case CK_i386:
40006f32e7eSjoerg     // The rest are coming from the i386 define above.
40106f32e7eSjoerg     Builder.defineMacro("__tune_i386__");
40206f32e7eSjoerg     break;
40306f32e7eSjoerg   case CK_i486:
40406f32e7eSjoerg   case CK_WinChipC6:
40506f32e7eSjoerg   case CK_WinChip2:
40606f32e7eSjoerg   case CK_C3:
40706f32e7eSjoerg     defineCPUMacros(Builder, "i486");
40806f32e7eSjoerg     break;
40906f32e7eSjoerg   case CK_PentiumMMX:
41006f32e7eSjoerg     Builder.defineMacro("__pentium_mmx__");
41106f32e7eSjoerg     Builder.defineMacro("__tune_pentium_mmx__");
41206f32e7eSjoerg     LLVM_FALLTHROUGH;
41306f32e7eSjoerg   case CK_i586:
41406f32e7eSjoerg   case CK_Pentium:
41506f32e7eSjoerg     defineCPUMacros(Builder, "i586");
41606f32e7eSjoerg     defineCPUMacros(Builder, "pentium");
41706f32e7eSjoerg     break;
41806f32e7eSjoerg   case CK_Pentium3:
41906f32e7eSjoerg   case CK_PentiumM:
42006f32e7eSjoerg     Builder.defineMacro("__tune_pentium3__");
42106f32e7eSjoerg     LLVM_FALLTHROUGH;
42206f32e7eSjoerg   case CK_Pentium2:
42306f32e7eSjoerg   case CK_C3_2:
42406f32e7eSjoerg     Builder.defineMacro("__tune_pentium2__");
42506f32e7eSjoerg     LLVM_FALLTHROUGH;
42606f32e7eSjoerg   case CK_PentiumPro:
42706f32e7eSjoerg   case CK_i686:
42806f32e7eSjoerg     defineCPUMacros(Builder, "i686");
42906f32e7eSjoerg     defineCPUMacros(Builder, "pentiumpro");
43006f32e7eSjoerg     break;
43106f32e7eSjoerg   case CK_Pentium4:
43206f32e7eSjoerg     defineCPUMacros(Builder, "pentium4");
43306f32e7eSjoerg     break;
43406f32e7eSjoerg   case CK_Yonah:
43506f32e7eSjoerg   case CK_Prescott:
43606f32e7eSjoerg   case CK_Nocona:
43706f32e7eSjoerg     defineCPUMacros(Builder, "nocona");
43806f32e7eSjoerg     break;
43906f32e7eSjoerg   case CK_Core2:
44006f32e7eSjoerg   case CK_Penryn:
44106f32e7eSjoerg     defineCPUMacros(Builder, "core2");
44206f32e7eSjoerg     break;
44306f32e7eSjoerg   case CK_Bonnell:
44406f32e7eSjoerg     defineCPUMacros(Builder, "atom");
44506f32e7eSjoerg     break;
44606f32e7eSjoerg   case CK_Silvermont:
44706f32e7eSjoerg     defineCPUMacros(Builder, "slm");
44806f32e7eSjoerg     break;
44906f32e7eSjoerg   case CK_Goldmont:
45006f32e7eSjoerg     defineCPUMacros(Builder, "goldmont");
45106f32e7eSjoerg     break;
45206f32e7eSjoerg   case CK_GoldmontPlus:
45306f32e7eSjoerg     defineCPUMacros(Builder, "goldmont_plus");
45406f32e7eSjoerg     break;
45506f32e7eSjoerg   case CK_Tremont:
45606f32e7eSjoerg     defineCPUMacros(Builder, "tremont");
45706f32e7eSjoerg     break;
45806f32e7eSjoerg   case CK_Nehalem:
45906f32e7eSjoerg   case CK_Westmere:
46006f32e7eSjoerg   case CK_SandyBridge:
46106f32e7eSjoerg   case CK_IvyBridge:
46206f32e7eSjoerg   case CK_Haswell:
46306f32e7eSjoerg   case CK_Broadwell:
46406f32e7eSjoerg   case CK_SkylakeClient:
46506f32e7eSjoerg   case CK_SkylakeServer:
46606f32e7eSjoerg   case CK_Cascadelake:
46706f32e7eSjoerg   case CK_Cooperlake:
46806f32e7eSjoerg   case CK_Cannonlake:
46906f32e7eSjoerg   case CK_IcelakeClient:
470*13fbcb42Sjoerg   case CK_Rocketlake:
47106f32e7eSjoerg   case CK_IcelakeServer:
47206f32e7eSjoerg   case CK_Tigerlake:
473*13fbcb42Sjoerg   case CK_SapphireRapids:
474*13fbcb42Sjoerg   case CK_Alderlake:
47506f32e7eSjoerg     // FIXME: Historically, we defined this legacy name, it would be nice to
47606f32e7eSjoerg     // remove it at some point. We've never exposed fine-grained names for
47706f32e7eSjoerg     // recent primary x86 CPUs, and we should keep it that way.
47806f32e7eSjoerg     defineCPUMacros(Builder, "corei7");
47906f32e7eSjoerg     break;
48006f32e7eSjoerg   case CK_KNL:
48106f32e7eSjoerg     defineCPUMacros(Builder, "knl");
48206f32e7eSjoerg     break;
48306f32e7eSjoerg   case CK_KNM:
48406f32e7eSjoerg     break;
48506f32e7eSjoerg   case CK_Lakemont:
48606f32e7eSjoerg     defineCPUMacros(Builder, "i586", /*Tuning*/false);
48706f32e7eSjoerg     defineCPUMacros(Builder, "pentium", /*Tuning*/false);
48806f32e7eSjoerg     Builder.defineMacro("__tune_lakemont__");
48906f32e7eSjoerg     break;
49006f32e7eSjoerg   case CK_K6_2:
49106f32e7eSjoerg     Builder.defineMacro("__k6_2__");
49206f32e7eSjoerg     Builder.defineMacro("__tune_k6_2__");
49306f32e7eSjoerg     LLVM_FALLTHROUGH;
49406f32e7eSjoerg   case CK_K6_3:
49506f32e7eSjoerg     if (CPU != CK_K6_2) { // In case of fallthrough
49606f32e7eSjoerg       // FIXME: GCC may be enabling these in cases where some other k6
49706f32e7eSjoerg       // architecture is specified but -m3dnow is explicitly provided. The
49806f32e7eSjoerg       // exact semantics need to be determined and emulated here.
49906f32e7eSjoerg       Builder.defineMacro("__k6_3__");
50006f32e7eSjoerg       Builder.defineMacro("__tune_k6_3__");
50106f32e7eSjoerg     }
50206f32e7eSjoerg     LLVM_FALLTHROUGH;
50306f32e7eSjoerg   case CK_K6:
50406f32e7eSjoerg     defineCPUMacros(Builder, "k6");
50506f32e7eSjoerg     break;
50606f32e7eSjoerg   case CK_Athlon:
50706f32e7eSjoerg   case CK_AthlonXP:
50806f32e7eSjoerg     defineCPUMacros(Builder, "athlon");
50906f32e7eSjoerg     if (SSELevel != NoSSE) {
51006f32e7eSjoerg       Builder.defineMacro("__athlon_sse__");
51106f32e7eSjoerg       Builder.defineMacro("__tune_athlon_sse__");
51206f32e7eSjoerg     }
51306f32e7eSjoerg     break;
51406f32e7eSjoerg   case CK_K8:
51506f32e7eSjoerg   case CK_K8SSE3:
51606f32e7eSjoerg   case CK_x86_64:
517*13fbcb42Sjoerg   case CK_x86_64_v2:
518*13fbcb42Sjoerg   case CK_x86_64_v3:
519*13fbcb42Sjoerg   case CK_x86_64_v4:
52006f32e7eSjoerg     defineCPUMacros(Builder, "k8");
52106f32e7eSjoerg     break;
52206f32e7eSjoerg   case CK_AMDFAM10:
52306f32e7eSjoerg     defineCPUMacros(Builder, "amdfam10");
52406f32e7eSjoerg     break;
52506f32e7eSjoerg   case CK_BTVER1:
52606f32e7eSjoerg     defineCPUMacros(Builder, "btver1");
52706f32e7eSjoerg     break;
52806f32e7eSjoerg   case CK_BTVER2:
52906f32e7eSjoerg     defineCPUMacros(Builder, "btver2");
53006f32e7eSjoerg     break;
53106f32e7eSjoerg   case CK_BDVER1:
53206f32e7eSjoerg     defineCPUMacros(Builder, "bdver1");
53306f32e7eSjoerg     break;
53406f32e7eSjoerg   case CK_BDVER2:
53506f32e7eSjoerg     defineCPUMacros(Builder, "bdver2");
53606f32e7eSjoerg     break;
53706f32e7eSjoerg   case CK_BDVER3:
53806f32e7eSjoerg     defineCPUMacros(Builder, "bdver3");
53906f32e7eSjoerg     break;
54006f32e7eSjoerg   case CK_BDVER4:
54106f32e7eSjoerg     defineCPUMacros(Builder, "bdver4");
54206f32e7eSjoerg     break;
54306f32e7eSjoerg   case CK_ZNVER1:
54406f32e7eSjoerg     defineCPUMacros(Builder, "znver1");
54506f32e7eSjoerg     break;
54606f32e7eSjoerg   case CK_ZNVER2:
54706f32e7eSjoerg     defineCPUMacros(Builder, "znver2");
54806f32e7eSjoerg     break;
549*13fbcb42Sjoerg   case CK_ZNVER3:
550*13fbcb42Sjoerg     defineCPUMacros(Builder, "znver3");
551*13fbcb42Sjoerg     break;
55206f32e7eSjoerg   case CK_Geode:
55306f32e7eSjoerg     defineCPUMacros(Builder, "geode");
55406f32e7eSjoerg     break;
55506f32e7eSjoerg   }
55606f32e7eSjoerg 
55706f32e7eSjoerg   // Target properties.
55806f32e7eSjoerg   Builder.defineMacro("__REGISTER_PREFIX__", "");
55906f32e7eSjoerg 
56006f32e7eSjoerg   // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
56106f32e7eSjoerg   // functions in glibc header files that use FP Stack inline asm which the
56206f32e7eSjoerg   // backend can't deal with (PR879).
56306f32e7eSjoerg   Builder.defineMacro("__NO_MATH_INLINES");
56406f32e7eSjoerg 
56506f32e7eSjoerg   if (HasAES)
56606f32e7eSjoerg     Builder.defineMacro("__AES__");
56706f32e7eSjoerg 
56806f32e7eSjoerg   if (HasVAES)
56906f32e7eSjoerg     Builder.defineMacro("__VAES__");
57006f32e7eSjoerg 
57106f32e7eSjoerg   if (HasPCLMUL)
57206f32e7eSjoerg     Builder.defineMacro("__PCLMUL__");
57306f32e7eSjoerg 
57406f32e7eSjoerg   if (HasVPCLMULQDQ)
57506f32e7eSjoerg     Builder.defineMacro("__VPCLMULQDQ__");
57606f32e7eSjoerg 
577*13fbcb42Sjoerg   // Note, in 32-bit mode, GCC does not define the macro if -mno-sahf. In LLVM,
578*13fbcb42Sjoerg   // the feature flag only applies to 64-bit mode.
579*13fbcb42Sjoerg   if (HasLAHFSAHF || getTriple().getArch() == llvm::Triple::x86)
580*13fbcb42Sjoerg     Builder.defineMacro("__LAHF_SAHF__");
581*13fbcb42Sjoerg 
58206f32e7eSjoerg   if (HasLZCNT)
58306f32e7eSjoerg     Builder.defineMacro("__LZCNT__");
58406f32e7eSjoerg 
58506f32e7eSjoerg   if (HasRDRND)
58606f32e7eSjoerg     Builder.defineMacro("__RDRND__");
58706f32e7eSjoerg 
58806f32e7eSjoerg   if (HasFSGSBASE)
58906f32e7eSjoerg     Builder.defineMacro("__FSGSBASE__");
59006f32e7eSjoerg 
59106f32e7eSjoerg   if (HasBMI)
59206f32e7eSjoerg     Builder.defineMacro("__BMI__");
59306f32e7eSjoerg 
59406f32e7eSjoerg   if (HasBMI2)
59506f32e7eSjoerg     Builder.defineMacro("__BMI2__");
59606f32e7eSjoerg 
59706f32e7eSjoerg   if (HasPOPCNT)
59806f32e7eSjoerg     Builder.defineMacro("__POPCNT__");
59906f32e7eSjoerg 
60006f32e7eSjoerg   if (HasRTM)
60106f32e7eSjoerg     Builder.defineMacro("__RTM__");
60206f32e7eSjoerg 
60306f32e7eSjoerg   if (HasPRFCHW)
60406f32e7eSjoerg     Builder.defineMacro("__PRFCHW__");
60506f32e7eSjoerg 
60606f32e7eSjoerg   if (HasRDSEED)
60706f32e7eSjoerg     Builder.defineMacro("__RDSEED__");
60806f32e7eSjoerg 
60906f32e7eSjoerg   if (HasADX)
61006f32e7eSjoerg     Builder.defineMacro("__ADX__");
61106f32e7eSjoerg 
61206f32e7eSjoerg   if (HasTBM)
61306f32e7eSjoerg     Builder.defineMacro("__TBM__");
61406f32e7eSjoerg 
61506f32e7eSjoerg   if (HasLWP)
61606f32e7eSjoerg     Builder.defineMacro("__LWP__");
61706f32e7eSjoerg 
61806f32e7eSjoerg   if (HasMWAITX)
61906f32e7eSjoerg     Builder.defineMacro("__MWAITX__");
62006f32e7eSjoerg 
62106f32e7eSjoerg   if (HasMOVBE)
62206f32e7eSjoerg     Builder.defineMacro("__MOVBE__");
62306f32e7eSjoerg 
62406f32e7eSjoerg   switch (XOPLevel) {
62506f32e7eSjoerg   case XOP:
62606f32e7eSjoerg     Builder.defineMacro("__XOP__");
62706f32e7eSjoerg     LLVM_FALLTHROUGH;
62806f32e7eSjoerg   case FMA4:
62906f32e7eSjoerg     Builder.defineMacro("__FMA4__");
63006f32e7eSjoerg     LLVM_FALLTHROUGH;
63106f32e7eSjoerg   case SSE4A:
63206f32e7eSjoerg     Builder.defineMacro("__SSE4A__");
63306f32e7eSjoerg     LLVM_FALLTHROUGH;
63406f32e7eSjoerg   case NoXOP:
63506f32e7eSjoerg     break;
63606f32e7eSjoerg   }
63706f32e7eSjoerg 
63806f32e7eSjoerg   if (HasFMA)
63906f32e7eSjoerg     Builder.defineMacro("__FMA__");
64006f32e7eSjoerg 
64106f32e7eSjoerg   if (HasF16C)
64206f32e7eSjoerg     Builder.defineMacro("__F16C__");
64306f32e7eSjoerg 
64406f32e7eSjoerg   if (HasGFNI)
64506f32e7eSjoerg     Builder.defineMacro("__GFNI__");
64606f32e7eSjoerg 
64706f32e7eSjoerg   if (HasAVX512CD)
64806f32e7eSjoerg     Builder.defineMacro("__AVX512CD__");
64906f32e7eSjoerg   if (HasAVX512VPOPCNTDQ)
65006f32e7eSjoerg     Builder.defineMacro("__AVX512VPOPCNTDQ__");
65106f32e7eSjoerg   if (HasAVX512VNNI)
65206f32e7eSjoerg     Builder.defineMacro("__AVX512VNNI__");
65306f32e7eSjoerg   if (HasAVX512BF16)
65406f32e7eSjoerg     Builder.defineMacro("__AVX512BF16__");
65506f32e7eSjoerg   if (HasAVX512ER)
65606f32e7eSjoerg     Builder.defineMacro("__AVX512ER__");
65706f32e7eSjoerg   if (HasAVX512PF)
65806f32e7eSjoerg     Builder.defineMacro("__AVX512PF__");
65906f32e7eSjoerg   if (HasAVX512DQ)
66006f32e7eSjoerg     Builder.defineMacro("__AVX512DQ__");
66106f32e7eSjoerg   if (HasAVX512BITALG)
66206f32e7eSjoerg     Builder.defineMacro("__AVX512BITALG__");
66306f32e7eSjoerg   if (HasAVX512BW)
66406f32e7eSjoerg     Builder.defineMacro("__AVX512BW__");
66506f32e7eSjoerg   if (HasAVX512VL)
66606f32e7eSjoerg     Builder.defineMacro("__AVX512VL__");
66706f32e7eSjoerg   if (HasAVX512VBMI)
66806f32e7eSjoerg     Builder.defineMacro("__AVX512VBMI__");
66906f32e7eSjoerg   if (HasAVX512VBMI2)
67006f32e7eSjoerg     Builder.defineMacro("__AVX512VBMI2__");
67106f32e7eSjoerg   if (HasAVX512IFMA)
67206f32e7eSjoerg     Builder.defineMacro("__AVX512IFMA__");
67306f32e7eSjoerg   if (HasAVX512VP2INTERSECT)
67406f32e7eSjoerg     Builder.defineMacro("__AVX512VP2INTERSECT__");
67506f32e7eSjoerg   if (HasSHA)
67606f32e7eSjoerg     Builder.defineMacro("__SHA__");
67706f32e7eSjoerg 
67806f32e7eSjoerg   if (HasFXSR)
67906f32e7eSjoerg     Builder.defineMacro("__FXSR__");
68006f32e7eSjoerg   if (HasXSAVE)
68106f32e7eSjoerg     Builder.defineMacro("__XSAVE__");
68206f32e7eSjoerg   if (HasXSAVEOPT)
68306f32e7eSjoerg     Builder.defineMacro("__XSAVEOPT__");
68406f32e7eSjoerg   if (HasXSAVEC)
68506f32e7eSjoerg     Builder.defineMacro("__XSAVEC__");
68606f32e7eSjoerg   if (HasXSAVES)
68706f32e7eSjoerg     Builder.defineMacro("__XSAVES__");
68806f32e7eSjoerg   if (HasPKU)
68906f32e7eSjoerg     Builder.defineMacro("__PKU__");
69006f32e7eSjoerg   if (HasCLFLUSHOPT)
69106f32e7eSjoerg     Builder.defineMacro("__CLFLUSHOPT__");
69206f32e7eSjoerg   if (HasCLWB)
69306f32e7eSjoerg     Builder.defineMacro("__CLWB__");
69406f32e7eSjoerg   if (HasWBNOINVD)
69506f32e7eSjoerg     Builder.defineMacro("__WBNOINVD__");
69606f32e7eSjoerg   if (HasSHSTK)
69706f32e7eSjoerg     Builder.defineMacro("__SHSTK__");
69806f32e7eSjoerg   if (HasSGX)
69906f32e7eSjoerg     Builder.defineMacro("__SGX__");
70006f32e7eSjoerg   if (HasPREFETCHWT1)
70106f32e7eSjoerg     Builder.defineMacro("__PREFETCHWT1__");
70206f32e7eSjoerg   if (HasCLZERO)
70306f32e7eSjoerg     Builder.defineMacro("__CLZERO__");
704*13fbcb42Sjoerg   if (HasKL)
705*13fbcb42Sjoerg     Builder.defineMacro("__KL__");
706*13fbcb42Sjoerg   if (HasWIDEKL)
707*13fbcb42Sjoerg     Builder.defineMacro("__WIDEKL__");
70806f32e7eSjoerg   if (HasRDPID)
70906f32e7eSjoerg     Builder.defineMacro("__RDPID__");
71006f32e7eSjoerg   if (HasCLDEMOTE)
71106f32e7eSjoerg     Builder.defineMacro("__CLDEMOTE__");
71206f32e7eSjoerg   if (HasWAITPKG)
71306f32e7eSjoerg     Builder.defineMacro("__WAITPKG__");
71406f32e7eSjoerg   if (HasMOVDIRI)
71506f32e7eSjoerg     Builder.defineMacro("__MOVDIRI__");
71606f32e7eSjoerg   if (HasMOVDIR64B)
71706f32e7eSjoerg     Builder.defineMacro("__MOVDIR64B__");
71806f32e7eSjoerg   if (HasPCONFIG)
71906f32e7eSjoerg     Builder.defineMacro("__PCONFIG__");
72006f32e7eSjoerg   if (HasPTWRITE)
72106f32e7eSjoerg     Builder.defineMacro("__PTWRITE__");
72206f32e7eSjoerg   if (HasINVPCID)
72306f32e7eSjoerg     Builder.defineMacro("__INVPCID__");
72406f32e7eSjoerg   if (HasENQCMD)
72506f32e7eSjoerg     Builder.defineMacro("__ENQCMD__");
726*13fbcb42Sjoerg   if (HasHRESET)
727*13fbcb42Sjoerg     Builder.defineMacro("__HRESET__");
728*13fbcb42Sjoerg   if (HasAMXTILE)
729*13fbcb42Sjoerg     Builder.defineMacro("__AMXTILE__");
730*13fbcb42Sjoerg   if (HasAMXINT8)
731*13fbcb42Sjoerg     Builder.defineMacro("__AMXINT8__");
732*13fbcb42Sjoerg   if (HasAMXBF16)
733*13fbcb42Sjoerg     Builder.defineMacro("__AMXBF16__");
734*13fbcb42Sjoerg   if (HasAVXVNNI)
735*13fbcb42Sjoerg     Builder.defineMacro("__AVXVNNI__");
736*13fbcb42Sjoerg   if (HasSERIALIZE)
737*13fbcb42Sjoerg     Builder.defineMacro("__SERIALIZE__");
738*13fbcb42Sjoerg   if (HasTSXLDTRK)
739*13fbcb42Sjoerg     Builder.defineMacro("__TSXLDTRK__");
740*13fbcb42Sjoerg   if (HasUINTR)
741*13fbcb42Sjoerg     Builder.defineMacro("__UINTR__");
74206f32e7eSjoerg 
74306f32e7eSjoerg   // Each case falls through to the previous one here.
74406f32e7eSjoerg   switch (SSELevel) {
74506f32e7eSjoerg   case AVX512F:
74606f32e7eSjoerg     Builder.defineMacro("__AVX512F__");
74706f32e7eSjoerg     LLVM_FALLTHROUGH;
74806f32e7eSjoerg   case AVX2:
74906f32e7eSjoerg     Builder.defineMacro("__AVX2__");
75006f32e7eSjoerg     LLVM_FALLTHROUGH;
75106f32e7eSjoerg   case AVX:
75206f32e7eSjoerg     Builder.defineMacro("__AVX__");
75306f32e7eSjoerg     LLVM_FALLTHROUGH;
75406f32e7eSjoerg   case SSE42:
75506f32e7eSjoerg     Builder.defineMacro("__SSE4_2__");
75606f32e7eSjoerg     LLVM_FALLTHROUGH;
75706f32e7eSjoerg   case SSE41:
75806f32e7eSjoerg     Builder.defineMacro("__SSE4_1__");
75906f32e7eSjoerg     LLVM_FALLTHROUGH;
76006f32e7eSjoerg   case SSSE3:
76106f32e7eSjoerg     Builder.defineMacro("__SSSE3__");
76206f32e7eSjoerg     LLVM_FALLTHROUGH;
76306f32e7eSjoerg   case SSE3:
76406f32e7eSjoerg     Builder.defineMacro("__SSE3__");
76506f32e7eSjoerg     LLVM_FALLTHROUGH;
76606f32e7eSjoerg   case SSE2:
76706f32e7eSjoerg     Builder.defineMacro("__SSE2__");
76806f32e7eSjoerg     Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
76906f32e7eSjoerg     LLVM_FALLTHROUGH;
77006f32e7eSjoerg   case SSE1:
77106f32e7eSjoerg     Builder.defineMacro("__SSE__");
77206f32e7eSjoerg     Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
77306f32e7eSjoerg     LLVM_FALLTHROUGH;
77406f32e7eSjoerg   case NoSSE:
77506f32e7eSjoerg     break;
77606f32e7eSjoerg   }
77706f32e7eSjoerg 
77806f32e7eSjoerg   if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
77906f32e7eSjoerg     switch (SSELevel) {
78006f32e7eSjoerg     case AVX512F:
78106f32e7eSjoerg     case AVX2:
78206f32e7eSjoerg     case AVX:
78306f32e7eSjoerg     case SSE42:
78406f32e7eSjoerg     case SSE41:
78506f32e7eSjoerg     case SSSE3:
78606f32e7eSjoerg     case SSE3:
78706f32e7eSjoerg     case SSE2:
78806f32e7eSjoerg       Builder.defineMacro("_M_IX86_FP", Twine(2));
78906f32e7eSjoerg       break;
79006f32e7eSjoerg     case SSE1:
79106f32e7eSjoerg       Builder.defineMacro("_M_IX86_FP", Twine(1));
79206f32e7eSjoerg       break;
79306f32e7eSjoerg     default:
79406f32e7eSjoerg       Builder.defineMacro("_M_IX86_FP", Twine(0));
79506f32e7eSjoerg       break;
79606f32e7eSjoerg     }
79706f32e7eSjoerg   }
79806f32e7eSjoerg 
79906f32e7eSjoerg   // Each case falls through to the previous one here.
80006f32e7eSjoerg   switch (MMX3DNowLevel) {
80106f32e7eSjoerg   case AMD3DNowAthlon:
80206f32e7eSjoerg     Builder.defineMacro("__3dNOW_A__");
80306f32e7eSjoerg     LLVM_FALLTHROUGH;
80406f32e7eSjoerg   case AMD3DNow:
80506f32e7eSjoerg     Builder.defineMacro("__3dNOW__");
80606f32e7eSjoerg     LLVM_FALLTHROUGH;
80706f32e7eSjoerg   case MMX:
80806f32e7eSjoerg     Builder.defineMacro("__MMX__");
80906f32e7eSjoerg     LLVM_FALLTHROUGH;
81006f32e7eSjoerg   case NoMMX3DNow:
81106f32e7eSjoerg     break;
81206f32e7eSjoerg   }
81306f32e7eSjoerg 
814*13fbcb42Sjoerg   if (CPU >= CK_i486 || CPU == CK_None) {
81506f32e7eSjoerg     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
81606f32e7eSjoerg     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
81706f32e7eSjoerg     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
81806f32e7eSjoerg   }
81906f32e7eSjoerg   if (HasCX8)
82006f32e7eSjoerg     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
82106f32e7eSjoerg   if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)
82206f32e7eSjoerg     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
82306f32e7eSjoerg 
82406f32e7eSjoerg   if (HasFloat128)
82506f32e7eSjoerg     Builder.defineMacro("__SIZEOF_FLOAT128__", "16");
82606f32e7eSjoerg }
82706f32e7eSjoerg 
isValidFeatureName(StringRef Name) const82806f32e7eSjoerg bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
82906f32e7eSjoerg   return llvm::StringSwitch<bool>(Name)
83006f32e7eSjoerg       .Case("3dnow", true)
83106f32e7eSjoerg       .Case("3dnowa", true)
83206f32e7eSjoerg       .Case("adx", true)
83306f32e7eSjoerg       .Case("aes", true)
834*13fbcb42Sjoerg       .Case("amx-bf16", true)
835*13fbcb42Sjoerg       .Case("amx-int8", true)
836*13fbcb42Sjoerg       .Case("amx-tile", true)
83706f32e7eSjoerg       .Case("avx", true)
83806f32e7eSjoerg       .Case("avx2", true)
83906f32e7eSjoerg       .Case("avx512f", true)
84006f32e7eSjoerg       .Case("avx512cd", true)
84106f32e7eSjoerg       .Case("avx512vpopcntdq", true)
84206f32e7eSjoerg       .Case("avx512vnni", true)
84306f32e7eSjoerg       .Case("avx512bf16", true)
84406f32e7eSjoerg       .Case("avx512er", true)
84506f32e7eSjoerg       .Case("avx512pf", true)
84606f32e7eSjoerg       .Case("avx512dq", true)
84706f32e7eSjoerg       .Case("avx512bitalg", true)
84806f32e7eSjoerg       .Case("avx512bw", true)
84906f32e7eSjoerg       .Case("avx512vl", true)
85006f32e7eSjoerg       .Case("avx512vbmi", true)
85106f32e7eSjoerg       .Case("avx512vbmi2", true)
85206f32e7eSjoerg       .Case("avx512ifma", true)
85306f32e7eSjoerg       .Case("avx512vp2intersect", true)
854*13fbcb42Sjoerg       .Case("avxvnni", true)
85506f32e7eSjoerg       .Case("bmi", true)
85606f32e7eSjoerg       .Case("bmi2", true)
85706f32e7eSjoerg       .Case("cldemote", true)
85806f32e7eSjoerg       .Case("clflushopt", true)
85906f32e7eSjoerg       .Case("clwb", true)
86006f32e7eSjoerg       .Case("clzero", true)
86106f32e7eSjoerg       .Case("cx16", true)
86206f32e7eSjoerg       .Case("enqcmd", true)
86306f32e7eSjoerg       .Case("f16c", true)
86406f32e7eSjoerg       .Case("fma", true)
86506f32e7eSjoerg       .Case("fma4", true)
86606f32e7eSjoerg       .Case("fsgsbase", true)
86706f32e7eSjoerg       .Case("fxsr", true)
86806f32e7eSjoerg       .Case("gfni", true)
869*13fbcb42Sjoerg       .Case("hreset", true)
87006f32e7eSjoerg       .Case("invpcid", true)
871*13fbcb42Sjoerg       .Case("kl", true)
872*13fbcb42Sjoerg       .Case("widekl", true)
87306f32e7eSjoerg       .Case("lwp", true)
87406f32e7eSjoerg       .Case("lzcnt", true)
87506f32e7eSjoerg       .Case("mmx", true)
87606f32e7eSjoerg       .Case("movbe", true)
87706f32e7eSjoerg       .Case("movdiri", true)
87806f32e7eSjoerg       .Case("movdir64b", true)
87906f32e7eSjoerg       .Case("mwaitx", true)
88006f32e7eSjoerg       .Case("pclmul", true)
88106f32e7eSjoerg       .Case("pconfig", true)
88206f32e7eSjoerg       .Case("pku", true)
88306f32e7eSjoerg       .Case("popcnt", true)
88406f32e7eSjoerg       .Case("prefetchwt1", true)
88506f32e7eSjoerg       .Case("prfchw", true)
88606f32e7eSjoerg       .Case("ptwrite", true)
88706f32e7eSjoerg       .Case("rdpid", true)
88806f32e7eSjoerg       .Case("rdrnd", true)
88906f32e7eSjoerg       .Case("rdseed", true)
89006f32e7eSjoerg       .Case("rtm", true)
89106f32e7eSjoerg       .Case("sahf", true)
892*13fbcb42Sjoerg       .Case("serialize", true)
89306f32e7eSjoerg       .Case("sgx", true)
89406f32e7eSjoerg       .Case("sha", true)
89506f32e7eSjoerg       .Case("shstk", true)
89606f32e7eSjoerg       .Case("sse", true)
89706f32e7eSjoerg       .Case("sse2", true)
89806f32e7eSjoerg       .Case("sse3", true)
89906f32e7eSjoerg       .Case("ssse3", true)
90006f32e7eSjoerg       .Case("sse4", true)
90106f32e7eSjoerg       .Case("sse4.1", true)
90206f32e7eSjoerg       .Case("sse4.2", true)
90306f32e7eSjoerg       .Case("sse4a", true)
90406f32e7eSjoerg       .Case("tbm", true)
905*13fbcb42Sjoerg       .Case("tsxldtrk", true)
906*13fbcb42Sjoerg       .Case("uintr", true)
90706f32e7eSjoerg       .Case("vaes", true)
90806f32e7eSjoerg       .Case("vpclmulqdq", true)
90906f32e7eSjoerg       .Case("wbnoinvd", true)
91006f32e7eSjoerg       .Case("waitpkg", true)
91106f32e7eSjoerg       .Case("x87", true)
91206f32e7eSjoerg       .Case("xop", true)
91306f32e7eSjoerg       .Case("xsave", true)
91406f32e7eSjoerg       .Case("xsavec", true)
91506f32e7eSjoerg       .Case("xsaves", true)
91606f32e7eSjoerg       .Case("xsaveopt", true)
91706f32e7eSjoerg       .Default(false);
91806f32e7eSjoerg }
91906f32e7eSjoerg 
hasFeature(StringRef Feature) const92006f32e7eSjoerg bool X86TargetInfo::hasFeature(StringRef Feature) const {
92106f32e7eSjoerg   return llvm::StringSwitch<bool>(Feature)
92206f32e7eSjoerg       .Case("adx", HasADX)
92306f32e7eSjoerg       .Case("aes", HasAES)
924*13fbcb42Sjoerg       .Case("amx-bf16", HasAMXBF16)
925*13fbcb42Sjoerg       .Case("amx-int8", HasAMXINT8)
926*13fbcb42Sjoerg       .Case("amx-tile", HasAMXTILE)
927*13fbcb42Sjoerg       .Case("avxvnni", HasAVXVNNI)
92806f32e7eSjoerg       .Case("avx", SSELevel >= AVX)
92906f32e7eSjoerg       .Case("avx2", SSELevel >= AVX2)
93006f32e7eSjoerg       .Case("avx512f", SSELevel >= AVX512F)
93106f32e7eSjoerg       .Case("avx512cd", HasAVX512CD)
93206f32e7eSjoerg       .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ)
93306f32e7eSjoerg       .Case("avx512vnni", HasAVX512VNNI)
93406f32e7eSjoerg       .Case("avx512bf16", HasAVX512BF16)
93506f32e7eSjoerg       .Case("avx512er", HasAVX512ER)
93606f32e7eSjoerg       .Case("avx512pf", HasAVX512PF)
93706f32e7eSjoerg       .Case("avx512dq", HasAVX512DQ)
93806f32e7eSjoerg       .Case("avx512bitalg", HasAVX512BITALG)
93906f32e7eSjoerg       .Case("avx512bw", HasAVX512BW)
94006f32e7eSjoerg       .Case("avx512vl", HasAVX512VL)
94106f32e7eSjoerg       .Case("avx512vbmi", HasAVX512VBMI)
94206f32e7eSjoerg       .Case("avx512vbmi2", HasAVX512VBMI2)
94306f32e7eSjoerg       .Case("avx512ifma", HasAVX512IFMA)
94406f32e7eSjoerg       .Case("avx512vp2intersect", HasAVX512VP2INTERSECT)
94506f32e7eSjoerg       .Case("bmi", HasBMI)
94606f32e7eSjoerg       .Case("bmi2", HasBMI2)
94706f32e7eSjoerg       .Case("cldemote", HasCLDEMOTE)
94806f32e7eSjoerg       .Case("clflushopt", HasCLFLUSHOPT)
94906f32e7eSjoerg       .Case("clwb", HasCLWB)
95006f32e7eSjoerg       .Case("clzero", HasCLZERO)
95106f32e7eSjoerg       .Case("cx8", HasCX8)
95206f32e7eSjoerg       .Case("cx16", HasCX16)
95306f32e7eSjoerg       .Case("enqcmd", HasENQCMD)
95406f32e7eSjoerg       .Case("f16c", HasF16C)
95506f32e7eSjoerg       .Case("fma", HasFMA)
95606f32e7eSjoerg       .Case("fma4", XOPLevel >= FMA4)
95706f32e7eSjoerg       .Case("fsgsbase", HasFSGSBASE)
95806f32e7eSjoerg       .Case("fxsr", HasFXSR)
95906f32e7eSjoerg       .Case("gfni", HasGFNI)
960*13fbcb42Sjoerg       .Case("hreset", HasHRESET)
96106f32e7eSjoerg       .Case("invpcid", HasINVPCID)
962*13fbcb42Sjoerg       .Case("kl", HasKL)
963*13fbcb42Sjoerg       .Case("widekl", HasWIDEKL)
96406f32e7eSjoerg       .Case("lwp", HasLWP)
96506f32e7eSjoerg       .Case("lzcnt", HasLZCNT)
96606f32e7eSjoerg       .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
96706f32e7eSjoerg       .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
96806f32e7eSjoerg       .Case("mmx", MMX3DNowLevel >= MMX)
96906f32e7eSjoerg       .Case("movbe", HasMOVBE)
97006f32e7eSjoerg       .Case("movdiri", HasMOVDIRI)
97106f32e7eSjoerg       .Case("movdir64b", HasMOVDIR64B)
97206f32e7eSjoerg       .Case("mwaitx", HasMWAITX)
97306f32e7eSjoerg       .Case("pclmul", HasPCLMUL)
97406f32e7eSjoerg       .Case("pconfig", HasPCONFIG)
97506f32e7eSjoerg       .Case("pku", HasPKU)
97606f32e7eSjoerg       .Case("popcnt", HasPOPCNT)
97706f32e7eSjoerg       .Case("prefetchwt1", HasPREFETCHWT1)
97806f32e7eSjoerg       .Case("prfchw", HasPRFCHW)
97906f32e7eSjoerg       .Case("ptwrite", HasPTWRITE)
98006f32e7eSjoerg       .Case("rdpid", HasRDPID)
98106f32e7eSjoerg       .Case("rdrnd", HasRDRND)
98206f32e7eSjoerg       .Case("rdseed", HasRDSEED)
98306f32e7eSjoerg       .Case("retpoline-external-thunk", HasRetpolineExternalThunk)
98406f32e7eSjoerg       .Case("rtm", HasRTM)
98506f32e7eSjoerg       .Case("sahf", HasLAHFSAHF)
986*13fbcb42Sjoerg       .Case("serialize", HasSERIALIZE)
98706f32e7eSjoerg       .Case("sgx", HasSGX)
98806f32e7eSjoerg       .Case("sha", HasSHA)
98906f32e7eSjoerg       .Case("shstk", HasSHSTK)
99006f32e7eSjoerg       .Case("sse", SSELevel >= SSE1)
99106f32e7eSjoerg       .Case("sse2", SSELevel >= SSE2)
99206f32e7eSjoerg       .Case("sse3", SSELevel >= SSE3)
99306f32e7eSjoerg       .Case("ssse3", SSELevel >= SSSE3)
99406f32e7eSjoerg       .Case("sse4.1", SSELevel >= SSE41)
99506f32e7eSjoerg       .Case("sse4.2", SSELevel >= SSE42)
99606f32e7eSjoerg       .Case("sse4a", XOPLevel >= SSE4A)
99706f32e7eSjoerg       .Case("tbm", HasTBM)
998*13fbcb42Sjoerg       .Case("tsxldtrk", HasTSXLDTRK)
999*13fbcb42Sjoerg       .Case("uintr", HasUINTR)
100006f32e7eSjoerg       .Case("vaes", HasVAES)
100106f32e7eSjoerg       .Case("vpclmulqdq", HasVPCLMULQDQ)
100206f32e7eSjoerg       .Case("wbnoinvd", HasWBNOINVD)
100306f32e7eSjoerg       .Case("waitpkg", HasWAITPKG)
100406f32e7eSjoerg       .Case("x86", true)
100506f32e7eSjoerg       .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
100606f32e7eSjoerg       .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
100706f32e7eSjoerg       .Case("xop", XOPLevel >= XOP)
100806f32e7eSjoerg       .Case("xsave", HasXSAVE)
100906f32e7eSjoerg       .Case("xsavec", HasXSAVEC)
101006f32e7eSjoerg       .Case("xsaves", HasXSAVES)
101106f32e7eSjoerg       .Case("xsaveopt", HasXSAVEOPT)
101206f32e7eSjoerg       .Default(false);
101306f32e7eSjoerg }
101406f32e7eSjoerg 
101506f32e7eSjoerg // We can't use a generic validation scheme for the features accepted here
101606f32e7eSjoerg // versus subtarget features accepted in the target attribute because the
101706f32e7eSjoerg // bitfield structure that's initialized in the runtime only supports the
101806f32e7eSjoerg // below currently rather than the full range of subtarget features. (See
101906f32e7eSjoerg // X86TargetInfo::hasFeature for a somewhat comprehensive list).
validateCpuSupports(StringRef FeatureStr) const102006f32e7eSjoerg bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
102106f32e7eSjoerg   return llvm::StringSwitch<bool>(FeatureStr)
1022*13fbcb42Sjoerg #define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, true)
102306f32e7eSjoerg #include "llvm/Support/X86TargetParser.def"
102406f32e7eSjoerg       .Default(false);
102506f32e7eSjoerg }
102606f32e7eSjoerg 
getFeature(StringRef Name)102706f32e7eSjoerg static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {
102806f32e7eSjoerg   return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)
1029*13fbcb42Sjoerg #define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM)
103006f32e7eSjoerg #include "llvm/Support/X86TargetParser.def"
103106f32e7eSjoerg       ;
103206f32e7eSjoerg   // Note, this function should only be used after ensuring the value is
103306f32e7eSjoerg   // correct, so it asserts if the value is out of range.
103406f32e7eSjoerg }
103506f32e7eSjoerg 
getFeaturePriority(llvm::X86::ProcessorFeatures Feat)103606f32e7eSjoerg static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) {
103706f32e7eSjoerg   enum class FeatPriority {
103806f32e7eSjoerg #define FEATURE(FEAT) FEAT,
103906f32e7eSjoerg #include "clang/Basic/X86Target.def"
104006f32e7eSjoerg   };
104106f32e7eSjoerg   switch (Feat) {
104206f32e7eSjoerg #define FEATURE(FEAT)                                                          \
104306f32e7eSjoerg   case llvm::X86::FEAT:                                                        \
104406f32e7eSjoerg     return static_cast<unsigned>(FeatPriority::FEAT);
104506f32e7eSjoerg #include "clang/Basic/X86Target.def"
104606f32e7eSjoerg   default:
104706f32e7eSjoerg     llvm_unreachable("No Feature Priority for non-CPUSupports Features");
104806f32e7eSjoerg   }
104906f32e7eSjoerg }
105006f32e7eSjoerg 
multiVersionSortPriority(StringRef Name) const105106f32e7eSjoerg unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
105206f32e7eSjoerg   // Valid CPUs have a 'key feature' that compares just better than its key
105306f32e7eSjoerg   // feature.
1054*13fbcb42Sjoerg   using namespace llvm::X86;
1055*13fbcb42Sjoerg   CPUKind Kind = parseArchX86(Name);
1056*13fbcb42Sjoerg   if (Kind != CK_None) {
1057*13fbcb42Sjoerg     ProcessorFeatures KeyFeature = getKeyFeature(Kind);
1058*13fbcb42Sjoerg     return (getFeaturePriority(KeyFeature) << 1) + 1;
105906f32e7eSjoerg   }
106006f32e7eSjoerg 
106106f32e7eSjoerg   // Now we know we have a feature, so get its priority and shift it a few so
106206f32e7eSjoerg   // that we have sufficient room for the CPUs (above).
106306f32e7eSjoerg   return getFeaturePriority(getFeature(Name)) << 1;
106406f32e7eSjoerg }
106506f32e7eSjoerg 
validateCPUSpecificCPUDispatch(StringRef Name) const106606f32e7eSjoerg bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const {
106706f32e7eSjoerg   return llvm::StringSwitch<bool>(Name)
106806f32e7eSjoerg #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true)
106906f32e7eSjoerg #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true)
107006f32e7eSjoerg #include "clang/Basic/X86Target.def"
107106f32e7eSjoerg       .Default(false);
107206f32e7eSjoerg }
107306f32e7eSjoerg 
CPUSpecificCPUDispatchNameDealias(StringRef Name)107406f32e7eSjoerg static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) {
107506f32e7eSjoerg   return llvm::StringSwitch<StringRef>(Name)
107606f32e7eSjoerg #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME)
107706f32e7eSjoerg #include "clang/Basic/X86Target.def"
107806f32e7eSjoerg       .Default(Name);
107906f32e7eSjoerg }
108006f32e7eSjoerg 
CPUSpecificManglingCharacter(StringRef Name) const108106f32e7eSjoerg char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const {
108206f32e7eSjoerg   return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name))
108306f32e7eSjoerg #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING)
108406f32e7eSjoerg #include "clang/Basic/X86Target.def"
108506f32e7eSjoerg       .Default(0);
108606f32e7eSjoerg }
108706f32e7eSjoerg 
getCPUSpecificCPUDispatchFeatures(StringRef Name,llvm::SmallVectorImpl<StringRef> & Features) const108806f32e7eSjoerg void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(
108906f32e7eSjoerg     StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
109006f32e7eSjoerg   StringRef WholeList =
109106f32e7eSjoerg       llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name))
109206f32e7eSjoerg #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES)
109306f32e7eSjoerg #include "clang/Basic/X86Target.def"
109406f32e7eSjoerg           .Default("");
109506f32e7eSjoerg   WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
109606f32e7eSjoerg }
109706f32e7eSjoerg 
109806f32e7eSjoerg // We can't use a generic validation scheme for the cpus accepted here
109906f32e7eSjoerg // versus subtarget cpus accepted in the target attribute because the
110006f32e7eSjoerg // variables intitialized by the runtime only support the below currently
110106f32e7eSjoerg // rather than the full range of cpus.
validateCpuIs(StringRef FeatureStr) const110206f32e7eSjoerg bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
110306f32e7eSjoerg   return llvm::StringSwitch<bool>(FeatureStr)
110406f32e7eSjoerg #define X86_VENDOR(ENUM, STRING) .Case(STRING, true)
1105*13fbcb42Sjoerg #define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
1106*13fbcb42Sjoerg #define X86_CPU_TYPE(ENUM, STR) .Case(STR, true)
1107*13fbcb42Sjoerg #define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true)
110806f32e7eSjoerg #include "llvm/Support/X86TargetParser.def"
110906f32e7eSjoerg       .Default(false);
111006f32e7eSjoerg }
111106f32e7eSjoerg 
matchAsmCCConstraint(const char * & Name)111206f32e7eSjoerg static unsigned matchAsmCCConstraint(const char *&Name) {
111306f32e7eSjoerg   auto RV = llvm::StringSwitch<unsigned>(Name)
111406f32e7eSjoerg                 .Case("@cca", 4)
111506f32e7eSjoerg                 .Case("@ccae", 5)
111606f32e7eSjoerg                 .Case("@ccb", 4)
111706f32e7eSjoerg                 .Case("@ccbe", 5)
111806f32e7eSjoerg                 .Case("@ccc", 4)
111906f32e7eSjoerg                 .Case("@cce", 4)
112006f32e7eSjoerg                 .Case("@ccz", 4)
112106f32e7eSjoerg                 .Case("@ccg", 4)
112206f32e7eSjoerg                 .Case("@ccge", 5)
112306f32e7eSjoerg                 .Case("@ccl", 4)
112406f32e7eSjoerg                 .Case("@ccle", 5)
112506f32e7eSjoerg                 .Case("@ccna", 5)
112606f32e7eSjoerg                 .Case("@ccnae", 6)
112706f32e7eSjoerg                 .Case("@ccnb", 5)
112806f32e7eSjoerg                 .Case("@ccnbe", 6)
112906f32e7eSjoerg                 .Case("@ccnc", 5)
113006f32e7eSjoerg                 .Case("@ccne", 5)
113106f32e7eSjoerg                 .Case("@ccnz", 5)
113206f32e7eSjoerg                 .Case("@ccng", 5)
113306f32e7eSjoerg                 .Case("@ccnge", 6)
113406f32e7eSjoerg                 .Case("@ccnl", 5)
113506f32e7eSjoerg                 .Case("@ccnle", 6)
113606f32e7eSjoerg                 .Case("@ccno", 5)
113706f32e7eSjoerg                 .Case("@ccnp", 5)
113806f32e7eSjoerg                 .Case("@ccns", 5)
113906f32e7eSjoerg                 .Case("@cco", 4)
114006f32e7eSjoerg                 .Case("@ccp", 4)
114106f32e7eSjoerg                 .Case("@ccs", 4)
114206f32e7eSjoerg                 .Default(0);
114306f32e7eSjoerg   return RV;
114406f32e7eSjoerg }
114506f32e7eSjoerg 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const114606f32e7eSjoerg bool X86TargetInfo::validateAsmConstraint(
114706f32e7eSjoerg     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
114806f32e7eSjoerg   switch (*Name) {
114906f32e7eSjoerg   default:
115006f32e7eSjoerg     return false;
115106f32e7eSjoerg   // Constant constraints.
115206f32e7eSjoerg   case 'e': // 32-bit signed integer constant for use with sign-extending x86_64
115306f32e7eSjoerg             // instructions.
115406f32e7eSjoerg   case 'Z': // 32-bit unsigned integer constant for use with zero-extending
115506f32e7eSjoerg             // x86_64 instructions.
115606f32e7eSjoerg   case 's':
115706f32e7eSjoerg     Info.setRequiresImmediate();
115806f32e7eSjoerg     return true;
115906f32e7eSjoerg   case 'I':
116006f32e7eSjoerg     Info.setRequiresImmediate(0, 31);
116106f32e7eSjoerg     return true;
116206f32e7eSjoerg   case 'J':
116306f32e7eSjoerg     Info.setRequiresImmediate(0, 63);
116406f32e7eSjoerg     return true;
116506f32e7eSjoerg   case 'K':
116606f32e7eSjoerg     Info.setRequiresImmediate(-128, 127);
116706f32e7eSjoerg     return true;
116806f32e7eSjoerg   case 'L':
116906f32e7eSjoerg     Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)});
117006f32e7eSjoerg     return true;
117106f32e7eSjoerg   case 'M':
117206f32e7eSjoerg     Info.setRequiresImmediate(0, 3);
117306f32e7eSjoerg     return true;
117406f32e7eSjoerg   case 'N':
117506f32e7eSjoerg     Info.setRequiresImmediate(0, 255);
117606f32e7eSjoerg     return true;
117706f32e7eSjoerg   case 'O':
117806f32e7eSjoerg     Info.setRequiresImmediate(0, 127);
117906f32e7eSjoerg     return true;
118006f32e7eSjoerg   // Register constraints.
118106f32e7eSjoerg   case 'Y': // 'Y' is the first character for several 2-character constraints.
118206f32e7eSjoerg     // Shift the pointer to the second character of the constraint.
118306f32e7eSjoerg     Name++;
118406f32e7eSjoerg     switch (*Name) {
118506f32e7eSjoerg     default:
118606f32e7eSjoerg       return false;
1187*13fbcb42Sjoerg     case 'z': // First SSE register.
118806f32e7eSjoerg     case '2':
118906f32e7eSjoerg     case 't': // Any SSE register, when SSE2 is enabled.
119006f32e7eSjoerg     case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
119106f32e7eSjoerg     case 'm': // Any MMX register, when inter-unit moves enabled.
119206f32e7eSjoerg     case 'k': // AVX512 arch mask registers: k1-k7.
119306f32e7eSjoerg       Info.setAllowsRegister();
119406f32e7eSjoerg       return true;
119506f32e7eSjoerg     }
119606f32e7eSjoerg   case 'f': // Any x87 floating point stack register.
119706f32e7eSjoerg     // Constraint 'f' cannot be used for output operands.
119806f32e7eSjoerg     if (Info.ConstraintStr[0] == '=')
119906f32e7eSjoerg       return false;
120006f32e7eSjoerg     Info.setAllowsRegister();
120106f32e7eSjoerg     return true;
120206f32e7eSjoerg   case 'a': // eax.
120306f32e7eSjoerg   case 'b': // ebx.
120406f32e7eSjoerg   case 'c': // ecx.
120506f32e7eSjoerg   case 'd': // edx.
120606f32e7eSjoerg   case 'S': // esi.
120706f32e7eSjoerg   case 'D': // edi.
120806f32e7eSjoerg   case 'A': // edx:eax.
120906f32e7eSjoerg   case 't': // Top of floating point stack.
121006f32e7eSjoerg   case 'u': // Second from top of floating point stack.
121106f32e7eSjoerg   case 'q': // Any register accessible as [r]l: a, b, c, and d.
121206f32e7eSjoerg   case 'y': // Any MMX register.
121306f32e7eSjoerg   case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)
121406f32e7eSjoerg   case 'x': // Any SSE register.
121506f32e7eSjoerg   case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0
121606f32e7eSjoerg             // for intermideate k reg operations).
121706f32e7eSjoerg   case 'Q': // Any register accessible as [r]h: a, b, c, and d.
121806f32e7eSjoerg   case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
121906f32e7eSjoerg   case 'l': // "Index" registers: any general register that can be used as an
122006f32e7eSjoerg             // index in a base+index memory access.
122106f32e7eSjoerg     Info.setAllowsRegister();
122206f32e7eSjoerg     return true;
122306f32e7eSjoerg   // Floating point constant constraints.
122406f32e7eSjoerg   case 'C': // SSE floating point constant.
122506f32e7eSjoerg   case 'G': // x87 floating point constant.
122606f32e7eSjoerg     return true;
122706f32e7eSjoerg   case '@':
122806f32e7eSjoerg     // CC condition changes.
122906f32e7eSjoerg     if (auto Len = matchAsmCCConstraint(Name)) {
123006f32e7eSjoerg       Name += Len - 1;
123106f32e7eSjoerg       Info.setAllowsRegister();
123206f32e7eSjoerg       return true;
123306f32e7eSjoerg     }
123406f32e7eSjoerg     return false;
123506f32e7eSjoerg   }
123606f32e7eSjoerg }
123706f32e7eSjoerg 
1238*13fbcb42Sjoerg // Below is based on the following information:
1239*13fbcb42Sjoerg // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1240*13fbcb42Sjoerg // |           Processor Name           | Cache Line Size (Bytes) |                                                                            Source                                                                            |
1241*13fbcb42Sjoerg // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1242*13fbcb42Sjoerg // | i386                               |                      64 | https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf                                          |
1243*13fbcb42Sjoerg // | 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) |
1244*13fbcb42Sjoerg // | i586/Pentium MMX                   |                      32 | https://www.7-cpu.com/cpu/P-MMX.html                                                                                                                         |
1245*13fbcb42Sjoerg // | i686/Pentium                       |                      32 | https://www.7-cpu.com/cpu/P6.html                                                                                                                            |
1246*13fbcb42Sjoerg // | Netburst/Pentium4                  |                      64 | https://www.7-cpu.com/cpu/P4-180.html                                                                                                                        |
1247*13fbcb42Sjoerg // | Atom                               |                      64 | https://www.7-cpu.com/cpu/Atom.html                                                                                                                          |
1248*13fbcb42Sjoerg // | Westmere                           |                      64 | https://en.wikichip.org/wiki/intel/microarchitectures/sandy_bridge_(client) "Cache Architecture"                                                             |
1249*13fbcb42Sjoerg // | Sandy Bridge                       |                      64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html                                                                    |
1250*13fbcb42Sjoerg // | Ivy Bridge                         |                      64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html                                                      |
1251*13fbcb42Sjoerg // | Haswell                            |                      64 | https://www.7-cpu.com/cpu/Haswell.html                                                                                                                       |
1252*13fbcb42Sjoerg // | Boadwell                           |                      64 | https://www.7-cpu.com/cpu/Broadwell.html                                                                                                                     |
1253*13fbcb42Sjoerg // | Skylake (including skylake-avx512) |                      64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy"                                                                       |
1254*13fbcb42Sjoerg // | Cascade Lake                       |                      64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy"                                                                  |
1255*13fbcb42Sjoerg // | Skylake                            |                      64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy"                                                                           |
1256*13fbcb42Sjoerg // | Ice Lake                           |                      64 | https://www.7-cpu.com/cpu/Ice_Lake.html                                                                                                                      |
1257*13fbcb42Sjoerg // | 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" |
1258*13fbcb42Sjoerg // | 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 "       |
1259*13fbcb42Sjoerg // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
getCPUCacheLineSize() const1260*13fbcb42Sjoerg Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
1261*13fbcb42Sjoerg   using namespace llvm::X86;
1262*13fbcb42Sjoerg   switch (CPU) {
1263*13fbcb42Sjoerg     // i386
1264*13fbcb42Sjoerg     case CK_i386:
1265*13fbcb42Sjoerg     // i486
1266*13fbcb42Sjoerg     case CK_i486:
1267*13fbcb42Sjoerg     case CK_WinChipC6:
1268*13fbcb42Sjoerg     case CK_WinChip2:
1269*13fbcb42Sjoerg     case CK_C3:
1270*13fbcb42Sjoerg     // Lakemont
1271*13fbcb42Sjoerg     case CK_Lakemont:
1272*13fbcb42Sjoerg       return 16;
1273*13fbcb42Sjoerg 
1274*13fbcb42Sjoerg     // i586
1275*13fbcb42Sjoerg     case CK_i586:
1276*13fbcb42Sjoerg     case CK_Pentium:
1277*13fbcb42Sjoerg     case CK_PentiumMMX:
1278*13fbcb42Sjoerg     // i686
1279*13fbcb42Sjoerg     case CK_PentiumPro:
1280*13fbcb42Sjoerg     case CK_i686:
1281*13fbcb42Sjoerg     case CK_Pentium2:
1282*13fbcb42Sjoerg     case CK_Pentium3:
1283*13fbcb42Sjoerg     case CK_PentiumM:
1284*13fbcb42Sjoerg     case CK_C3_2:
1285*13fbcb42Sjoerg     // K6
1286*13fbcb42Sjoerg     case CK_K6:
1287*13fbcb42Sjoerg     case CK_K6_2:
1288*13fbcb42Sjoerg     case CK_K6_3:
1289*13fbcb42Sjoerg     // Geode
1290*13fbcb42Sjoerg     case CK_Geode:
1291*13fbcb42Sjoerg       return 32;
1292*13fbcb42Sjoerg 
1293*13fbcb42Sjoerg     // Netburst
1294*13fbcb42Sjoerg     case CK_Pentium4:
1295*13fbcb42Sjoerg     case CK_Prescott:
1296*13fbcb42Sjoerg     case CK_Nocona:
1297*13fbcb42Sjoerg     // Atom
1298*13fbcb42Sjoerg     case CK_Bonnell:
1299*13fbcb42Sjoerg     case CK_Silvermont:
1300*13fbcb42Sjoerg     case CK_Goldmont:
1301*13fbcb42Sjoerg     case CK_GoldmontPlus:
1302*13fbcb42Sjoerg     case CK_Tremont:
1303*13fbcb42Sjoerg 
1304*13fbcb42Sjoerg     case CK_Westmere:
1305*13fbcb42Sjoerg     case CK_SandyBridge:
1306*13fbcb42Sjoerg     case CK_IvyBridge:
1307*13fbcb42Sjoerg     case CK_Haswell:
1308*13fbcb42Sjoerg     case CK_Broadwell:
1309*13fbcb42Sjoerg     case CK_SkylakeClient:
1310*13fbcb42Sjoerg     case CK_SkylakeServer:
1311*13fbcb42Sjoerg     case CK_Cascadelake:
1312*13fbcb42Sjoerg     case CK_Nehalem:
1313*13fbcb42Sjoerg     case CK_Cooperlake:
1314*13fbcb42Sjoerg     case CK_Cannonlake:
1315*13fbcb42Sjoerg     case CK_Tigerlake:
1316*13fbcb42Sjoerg     case CK_SapphireRapids:
1317*13fbcb42Sjoerg     case CK_IcelakeClient:
1318*13fbcb42Sjoerg     case CK_Rocketlake:
1319*13fbcb42Sjoerg     case CK_IcelakeServer:
1320*13fbcb42Sjoerg     case CK_Alderlake:
1321*13fbcb42Sjoerg     case CK_KNL:
1322*13fbcb42Sjoerg     case CK_KNM:
1323*13fbcb42Sjoerg     // K7
1324*13fbcb42Sjoerg     case CK_Athlon:
1325*13fbcb42Sjoerg     case CK_AthlonXP:
1326*13fbcb42Sjoerg     // K8
1327*13fbcb42Sjoerg     case CK_K8:
1328*13fbcb42Sjoerg     case CK_K8SSE3:
1329*13fbcb42Sjoerg     case CK_AMDFAM10:
1330*13fbcb42Sjoerg     // Bobcat
1331*13fbcb42Sjoerg     case CK_BTVER1:
1332*13fbcb42Sjoerg     case CK_BTVER2:
1333*13fbcb42Sjoerg     // Bulldozer
1334*13fbcb42Sjoerg     case CK_BDVER1:
1335*13fbcb42Sjoerg     case CK_BDVER2:
1336*13fbcb42Sjoerg     case CK_BDVER3:
1337*13fbcb42Sjoerg     case CK_BDVER4:
1338*13fbcb42Sjoerg     // Zen
1339*13fbcb42Sjoerg     case CK_ZNVER1:
1340*13fbcb42Sjoerg     case CK_ZNVER2:
1341*13fbcb42Sjoerg     case CK_ZNVER3:
1342*13fbcb42Sjoerg     // Deprecated
1343*13fbcb42Sjoerg     case CK_x86_64:
1344*13fbcb42Sjoerg     case CK_x86_64_v2:
1345*13fbcb42Sjoerg     case CK_x86_64_v3:
1346*13fbcb42Sjoerg     case CK_x86_64_v4:
1347*13fbcb42Sjoerg     case CK_Yonah:
1348*13fbcb42Sjoerg     case CK_Penryn:
1349*13fbcb42Sjoerg     case CK_Core2:
1350*13fbcb42Sjoerg       return 64;
1351*13fbcb42Sjoerg 
1352*13fbcb42Sjoerg     // The following currently have unknown cache line sizes (but they are probably all 64):
1353*13fbcb42Sjoerg     // Core
1354*13fbcb42Sjoerg     case CK_None:
1355*13fbcb42Sjoerg       return None;
1356*13fbcb42Sjoerg   }
1357*13fbcb42Sjoerg   llvm_unreachable("Unknown CPU kind");
1358*13fbcb42Sjoerg }
1359*13fbcb42Sjoerg 
validateOutputSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1360*13fbcb42Sjoerg bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
1361*13fbcb42Sjoerg                                        StringRef Constraint,
136206f32e7eSjoerg                                        unsigned Size) const {
136306f32e7eSjoerg   // Strip off constraint modifiers.
136406f32e7eSjoerg   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
136506f32e7eSjoerg     Constraint = Constraint.substr(1);
136606f32e7eSjoerg 
1367*13fbcb42Sjoerg   return validateOperandSize(FeatureMap, Constraint, Size);
136806f32e7eSjoerg }
136906f32e7eSjoerg 
validateInputSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1370*13fbcb42Sjoerg bool X86TargetInfo::validateInputSize(const llvm::StringMap<bool> &FeatureMap,
1371*13fbcb42Sjoerg                                       StringRef Constraint,
137206f32e7eSjoerg                                       unsigned Size) const {
1373*13fbcb42Sjoerg   return validateOperandSize(FeatureMap, Constraint, Size);
137406f32e7eSjoerg }
137506f32e7eSjoerg 
validateOperandSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1376*13fbcb42Sjoerg bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
1377*13fbcb42Sjoerg                                         StringRef Constraint,
137806f32e7eSjoerg                                         unsigned Size) const {
137906f32e7eSjoerg   switch (Constraint[0]) {
138006f32e7eSjoerg   default:
138106f32e7eSjoerg     break;
138206f32e7eSjoerg   case 'k':
138306f32e7eSjoerg   // Registers k0-k7 (AVX512) size limit is 64 bit.
138406f32e7eSjoerg   case 'y':
138506f32e7eSjoerg     return Size <= 64;
138606f32e7eSjoerg   case 'f':
138706f32e7eSjoerg   case 't':
138806f32e7eSjoerg   case 'u':
138906f32e7eSjoerg     return Size <= 128;
139006f32e7eSjoerg   case 'Y':
139106f32e7eSjoerg     // 'Y' is the first character for several 2-character constraints.
139206f32e7eSjoerg     switch (Constraint[1]) {
139306f32e7eSjoerg     default:
139406f32e7eSjoerg       return false;
139506f32e7eSjoerg     case 'm':
139606f32e7eSjoerg       // 'Ym' is synonymous with 'y'.
139706f32e7eSjoerg     case 'k':
139806f32e7eSjoerg       return Size <= 64;
139906f32e7eSjoerg     case 'z':
1400*13fbcb42Sjoerg       // XMM0/YMM/ZMM0
1401*13fbcb42Sjoerg       if (hasFeatureEnabled(FeatureMap, "avx512f"))
1402*13fbcb42Sjoerg         // ZMM0 can be used if target supports AVX512F.
1403*13fbcb42Sjoerg         return Size <= 512U;
1404*13fbcb42Sjoerg       else if (hasFeatureEnabled(FeatureMap, "avx"))
1405*13fbcb42Sjoerg         // YMM0 can be used if target supports AVX.
1406*13fbcb42Sjoerg         return Size <= 256U;
1407*13fbcb42Sjoerg       else if (hasFeatureEnabled(FeatureMap, "sse"))
140806f32e7eSjoerg         return Size <= 128U;
140906f32e7eSjoerg       return false;
141006f32e7eSjoerg     case 'i':
141106f32e7eSjoerg     case 't':
141206f32e7eSjoerg     case '2':
141306f32e7eSjoerg       // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled.
141406f32e7eSjoerg       if (SSELevel < SSE2)
141506f32e7eSjoerg         return false;
141606f32e7eSjoerg       break;
141706f32e7eSjoerg     }
1418*13fbcb42Sjoerg     break;
141906f32e7eSjoerg   case 'v':
142006f32e7eSjoerg   case 'x':
1421*13fbcb42Sjoerg     if (hasFeatureEnabled(FeatureMap, "avx512f"))
142206f32e7eSjoerg       // 512-bit zmm registers can be used if target supports AVX512F.
142306f32e7eSjoerg       return Size <= 512U;
1424*13fbcb42Sjoerg     else if (hasFeatureEnabled(FeatureMap, "avx"))
142506f32e7eSjoerg       // 256-bit ymm registers can be used if target supports AVX.
142606f32e7eSjoerg       return Size <= 256U;
142706f32e7eSjoerg     return Size <= 128U;
142806f32e7eSjoerg 
142906f32e7eSjoerg   }
143006f32e7eSjoerg 
143106f32e7eSjoerg   return true;
143206f32e7eSjoerg }
143306f32e7eSjoerg 
convertConstraint(const char * & Constraint) const143406f32e7eSjoerg std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
143506f32e7eSjoerg   switch (*Constraint) {
143606f32e7eSjoerg   case '@':
143706f32e7eSjoerg     if (auto Len = matchAsmCCConstraint(Constraint)) {
143806f32e7eSjoerg       std::string Converted = "{" + std::string(Constraint, Len) + "}";
143906f32e7eSjoerg       Constraint += Len - 1;
144006f32e7eSjoerg       return Converted;
144106f32e7eSjoerg     }
144206f32e7eSjoerg     return std::string(1, *Constraint);
144306f32e7eSjoerg   case 'a':
144406f32e7eSjoerg     return std::string("{ax}");
144506f32e7eSjoerg   case 'b':
144606f32e7eSjoerg     return std::string("{bx}");
144706f32e7eSjoerg   case 'c':
144806f32e7eSjoerg     return std::string("{cx}");
144906f32e7eSjoerg   case 'd':
145006f32e7eSjoerg     return std::string("{dx}");
145106f32e7eSjoerg   case 'S':
145206f32e7eSjoerg     return std::string("{si}");
145306f32e7eSjoerg   case 'D':
145406f32e7eSjoerg     return std::string("{di}");
145506f32e7eSjoerg   case 'p': // address
145606f32e7eSjoerg     return std::string("im");
145706f32e7eSjoerg   case 't': // top of floating point stack.
145806f32e7eSjoerg     return std::string("{st}");
145906f32e7eSjoerg   case 'u':                        // second from top of floating point stack.
146006f32e7eSjoerg     return std::string("{st(1)}"); // second from top of floating point stack.
146106f32e7eSjoerg   case 'Y':
146206f32e7eSjoerg     switch (Constraint[1]) {
146306f32e7eSjoerg     default:
146406f32e7eSjoerg       // Break from inner switch and fall through (copy single char),
146506f32e7eSjoerg       // continue parsing after copying the current constraint into
146606f32e7eSjoerg       // the return string.
146706f32e7eSjoerg       break;
146806f32e7eSjoerg     case 'k':
146906f32e7eSjoerg     case 'm':
147006f32e7eSjoerg     case 'i':
147106f32e7eSjoerg     case 't':
147206f32e7eSjoerg     case 'z':
147306f32e7eSjoerg     case '2':
147406f32e7eSjoerg       // "^" hints llvm that this is a 2 letter constraint.
147506f32e7eSjoerg       // "Constraint++" is used to promote the string iterator
147606f32e7eSjoerg       // to the next constraint.
147706f32e7eSjoerg       return std::string("^") + std::string(Constraint++, 2);
147806f32e7eSjoerg     }
147906f32e7eSjoerg     LLVM_FALLTHROUGH;
148006f32e7eSjoerg   default:
148106f32e7eSjoerg     return std::string(1, *Constraint);
148206f32e7eSjoerg   }
148306f32e7eSjoerg }
148406f32e7eSjoerg 
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const148506f32e7eSjoerg void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
1486*13fbcb42Sjoerg   bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
1487*13fbcb42Sjoerg   llvm::X86::fillValidCPUArchList(Values, Only64Bit);
148806f32e7eSjoerg }
148906f32e7eSjoerg 
fillValidTuneCPUList(SmallVectorImpl<StringRef> & Values) const1490*13fbcb42Sjoerg void X86TargetInfo::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const {
1491*13fbcb42Sjoerg   llvm::X86::fillValidTuneCPUList(Values);
149206f32e7eSjoerg }
149306f32e7eSjoerg 
getGCCRegNames() const149406f32e7eSjoerg ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {
149506f32e7eSjoerg   return llvm::makeArrayRef(GCCRegNames);
149606f32e7eSjoerg }
149706f32e7eSjoerg 
getGCCAddlRegNames() const149806f32e7eSjoerg ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
149906f32e7eSjoerg   return llvm::makeArrayRef(AddlRegNames);
150006f32e7eSjoerg }
150106f32e7eSjoerg 
getTargetBuiltins() const150206f32e7eSjoerg ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
150306f32e7eSjoerg   return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
150406f32e7eSjoerg                                                 Builtin::FirstTSBuiltin + 1);
150506f32e7eSjoerg }
150606f32e7eSjoerg 
getTargetBuiltins() const150706f32e7eSjoerg ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
150806f32e7eSjoerg   return llvm::makeArrayRef(BuiltinInfoX86,
150906f32e7eSjoerg                             X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
151006f32e7eSjoerg }
1511