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