xref: /freebsd-src/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp (revision c80e69b00d976a5a3b3e84527f270fa7e72a8205)
10b57cec5SDimitry Andric //===--- X86.cpp - Implement X86 target feature support -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements X86 TargetInfo objects.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "X86.h"
140b57cec5SDimitry Andric #include "clang/Basic/Builtins.h"
150b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
160b57cec5SDimitry Andric #include "clang/Basic/TargetBuiltins.h"
170b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
190b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
2006c3fb27SDimitry Andric #include "llvm/TargetParser/X86TargetParser.h"
21bdd1243dSDimitry Andric #include <optional>
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace clang {
240b57cec5SDimitry Andric namespace targets {
250b57cec5SDimitry Andric 
26bdd1243dSDimitry Andric static constexpr Builtin::Info BuiltinInfoX86[] = {
270b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
28bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
290b57cec5SDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
30bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
310b57cec5SDimitry Andric #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
32bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
330b57cec5SDimitry Andric #include "clang/Basic/BuiltinsX86.def"
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
36bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
370b57cec5SDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
38bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
390b57cec5SDimitry Andric #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
40bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
410b57cec5SDimitry Andric #include "clang/Basic/BuiltinsX86_64.def"
420b57cec5SDimitry Andric };
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric static const char *const GCCRegNames[] = {
450b57cec5SDimitry Andric     "ax",    "dx",    "cx",    "bx",    "si",      "di",    "bp",    "sp",
460b57cec5SDimitry Andric     "st",    "st(1)", "st(2)", "st(3)", "st(4)",   "st(5)", "st(6)", "st(7)",
470b57cec5SDimitry Andric     "argp",  "flags", "fpcr",  "fpsr",  "dirflag", "frame", "xmm0",  "xmm1",
480b57cec5SDimitry Andric     "xmm2",  "xmm3",  "xmm4",  "xmm5",  "xmm6",    "xmm7",  "mm0",   "mm1",
490b57cec5SDimitry Andric     "mm2",   "mm3",   "mm4",   "mm5",   "mm6",     "mm7",   "r8",    "r9",
500b57cec5SDimitry Andric     "r10",   "r11",   "r12",   "r13",   "r14",     "r15",   "xmm8",  "xmm9",
510b57cec5SDimitry Andric     "xmm10", "xmm11", "xmm12", "xmm13", "xmm14",   "xmm15", "ymm0",  "ymm1",
520b57cec5SDimitry Andric     "ymm2",  "ymm3",  "ymm4",  "ymm5",  "ymm6",    "ymm7",  "ymm8",  "ymm9",
530b57cec5SDimitry Andric     "ymm10", "ymm11", "ymm12", "ymm13", "ymm14",   "ymm15", "xmm16", "xmm17",
540b57cec5SDimitry Andric     "xmm18", "xmm19", "xmm20", "xmm21", "xmm22",   "xmm23", "xmm24", "xmm25",
550b57cec5SDimitry Andric     "xmm26", "xmm27", "xmm28", "xmm29", "xmm30",   "xmm31", "ymm16", "ymm17",
560b57cec5SDimitry Andric     "ymm18", "ymm19", "ymm20", "ymm21", "ymm22",   "ymm23", "ymm24", "ymm25",
570b57cec5SDimitry Andric     "ymm26", "ymm27", "ymm28", "ymm29", "ymm30",   "ymm31", "zmm0",  "zmm1",
580b57cec5SDimitry Andric     "zmm2",  "zmm3",  "zmm4",  "zmm5",  "zmm6",    "zmm7",  "zmm8",  "zmm9",
590b57cec5SDimitry Andric     "zmm10", "zmm11", "zmm12", "zmm13", "zmm14",   "zmm15", "zmm16", "zmm17",
600b57cec5SDimitry Andric     "zmm18", "zmm19", "zmm20", "zmm21", "zmm22",   "zmm23", "zmm24", "zmm25",
610b57cec5SDimitry Andric     "zmm26", "zmm27", "zmm28", "zmm29", "zmm30",   "zmm31", "k0",    "k1",
620b57cec5SDimitry Andric     "k2",    "k3",    "k4",    "k5",    "k6",      "k7",
630b57cec5SDimitry Andric     "cr0",   "cr2",   "cr3",   "cr4",   "cr8",
640b57cec5SDimitry Andric     "dr0",   "dr1",   "dr2",   "dr3",   "dr6",     "dr7",
650b57cec5SDimitry Andric     "bnd0",  "bnd1",  "bnd2",  "bnd3",
665ffd83dbSDimitry Andric     "tmm0",  "tmm1",  "tmm2",  "tmm3",  "tmm4",    "tmm5",  "tmm6",  "tmm7",
670fca6ea1SDimitry Andric     "r16",   "r17",   "r18",   "r19",   "r20",     "r21",   "r22",   "r23",
680fca6ea1SDimitry Andric     "r24",   "r25",   "r26",   "r27",   "r28",     "r29",   "r30",   "r31",
690b57cec5SDimitry Andric };
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric const TargetInfo::AddlRegName AddlRegNames[] = {
720b57cec5SDimitry Andric     {{"al", "ah", "eax", "rax"}, 0},
730b57cec5SDimitry Andric     {{"bl", "bh", "ebx", "rbx"}, 3},
740b57cec5SDimitry Andric     {{"cl", "ch", "ecx", "rcx"}, 2},
750b57cec5SDimitry Andric     {{"dl", "dh", "edx", "rdx"}, 1},
760b57cec5SDimitry Andric     {{"esi", "rsi"}, 4},
770b57cec5SDimitry Andric     {{"edi", "rdi"}, 5},
780b57cec5SDimitry Andric     {{"esp", "rsp"}, 7},
790b57cec5SDimitry Andric     {{"ebp", "rbp"}, 6},
800b57cec5SDimitry Andric     {{"r8d", "r8w", "r8b"}, 38},
810b57cec5SDimitry Andric     {{"r9d", "r9w", "r9b"}, 39},
820b57cec5SDimitry Andric     {{"r10d", "r10w", "r10b"}, 40},
830b57cec5SDimitry Andric     {{"r11d", "r11w", "r11b"}, 41},
840b57cec5SDimitry Andric     {{"r12d", "r12w", "r12b"}, 42},
850b57cec5SDimitry Andric     {{"r13d", "r13w", "r13b"}, 43},
860b57cec5SDimitry Andric     {{"r14d", "r14w", "r14b"}, 44},
870b57cec5SDimitry Andric     {{"r15d", "r15w", "r15b"}, 45},
880fca6ea1SDimitry Andric     {{"r16d", "r16w", "r16b"}, 165},
890fca6ea1SDimitry Andric     {{"r17d", "r17w", "r17b"}, 166},
900fca6ea1SDimitry Andric     {{"r18d", "r18w", "r18b"}, 167},
910fca6ea1SDimitry Andric     {{"r19d", "r19w", "r19b"}, 168},
920fca6ea1SDimitry Andric     {{"r20d", "r20w", "r20b"}, 169},
930fca6ea1SDimitry Andric     {{"r21d", "r21w", "r21b"}, 170},
940fca6ea1SDimitry Andric     {{"r22d", "r22w", "r22b"}, 171},
950fca6ea1SDimitry Andric     {{"r23d", "r23w", "r23b"}, 172},
960fca6ea1SDimitry Andric     {{"r24d", "r24w", "r24b"}, 173},
970fca6ea1SDimitry Andric     {{"r25d", "r25w", "r25b"}, 174},
980fca6ea1SDimitry Andric     {{"r26d", "r26w", "r26b"}, 175},
990fca6ea1SDimitry Andric     {{"r27d", "r27w", "r27b"}, 176},
1000fca6ea1SDimitry Andric     {{"r28d", "r28w", "r28b"}, 177},
1010fca6ea1SDimitry Andric     {{"r29d", "r29w", "r29b"}, 178},
1020fca6ea1SDimitry Andric     {{"r30d", "r30w", "r30b"}, 179},
1030fca6ea1SDimitry Andric     {{"r31d", "r31w", "r31b"}, 180},
1040b57cec5SDimitry Andric };
1050b57cec5SDimitry Andric } // namespace targets
1060b57cec5SDimitry Andric } // namespace clang
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric using namespace clang;
1090b57cec5SDimitry Andric using namespace clang::targets;
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric bool X86TargetInfo::setFPMath(StringRef Name) {
1120b57cec5SDimitry Andric   if (Name == "387") {
1130b57cec5SDimitry Andric     FPMath = FP_387;
1140b57cec5SDimitry Andric     return true;
1150b57cec5SDimitry Andric   }
1160b57cec5SDimitry Andric   if (Name == "sse") {
1170b57cec5SDimitry Andric     FPMath = FP_SSE;
1180b57cec5SDimitry Andric     return true;
1190b57cec5SDimitry Andric   }
1200b57cec5SDimitry Andric   return false;
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric bool X86TargetInfo::initFeatureMap(
1240b57cec5SDimitry Andric     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
1250b57cec5SDimitry Andric     const std::vector<std::string> &FeaturesVec) const {
1260b57cec5SDimitry Andric   // FIXME: This *really* should not be here.
1270b57cec5SDimitry Andric   // X86_64 always has SSE2.
1280b57cec5SDimitry Andric   if (getTriple().getArch() == llvm::Triple::x86_64)
1295ffd83dbSDimitry Andric     setFeatureEnabled(Features, "sse2", true);
1300b57cec5SDimitry Andric 
1315ffd83dbSDimitry Andric   using namespace llvm::X86;
1320b57cec5SDimitry Andric 
1335ffd83dbSDimitry Andric   SmallVector<StringRef, 16> CPUFeatures;
1345ffd83dbSDimitry Andric   getFeaturesForCPU(CPU, CPUFeatures);
1355ffd83dbSDimitry Andric   for (auto &F : CPUFeatures)
1365ffd83dbSDimitry Andric     setFeatureEnabled(Features, F, true);
1370b57cec5SDimitry Andric 
138fe6060f1SDimitry Andric   std::vector<std::string> UpdatedFeaturesVec;
1395f757f3fSDimitry Andric   std::vector<std::string> UpdatedAVX10FeaturesVec;
1405f757f3fSDimitry Andric   enum { FE_NOSET = -1, FE_FALSE, FE_TRUE };
1415f757f3fSDimitry Andric   int HasEVEX512 = FE_NOSET;
1425f757f3fSDimitry Andric   bool HasAVX512F = Features.lookup("avx512f");
1435f757f3fSDimitry Andric   bool HasAVX10 = Features.lookup("avx10.1-256");
1445f757f3fSDimitry Andric   bool HasAVX10_512 = Features.lookup("avx10.1-512");
1455f757f3fSDimitry Andric   std::string LastAVX10;
1465f757f3fSDimitry Andric   std::string LastAVX512;
147fe6060f1SDimitry Andric   for (const auto &Feature : FeaturesVec) {
148fe6060f1SDimitry Andric     // Expand general-regs-only to -x86, -mmx and -sse
149fe6060f1SDimitry Andric     if (Feature == "+general-regs-only") {
150fe6060f1SDimitry Andric       UpdatedFeaturesVec.push_back("-x87");
151fe6060f1SDimitry Andric       UpdatedFeaturesVec.push_back("-mmx");
152fe6060f1SDimitry Andric       UpdatedFeaturesVec.push_back("-sse");
153fe6060f1SDimitry Andric       continue;
154fe6060f1SDimitry Andric     }
155fe6060f1SDimitry Andric 
1565f757f3fSDimitry Andric     if (Feature.substr(1, 6) == "avx10.") {
1575f757f3fSDimitry Andric       if (Feature[0] == '+') {
1585f757f3fSDimitry Andric         HasAVX10 = true;
1590fca6ea1SDimitry Andric         if (StringRef(Feature).ends_with("512"))
1605f757f3fSDimitry Andric           HasAVX10_512 = true;
1615f757f3fSDimitry Andric         LastAVX10 = Feature;
1625f757f3fSDimitry Andric       } else if (HasAVX10 && Feature == "-avx10.1-256") {
1635f757f3fSDimitry Andric         HasAVX10 = false;
1645f757f3fSDimitry Andric         HasAVX10_512 = false;
1655f757f3fSDimitry Andric       } else if (HasAVX10_512 && Feature == "-avx10.1-512") {
1665f757f3fSDimitry Andric         HasAVX10_512 = false;
1675f757f3fSDimitry Andric       }
1685f757f3fSDimitry Andric       // Postpone AVX10 features handling after AVX512 settled.
1695f757f3fSDimitry Andric       UpdatedAVX10FeaturesVec.push_back(Feature);
1705f757f3fSDimitry Andric       continue;
1710fca6ea1SDimitry Andric     } else if (!HasAVX512F && StringRef(Feature).starts_with("+avx512")) {
1725f757f3fSDimitry Andric       HasAVX512F = true;
1735f757f3fSDimitry Andric       LastAVX512 = Feature;
1745f757f3fSDimitry Andric     } else if (HasAVX512F && Feature == "-avx512f") {
1755f757f3fSDimitry Andric       HasAVX512F = false;
1765f757f3fSDimitry Andric     } else if (HasEVEX512 != FE_TRUE && Feature == "+evex512") {
1775f757f3fSDimitry Andric       HasEVEX512 = FE_TRUE;
1785f757f3fSDimitry Andric       continue;
1795f757f3fSDimitry Andric     } else if (HasEVEX512 != FE_FALSE && Feature == "-evex512") {
1805f757f3fSDimitry Andric       HasEVEX512 = FE_FALSE;
1815f757f3fSDimitry Andric       continue;
1825f757f3fSDimitry Andric     }
1835f757f3fSDimitry Andric 
184fe6060f1SDimitry Andric     UpdatedFeaturesVec.push_back(Feature);
185fe6060f1SDimitry Andric   }
1865f757f3fSDimitry Andric   llvm::append_range(UpdatedFeaturesVec, UpdatedAVX10FeaturesVec);
1875f757f3fSDimitry Andric   // HasEVEX512 is a three-states flag. We need to turn it into [+-]evex512
1885f757f3fSDimitry Andric   // according to other features.
1895f757f3fSDimitry Andric   if (HasAVX512F) {
1905f757f3fSDimitry Andric     UpdatedFeaturesVec.push_back(HasEVEX512 == FE_FALSE ? "-evex512"
1915f757f3fSDimitry Andric                                                         : "+evex512");
1925f757f3fSDimitry Andric     if (HasAVX10 && !HasAVX10_512 && HasEVEX512 != FE_FALSE)
1935f757f3fSDimitry Andric       Diags.Report(diag::warn_invalid_feature_combination)
1945f757f3fSDimitry Andric           << LastAVX512 + " " + LastAVX10 + "; will be promoted to avx10.1-512";
1955f757f3fSDimitry Andric   } else if (HasAVX10) {
1965f757f3fSDimitry Andric     if (HasEVEX512 != FE_NOSET)
1975f757f3fSDimitry Andric       Diags.Report(diag::warn_invalid_feature_combination)
1985f757f3fSDimitry Andric           << LastAVX10 + (HasEVEX512 == FE_TRUE ? " +evex512" : " -evex512");
1995f757f3fSDimitry Andric     UpdatedFeaturesVec.push_back(HasAVX10_512 ? "+evex512" : "-evex512");
2005f757f3fSDimitry Andric   }
201fe6060f1SDimitry Andric 
202fe6060f1SDimitry Andric   if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec))
2030b57cec5SDimitry Andric     return false;
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric   // Can't do this earlier because we need to be able to explicitly enable
2060b57cec5SDimitry Andric   // or disable these features and the things that they depend upon.
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
2090b57cec5SDimitry Andric   auto I = Features.find("sse4.2");
2100b57cec5SDimitry Andric   if (I != Features.end() && I->getValue() &&
211349cc55cSDimitry Andric       !llvm::is_contained(UpdatedFeaturesVec, "-popcnt"))
2120b57cec5SDimitry Andric     Features["popcnt"] = true;
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   // Additionally, if SSE is enabled and mmx is not explicitly disabled,
2150b57cec5SDimitry Andric   // then enable MMX.
2160b57cec5SDimitry Andric   I = Features.find("sse");
2170b57cec5SDimitry Andric   if (I != Features.end() && I->getValue() &&
218349cc55cSDimitry Andric       !llvm::is_contained(UpdatedFeaturesVec, "-mmx"))
2190b57cec5SDimitry Andric     Features["mmx"] = true;
2200b57cec5SDimitry Andric 
2215ffd83dbSDimitry Andric   // Enable xsave if avx is enabled and xsave is not explicitly disabled.
2225ffd83dbSDimitry Andric   I = Features.find("avx");
2235ffd83dbSDimitry Andric   if (I != Features.end() && I->getValue() &&
224349cc55cSDimitry Andric       !llvm::is_contained(UpdatedFeaturesVec, "-xsave"))
2255ffd83dbSDimitry Andric     Features["xsave"] = true;
2265ffd83dbSDimitry Andric 
227349cc55cSDimitry Andric   // Enable CRC32 if SSE4.2 is enabled and CRC32 is not explicitly disabled.
228349cc55cSDimitry Andric   I = Features.find("sse4.2");
229349cc55cSDimitry Andric   if (I != Features.end() && I->getValue() &&
230349cc55cSDimitry Andric       !llvm::is_contained(UpdatedFeaturesVec, "-crc32"))
231349cc55cSDimitry Andric     Features["crc32"] = true;
232349cc55cSDimitry Andric 
2330b57cec5SDimitry Andric   return true;
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric 
2365ffd83dbSDimitry Andric void X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
2375ffd83dbSDimitry Andric                                       StringRef Name, bool Enabled) const {
2385ffd83dbSDimitry Andric   if (Name == "sse4") {
2390b57cec5SDimitry Andric     // We can get here via the __target__ attribute since that's not controlled
2400b57cec5SDimitry Andric     // via the -msse4/-mno-sse4 command line alias. Handle this the same way
2410b57cec5SDimitry Andric     // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if
2420b57cec5SDimitry Andric     // disabled.
2430b57cec5SDimitry Andric     if (Enabled)
2445ffd83dbSDimitry Andric       Name = "sse4.2";
2450b57cec5SDimitry Andric     else
2465ffd83dbSDimitry Andric       Name = "sse4.1";
2470b57cec5SDimitry Andric   }
2485ffd83dbSDimitry Andric 
2495ffd83dbSDimitry Andric   Features[Name] = Enabled;
250e8d8bef9SDimitry Andric   llvm::X86::updateImpliedFeatures(Name, Enabled, Features);
2510b57cec5SDimitry Andric }
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric /// handleTargetFeatures - Perform initialization based on the user
2540b57cec5SDimitry Andric /// configured set of features.
2550b57cec5SDimitry Andric bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
2560b57cec5SDimitry Andric                                          DiagnosticsEngine &Diags) {
2570b57cec5SDimitry Andric   for (const auto &Feature : Features) {
2580b57cec5SDimitry Andric     if (Feature[0] != '+')
2590b57cec5SDimitry Andric       continue;
2600b57cec5SDimitry Andric 
2610fca6ea1SDimitry Andric     if (Feature == "+mmx") {
2620fca6ea1SDimitry Andric       HasMMX = true;
2630fca6ea1SDimitry Andric     } else if (Feature == "+aes") {
2640b57cec5SDimitry Andric       HasAES = true;
2650b57cec5SDimitry Andric     } else if (Feature == "+vaes") {
2660b57cec5SDimitry Andric       HasVAES = true;
2670b57cec5SDimitry Andric     } else if (Feature == "+pclmul") {
2680b57cec5SDimitry Andric       HasPCLMUL = true;
2690b57cec5SDimitry Andric     } else if (Feature == "+vpclmulqdq") {
2700b57cec5SDimitry Andric       HasVPCLMULQDQ = true;
2710b57cec5SDimitry Andric     } else if (Feature == "+lzcnt") {
2720b57cec5SDimitry Andric       HasLZCNT = true;
2730b57cec5SDimitry Andric     } else if (Feature == "+rdrnd") {
2740b57cec5SDimitry Andric       HasRDRND = true;
2750b57cec5SDimitry Andric     } else if (Feature == "+fsgsbase") {
2760b57cec5SDimitry Andric       HasFSGSBASE = true;
2770b57cec5SDimitry Andric     } else if (Feature == "+bmi") {
2780b57cec5SDimitry Andric       HasBMI = true;
2790b57cec5SDimitry Andric     } else if (Feature == "+bmi2") {
2800b57cec5SDimitry Andric       HasBMI2 = true;
2810b57cec5SDimitry Andric     } else if (Feature == "+popcnt") {
2820b57cec5SDimitry Andric       HasPOPCNT = true;
2830b57cec5SDimitry Andric     } else if (Feature == "+rtm") {
2840b57cec5SDimitry Andric       HasRTM = true;
2850b57cec5SDimitry Andric     } else if (Feature == "+prfchw") {
2860b57cec5SDimitry Andric       HasPRFCHW = true;
2870b57cec5SDimitry Andric     } else if (Feature == "+rdseed") {
2880b57cec5SDimitry Andric       HasRDSEED = true;
2890b57cec5SDimitry Andric     } else if (Feature == "+adx") {
2900b57cec5SDimitry Andric       HasADX = true;
2910b57cec5SDimitry Andric     } else if (Feature == "+tbm") {
2920b57cec5SDimitry Andric       HasTBM = true;
2930b57cec5SDimitry Andric     } else if (Feature == "+lwp") {
2940b57cec5SDimitry Andric       HasLWP = true;
2950b57cec5SDimitry Andric     } else if (Feature == "+fma") {
2960b57cec5SDimitry Andric       HasFMA = true;
2970b57cec5SDimitry Andric     } else if (Feature == "+f16c") {
2980b57cec5SDimitry Andric       HasF16C = true;
2990b57cec5SDimitry Andric     } else if (Feature == "+gfni") {
3000b57cec5SDimitry Andric       HasGFNI = true;
3015f757f3fSDimitry Andric     } else if (Feature == "+evex512") {
3025f757f3fSDimitry Andric       HasEVEX512 = true;
3035f757f3fSDimitry Andric     } else if (Feature == "+avx10.1-256") {
3045f757f3fSDimitry Andric       HasAVX10_1 = true;
3055f757f3fSDimitry Andric     } else if (Feature == "+avx10.1-512") {
3065f757f3fSDimitry Andric       HasAVX10_1_512 = true;
3070b57cec5SDimitry Andric     } else if (Feature == "+avx512cd") {
3080b57cec5SDimitry Andric       HasAVX512CD = true;
3090b57cec5SDimitry Andric     } else if (Feature == "+avx512vpopcntdq") {
3100b57cec5SDimitry Andric       HasAVX512VPOPCNTDQ = true;
3110b57cec5SDimitry Andric     } else if (Feature == "+avx512vnni") {
3120b57cec5SDimitry Andric       HasAVX512VNNI = true;
3130b57cec5SDimitry Andric     } else if (Feature == "+avx512bf16") {
3140b57cec5SDimitry Andric       HasAVX512BF16 = true;
315349cc55cSDimitry Andric     } else if (Feature == "+avx512fp16") {
316349cc55cSDimitry Andric       HasAVX512FP16 = true;
317bdd1243dSDimitry Andric       HasLegalHalfType = true;
3180b57cec5SDimitry Andric     } else if (Feature == "+avx512dq") {
3190b57cec5SDimitry Andric       HasAVX512DQ = true;
3200b57cec5SDimitry Andric     } else if (Feature == "+avx512bitalg") {
3210b57cec5SDimitry Andric       HasAVX512BITALG = true;
3220b57cec5SDimitry Andric     } else if (Feature == "+avx512bw") {
3230b57cec5SDimitry Andric       HasAVX512BW = true;
3240b57cec5SDimitry Andric     } else if (Feature == "+avx512vl") {
3250b57cec5SDimitry Andric       HasAVX512VL = true;
3260b57cec5SDimitry Andric     } else if (Feature == "+avx512vbmi") {
3270b57cec5SDimitry Andric       HasAVX512VBMI = true;
3280b57cec5SDimitry Andric     } else if (Feature == "+avx512vbmi2") {
3290b57cec5SDimitry Andric       HasAVX512VBMI2 = true;
3300b57cec5SDimitry Andric     } else if (Feature == "+avx512ifma") {
3310b57cec5SDimitry Andric       HasAVX512IFMA = true;
3320b57cec5SDimitry Andric     } else if (Feature == "+avx512vp2intersect") {
3330b57cec5SDimitry Andric       HasAVX512VP2INTERSECT = true;
3340b57cec5SDimitry Andric     } else if (Feature == "+sha") {
3350b57cec5SDimitry Andric       HasSHA = true;
33606c3fb27SDimitry Andric     } else if (Feature == "+sha512") {
33706c3fb27SDimitry Andric       HasSHA512 = true;
3380b57cec5SDimitry Andric     } else if (Feature == "+shstk") {
3390b57cec5SDimitry Andric       HasSHSTK = true;
34006c3fb27SDimitry Andric     } else if (Feature == "+sm3") {
34106c3fb27SDimitry Andric       HasSM3 = true;
34206c3fb27SDimitry Andric     } else if (Feature == "+sm4") {
34306c3fb27SDimitry Andric       HasSM4 = true;
3440b57cec5SDimitry Andric     } else if (Feature == "+movbe") {
3450b57cec5SDimitry Andric       HasMOVBE = true;
3460b57cec5SDimitry Andric     } else if (Feature == "+sgx") {
3470b57cec5SDimitry Andric       HasSGX = true;
3480b57cec5SDimitry Andric     } else if (Feature == "+cx8") {
3490b57cec5SDimitry Andric       HasCX8 = true;
3500b57cec5SDimitry Andric     } else if (Feature == "+cx16") {
3510b57cec5SDimitry Andric       HasCX16 = true;
3520b57cec5SDimitry Andric     } else if (Feature == "+fxsr") {
3530b57cec5SDimitry Andric       HasFXSR = true;
3540b57cec5SDimitry Andric     } else if (Feature == "+xsave") {
3550b57cec5SDimitry Andric       HasXSAVE = true;
3560b57cec5SDimitry Andric     } else if (Feature == "+xsaveopt") {
3570b57cec5SDimitry Andric       HasXSAVEOPT = true;
3580b57cec5SDimitry Andric     } else if (Feature == "+xsavec") {
3590b57cec5SDimitry Andric       HasXSAVEC = true;
3600b57cec5SDimitry Andric     } else if (Feature == "+xsaves") {
3610b57cec5SDimitry Andric       HasXSAVES = true;
3620b57cec5SDimitry Andric     } else if (Feature == "+mwaitx") {
3630b57cec5SDimitry Andric       HasMWAITX = true;
3640b57cec5SDimitry Andric     } else if (Feature == "+pku") {
3650b57cec5SDimitry Andric       HasPKU = true;
3660b57cec5SDimitry Andric     } else if (Feature == "+clflushopt") {
3670b57cec5SDimitry Andric       HasCLFLUSHOPT = true;
3680b57cec5SDimitry Andric     } else if (Feature == "+clwb") {
3690b57cec5SDimitry Andric       HasCLWB = true;
3700b57cec5SDimitry Andric     } else if (Feature == "+wbnoinvd") {
3710b57cec5SDimitry Andric       HasWBNOINVD = true;
372bdd1243dSDimitry Andric     } else if (Feature == "+prefetchi") {
373bdd1243dSDimitry Andric       HasPREFETCHI = true;
3740b57cec5SDimitry Andric     } else if (Feature == "+clzero") {
3750b57cec5SDimitry Andric       HasCLZERO = true;
3760b57cec5SDimitry Andric     } else if (Feature == "+cldemote") {
3770b57cec5SDimitry Andric       HasCLDEMOTE = true;
3780b57cec5SDimitry Andric     } else if (Feature == "+rdpid") {
3790b57cec5SDimitry Andric       HasRDPID = true;
380753f127fSDimitry Andric     } else if (Feature == "+rdpru") {
381753f127fSDimitry Andric       HasRDPRU = true;
382e8d8bef9SDimitry Andric     } else if (Feature == "+kl") {
383e8d8bef9SDimitry Andric       HasKL = true;
384e8d8bef9SDimitry Andric     } else if (Feature == "+widekl") {
385e8d8bef9SDimitry Andric       HasWIDEKL = true;
3860b57cec5SDimitry Andric     } else if (Feature == "+retpoline-external-thunk") {
3870b57cec5SDimitry Andric       HasRetpolineExternalThunk = true;
3880b57cec5SDimitry Andric     } else if (Feature == "+sahf") {
3890b57cec5SDimitry Andric       HasLAHFSAHF = true;
3900b57cec5SDimitry Andric     } else if (Feature == "+waitpkg") {
3910b57cec5SDimitry Andric       HasWAITPKG = true;
3920b57cec5SDimitry Andric     } else if (Feature == "+movdiri") {
3930b57cec5SDimitry Andric       HasMOVDIRI = true;
3940b57cec5SDimitry Andric     } else if (Feature == "+movdir64b") {
3950b57cec5SDimitry Andric       HasMOVDIR64B = true;
3960b57cec5SDimitry Andric     } else if (Feature == "+pconfig") {
3970b57cec5SDimitry Andric       HasPCONFIG = true;
3980b57cec5SDimitry Andric     } else if (Feature == "+ptwrite") {
3990b57cec5SDimitry Andric       HasPTWRITE = true;
4000b57cec5SDimitry Andric     } else if (Feature == "+invpcid") {
4010b57cec5SDimitry Andric       HasINVPCID = true;
4020b57cec5SDimitry Andric     } else if (Feature == "+enqcmd") {
4030b57cec5SDimitry Andric       HasENQCMD = true;
404e8d8bef9SDimitry Andric     } else if (Feature == "+hreset") {
405e8d8bef9SDimitry Andric       HasHRESET = true;
4065ffd83dbSDimitry Andric     } else if (Feature == "+amx-bf16") {
4075ffd83dbSDimitry Andric       HasAMXBF16 = true;
408bdd1243dSDimitry Andric     } else if (Feature == "+amx-fp16") {
409bdd1243dSDimitry Andric       HasAMXFP16 = true;
4105ffd83dbSDimitry Andric     } else if (Feature == "+amx-int8") {
4115ffd83dbSDimitry Andric       HasAMXINT8 = true;
4125ffd83dbSDimitry Andric     } else if (Feature == "+amx-tile") {
4135ffd83dbSDimitry Andric       HasAMXTILE = true;
41406c3fb27SDimitry Andric     } else if (Feature == "+amx-complex") {
41506c3fb27SDimitry Andric       HasAMXCOMPLEX = true;
416bdd1243dSDimitry Andric     } else if (Feature == "+cmpccxadd") {
417bdd1243dSDimitry Andric       HasCMPCCXADD = true;
418bdd1243dSDimitry Andric     } else if (Feature == "+raoint") {
419bdd1243dSDimitry Andric       HasRAOINT = true;
420bdd1243dSDimitry Andric     } else if (Feature == "+avxifma") {
421bdd1243dSDimitry Andric       HasAVXIFMA = true;
422bdd1243dSDimitry Andric     } else if (Feature == "+avxneconvert") {
423bdd1243dSDimitry Andric       HasAVXNECONVERT= true;
424e8d8bef9SDimitry Andric     } else if (Feature == "+avxvnni") {
425e8d8bef9SDimitry Andric       HasAVXVNNI = true;
42606c3fb27SDimitry Andric     } else if (Feature == "+avxvnniint16") {
42706c3fb27SDimitry Andric       HasAVXVNNIINT16 = true;
428bdd1243dSDimitry Andric     } else if (Feature == "+avxvnniint8") {
429bdd1243dSDimitry Andric       HasAVXVNNIINT8 = true;
4305ffd83dbSDimitry Andric     } else if (Feature == "+serialize") {
4315ffd83dbSDimitry Andric       HasSERIALIZE = true;
4325ffd83dbSDimitry Andric     } else if (Feature == "+tsxldtrk") {
4335ffd83dbSDimitry Andric       HasTSXLDTRK = true;
434e8d8bef9SDimitry Andric     } else if (Feature == "+uintr") {
435e8d8bef9SDimitry Andric       HasUINTR = true;
4365f757f3fSDimitry Andric     } else if (Feature == "+usermsr") {
4375f757f3fSDimitry Andric       HasUSERMSR = true;
438349cc55cSDimitry Andric     } else if (Feature == "+crc32") {
439349cc55cSDimitry Andric       HasCRC32 = true;
440349cc55cSDimitry Andric     } else if (Feature == "+x87") {
441349cc55cSDimitry Andric       HasX87 = true;
44206c3fb27SDimitry Andric     } else if (Feature == "+fullbf16") {
44306c3fb27SDimitry Andric       HasFullBFloat16 = true;
4445f757f3fSDimitry Andric     } else if (Feature == "+egpr") {
4455f757f3fSDimitry Andric       HasEGPR = true;
4460fca6ea1SDimitry Andric     } else if (Feature == "+inline-asm-use-gpr32") {
4470fca6ea1SDimitry Andric       HasInlineAsmUseGPR32 = true;
4485f757f3fSDimitry Andric     } else if (Feature == "+push2pop2") {
4495f757f3fSDimitry Andric       HasPush2Pop2 = true;
4505f757f3fSDimitry Andric     } else if (Feature == "+ppx") {
4515f757f3fSDimitry Andric       HasPPX = true;
4525f757f3fSDimitry Andric     } else if (Feature == "+ndd") {
4535f757f3fSDimitry Andric       HasNDD = true;
4545f757f3fSDimitry Andric     } else if (Feature == "+ccmp") {
4555f757f3fSDimitry Andric       HasCCMP = true;
4560fca6ea1SDimitry Andric     } else if (Feature == "+nf") {
4570fca6ea1SDimitry Andric       HasNF = true;
4585f757f3fSDimitry Andric     } else if (Feature == "+cf") {
4595f757f3fSDimitry Andric       HasCF = true;
4600fca6ea1SDimitry Andric     } else if (Feature == "+zu") {
4610fca6ea1SDimitry Andric       HasZU = true;
4620fca6ea1SDimitry Andric     } else if (Feature == "+branch-hint") {
4630fca6ea1SDimitry Andric       HasBranchHint = true;
4640b57cec5SDimitry Andric     }
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
4670b57cec5SDimitry Andric                            .Case("+avx512f", AVX512F)
4680b57cec5SDimitry Andric                            .Case("+avx2", AVX2)
4690b57cec5SDimitry Andric                            .Case("+avx", AVX)
4700b57cec5SDimitry Andric                            .Case("+sse4.2", SSE42)
4710b57cec5SDimitry Andric                            .Case("+sse4.1", SSE41)
4720b57cec5SDimitry Andric                            .Case("+ssse3", SSSE3)
4730b57cec5SDimitry Andric                            .Case("+sse3", SSE3)
4740b57cec5SDimitry Andric                            .Case("+sse2", SSE2)
4750b57cec5SDimitry Andric                            .Case("+sse", SSE1)
4760b57cec5SDimitry Andric                            .Default(NoSSE);
4770b57cec5SDimitry Andric     SSELevel = std::max(SSELevel, Level);
4780b57cec5SDimitry Andric 
47981ad6265SDimitry Andric     HasFloat16 = SSELevel >= SSE2;
48081ad6265SDimitry Andric 
48106c3fb27SDimitry Andric     // X86 target has bfloat16 emulation support in the backend, where
48206c3fb27SDimitry Andric     // bfloat16 is treated as a 32-bit float, arithmetic operations are
48306c3fb27SDimitry Andric     // performed in 32-bit, and the result is converted back to bfloat16.
48406c3fb27SDimitry Andric     // Truncation and extension between bfloat16 and 32-bit float are supported
48506c3fb27SDimitry Andric     // by the compiler-rt library. However, native bfloat16 support is currently
48606c3fb27SDimitry Andric     // not available in the X86 target. Hence, HasFullBFloat16 will be false
48706c3fb27SDimitry Andric     // until native bfloat16 support is available. HasFullBFloat16 is used to
48806c3fb27SDimitry Andric     // determine whether to automatically use excess floating point precision
48906c3fb27SDimitry Andric     // for bfloat16 arithmetic operations in the front-end.
49061cfbce3SDimitry Andric     HasBFloat16 = SSELevel >= SSE2;
49161cfbce3SDimitry Andric 
4920b57cec5SDimitry Andric     XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
4930b57cec5SDimitry Andric                          .Case("+xop", XOP)
4940b57cec5SDimitry Andric                          .Case("+fma4", FMA4)
4950b57cec5SDimitry Andric                          .Case("+sse4a", SSE4A)
4960b57cec5SDimitry Andric                          .Default(NoXOP);
4970b57cec5SDimitry Andric     XOPLevel = std::max(XOPLevel, XLevel);
4980b57cec5SDimitry Andric   }
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric   // LLVM doesn't have a separate switch for fpmath, so only accept it if it
5010b57cec5SDimitry Andric   // matches the selected sse level.
5020b57cec5SDimitry Andric   if ((FPMath == FP_SSE && SSELevel < SSE1) ||
5030b57cec5SDimitry Andric       (FPMath == FP_387 && SSELevel >= SSE1)) {
5040b57cec5SDimitry Andric     Diags.Report(diag::err_target_unsupported_fpmath)
5050b57cec5SDimitry Andric         << (FPMath == FP_SSE ? "sse" : "387");
5060b57cec5SDimitry Andric     return false;
5070b57cec5SDimitry Andric   }
5080b57cec5SDimitry Andric 
5094824e7fdSDimitry Andric   // FIXME: We should allow long double type on 32-bits to match with GCC.
5104824e7fdSDimitry Andric   // This requires backend to be able to lower f80 without x87 first.
5114824e7fdSDimitry Andric   if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended())
512349cc55cSDimitry Andric     HasLongDouble = false;
513349cc55cSDimitry Andric 
5140b57cec5SDimitry Andric   return true;
5150b57cec5SDimitry Andric }
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
5180b57cec5SDimitry Andric /// definitions for this particular subtarget.
5190b57cec5SDimitry Andric void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
5200b57cec5SDimitry Andric                                      MacroBuilder &Builder) const {
5210b57cec5SDimitry Andric   // Inline assembly supports X86 flag outputs.
5220b57cec5SDimitry Andric   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric   std::string CodeModel = getTargetOpts().CodeModel;
5250b57cec5SDimitry Andric   if (CodeModel == "default")
5260b57cec5SDimitry Andric     CodeModel = "small";
5275ffd83dbSDimitry Andric   Builder.defineMacro("__code_model_" + CodeModel + "__");
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric   // Target identification.
5300b57cec5SDimitry Andric   if (getTriple().getArch() == llvm::Triple::x86_64) {
5310b57cec5SDimitry Andric     Builder.defineMacro("__amd64__");
5320b57cec5SDimitry Andric     Builder.defineMacro("__amd64");
5330b57cec5SDimitry Andric     Builder.defineMacro("__x86_64");
5340b57cec5SDimitry Andric     Builder.defineMacro("__x86_64__");
5350b57cec5SDimitry Andric     if (getTriple().getArchName() == "x86_64h") {
5360b57cec5SDimitry Andric       Builder.defineMacro("__x86_64h");
5370b57cec5SDimitry Andric       Builder.defineMacro("__x86_64h__");
5380b57cec5SDimitry Andric     }
5390b57cec5SDimitry Andric   } else {
5400b57cec5SDimitry Andric     DefineStd(Builder, "i386", Opts);
5410b57cec5SDimitry Andric   }
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric   Builder.defineMacro("__SEG_GS");
5440b57cec5SDimitry Andric   Builder.defineMacro("__SEG_FS");
5450b57cec5SDimitry Andric   Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))");
5460b57cec5SDimitry Andric   Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))");
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric   // Subtarget options.
5490b57cec5SDimitry Andric   // FIXME: We are hard-coding the tune parameters based on the CPU, but they
5500b57cec5SDimitry Andric   // truly should be based on -mtune options.
5515ffd83dbSDimitry Andric   using namespace llvm::X86;
5520b57cec5SDimitry Andric   switch (CPU) {
5535ffd83dbSDimitry Andric   case CK_None:
5540b57cec5SDimitry Andric     break;
5550b57cec5SDimitry Andric   case CK_i386:
5560b57cec5SDimitry Andric     // The rest are coming from the i386 define above.
5570b57cec5SDimitry Andric     Builder.defineMacro("__tune_i386__");
5580b57cec5SDimitry Andric     break;
5590b57cec5SDimitry Andric   case CK_i486:
5600b57cec5SDimitry Andric   case CK_WinChipC6:
5610b57cec5SDimitry Andric   case CK_WinChip2:
5620b57cec5SDimitry Andric   case CK_C3:
5630b57cec5SDimitry Andric     defineCPUMacros(Builder, "i486");
5640b57cec5SDimitry Andric     break;
5650b57cec5SDimitry Andric   case CK_PentiumMMX:
5660b57cec5SDimitry Andric     Builder.defineMacro("__pentium_mmx__");
5670b57cec5SDimitry Andric     Builder.defineMacro("__tune_pentium_mmx__");
568bdd1243dSDimitry Andric     [[fallthrough]];
5690b57cec5SDimitry Andric   case CK_i586:
5700b57cec5SDimitry Andric   case CK_Pentium:
5710b57cec5SDimitry Andric     defineCPUMacros(Builder, "i586");
5720b57cec5SDimitry Andric     defineCPUMacros(Builder, "pentium");
5730b57cec5SDimitry Andric     break;
5740b57cec5SDimitry Andric   case CK_Pentium3:
5750b57cec5SDimitry Andric   case CK_PentiumM:
5760b57cec5SDimitry Andric     Builder.defineMacro("__tune_pentium3__");
577bdd1243dSDimitry Andric     [[fallthrough]];
5780b57cec5SDimitry Andric   case CK_Pentium2:
5790b57cec5SDimitry Andric   case CK_C3_2:
5800b57cec5SDimitry Andric     Builder.defineMacro("__tune_pentium2__");
581bdd1243dSDimitry Andric     [[fallthrough]];
5820b57cec5SDimitry Andric   case CK_PentiumPro:
5830b57cec5SDimitry Andric   case CK_i686:
5840b57cec5SDimitry Andric     defineCPUMacros(Builder, "i686");
5850b57cec5SDimitry Andric     defineCPUMacros(Builder, "pentiumpro");
5860b57cec5SDimitry Andric     break;
5870b57cec5SDimitry Andric   case CK_Pentium4:
5880b57cec5SDimitry Andric     defineCPUMacros(Builder, "pentium4");
5890b57cec5SDimitry Andric     break;
5900b57cec5SDimitry Andric   case CK_Yonah:
5910b57cec5SDimitry Andric   case CK_Prescott:
5920b57cec5SDimitry Andric   case CK_Nocona:
5930b57cec5SDimitry Andric     defineCPUMacros(Builder, "nocona");
5940b57cec5SDimitry Andric     break;
5950b57cec5SDimitry Andric   case CK_Core2:
5960b57cec5SDimitry Andric   case CK_Penryn:
5970b57cec5SDimitry Andric     defineCPUMacros(Builder, "core2");
5980b57cec5SDimitry Andric     break;
5990b57cec5SDimitry Andric   case CK_Bonnell:
6000b57cec5SDimitry Andric     defineCPUMacros(Builder, "atom");
6010b57cec5SDimitry Andric     break;
6020b57cec5SDimitry Andric   case CK_Silvermont:
6030b57cec5SDimitry Andric     defineCPUMacros(Builder, "slm");
6040b57cec5SDimitry Andric     break;
6050b57cec5SDimitry Andric   case CK_Goldmont:
6060b57cec5SDimitry Andric     defineCPUMacros(Builder, "goldmont");
6070b57cec5SDimitry Andric     break;
6080b57cec5SDimitry Andric   case CK_GoldmontPlus:
6090b57cec5SDimitry Andric     defineCPUMacros(Builder, "goldmont_plus");
6100b57cec5SDimitry Andric     break;
6110b57cec5SDimitry Andric   case CK_Tremont:
6120b57cec5SDimitry Andric     defineCPUMacros(Builder, "tremont");
6130b57cec5SDimitry Andric     break;
6145f757f3fSDimitry Andric   // Gracemont and later atom-cores use P-core cpu macros.
6155f757f3fSDimitry Andric   case CK_Gracemont:
6160b57cec5SDimitry Andric   case CK_Nehalem:
6170b57cec5SDimitry Andric   case CK_Westmere:
6180b57cec5SDimitry Andric   case CK_SandyBridge:
6190b57cec5SDimitry Andric   case CK_IvyBridge:
6200b57cec5SDimitry Andric   case CK_Haswell:
6210b57cec5SDimitry Andric   case CK_Broadwell:
6220b57cec5SDimitry Andric   case CK_SkylakeClient:
6230b57cec5SDimitry Andric   case CK_SkylakeServer:
6240b57cec5SDimitry Andric   case CK_Cascadelake:
6250b57cec5SDimitry Andric   case CK_Cooperlake:
6260b57cec5SDimitry Andric   case CK_Cannonlake:
6270b57cec5SDimitry Andric   case CK_IcelakeClient:
628fe6060f1SDimitry Andric   case CK_Rocketlake:
6290b57cec5SDimitry Andric   case CK_IcelakeServer:
630a7dea167SDimitry Andric   case CK_Tigerlake:
631e8d8bef9SDimitry Andric   case CK_SapphireRapids:
632e8d8bef9SDimitry Andric   case CK_Alderlake:
633bdd1243dSDimitry Andric   case CK_Raptorlake:
634bdd1243dSDimitry Andric   case CK_Meteorlake:
6355f757f3fSDimitry Andric   case CK_Arrowlake:
6365f757f3fSDimitry Andric   case CK_ArrowlakeS:
6375f757f3fSDimitry Andric   case CK_Lunarlake:
6385f757f3fSDimitry Andric   case CK_Pantherlake:
639bdd1243dSDimitry Andric   case CK_Sierraforest:
640bdd1243dSDimitry Andric   case CK_Grandridge:
641bdd1243dSDimitry Andric   case CK_Graniterapids:
64206c3fb27SDimitry Andric   case CK_GraniterapidsD:
643bdd1243dSDimitry Andric   case CK_Emeraldrapids:
6445f757f3fSDimitry Andric   case CK_Clearwaterforest:
6450b57cec5SDimitry Andric     // FIXME: Historically, we defined this legacy name, it would be nice to
6460b57cec5SDimitry Andric     // remove it at some point. We've never exposed fine-grained names for
6470b57cec5SDimitry Andric     // recent primary x86 CPUs, and we should keep it that way.
6480b57cec5SDimitry Andric     defineCPUMacros(Builder, "corei7");
6490b57cec5SDimitry Andric     break;
6500b57cec5SDimitry Andric   case CK_KNL:
6510b57cec5SDimitry Andric     defineCPUMacros(Builder, "knl");
6520b57cec5SDimitry Andric     break;
6530b57cec5SDimitry Andric   case CK_KNM:
6540b57cec5SDimitry Andric     break;
6550b57cec5SDimitry Andric   case CK_Lakemont:
6560b57cec5SDimitry Andric     defineCPUMacros(Builder, "i586", /*Tuning*/false);
6570b57cec5SDimitry Andric     defineCPUMacros(Builder, "pentium", /*Tuning*/false);
6580b57cec5SDimitry Andric     Builder.defineMacro("__tune_lakemont__");
6590b57cec5SDimitry Andric     break;
6600b57cec5SDimitry Andric   case CK_K6_2:
6610b57cec5SDimitry Andric     Builder.defineMacro("__k6_2__");
6620b57cec5SDimitry Andric     Builder.defineMacro("__tune_k6_2__");
663bdd1243dSDimitry Andric     [[fallthrough]];
6640b57cec5SDimitry Andric   case CK_K6_3:
6650b57cec5SDimitry Andric     if (CPU != CK_K6_2) { // In case of fallthrough
6660b57cec5SDimitry Andric       // FIXME: GCC may be enabling these in cases where some other k6
6670b57cec5SDimitry Andric       // architecture is specified but -m3dnow is explicitly provided. The
6680b57cec5SDimitry Andric       // exact semantics need to be determined and emulated here.
6690b57cec5SDimitry Andric       Builder.defineMacro("__k6_3__");
6700b57cec5SDimitry Andric       Builder.defineMacro("__tune_k6_3__");
6710b57cec5SDimitry Andric     }
672bdd1243dSDimitry Andric     [[fallthrough]];
6730b57cec5SDimitry Andric   case CK_K6:
6740b57cec5SDimitry Andric     defineCPUMacros(Builder, "k6");
6750b57cec5SDimitry Andric     break;
6760b57cec5SDimitry Andric   case CK_Athlon:
6770b57cec5SDimitry Andric   case CK_AthlonXP:
6780b57cec5SDimitry Andric     defineCPUMacros(Builder, "athlon");
6790b57cec5SDimitry Andric     if (SSELevel != NoSSE) {
6800b57cec5SDimitry Andric       Builder.defineMacro("__athlon_sse__");
6810b57cec5SDimitry Andric       Builder.defineMacro("__tune_athlon_sse__");
6820b57cec5SDimitry Andric     }
6830b57cec5SDimitry Andric     break;
6840b57cec5SDimitry Andric   case CK_K8:
6850b57cec5SDimitry Andric   case CK_K8SSE3:
6860b57cec5SDimitry Andric   case CK_x86_64:
6874652422eSDimitry Andric     defineCPUMacros(Builder, "k8");
6884652422eSDimitry Andric     break;
689e8d8bef9SDimitry Andric   case CK_x86_64_v2:
690e8d8bef9SDimitry Andric   case CK_x86_64_v3:
691e8d8bef9SDimitry Andric   case CK_x86_64_v4:
6920b57cec5SDimitry Andric     break;
6930b57cec5SDimitry Andric   case CK_AMDFAM10:
6940b57cec5SDimitry Andric     defineCPUMacros(Builder, "amdfam10");
6950b57cec5SDimitry Andric     break;
6960b57cec5SDimitry Andric   case CK_BTVER1:
6970b57cec5SDimitry Andric     defineCPUMacros(Builder, "btver1");
6980b57cec5SDimitry Andric     break;
6990b57cec5SDimitry Andric   case CK_BTVER2:
7000b57cec5SDimitry Andric     defineCPUMacros(Builder, "btver2");
7010b57cec5SDimitry Andric     break;
7020b57cec5SDimitry Andric   case CK_BDVER1:
7030b57cec5SDimitry Andric     defineCPUMacros(Builder, "bdver1");
7040b57cec5SDimitry Andric     break;
7050b57cec5SDimitry Andric   case CK_BDVER2:
7060b57cec5SDimitry Andric     defineCPUMacros(Builder, "bdver2");
7070b57cec5SDimitry Andric     break;
7080b57cec5SDimitry Andric   case CK_BDVER3:
7090b57cec5SDimitry Andric     defineCPUMacros(Builder, "bdver3");
7100b57cec5SDimitry Andric     break;
7110b57cec5SDimitry Andric   case CK_BDVER4:
7120b57cec5SDimitry Andric     defineCPUMacros(Builder, "bdver4");
7130b57cec5SDimitry Andric     break;
7140b57cec5SDimitry Andric   case CK_ZNVER1:
7150b57cec5SDimitry Andric     defineCPUMacros(Builder, "znver1");
7160b57cec5SDimitry Andric     break;
7170b57cec5SDimitry Andric   case CK_ZNVER2:
7180b57cec5SDimitry Andric     defineCPUMacros(Builder, "znver2");
7190b57cec5SDimitry Andric     break;
720e8d8bef9SDimitry Andric   case CK_ZNVER3:
721e8d8bef9SDimitry Andric     defineCPUMacros(Builder, "znver3");
722e8d8bef9SDimitry Andric     break;
723bdd1243dSDimitry Andric   case CK_ZNVER4:
724bdd1243dSDimitry Andric     defineCPUMacros(Builder, "znver4");
725bdd1243dSDimitry Andric     break;
726*c80e69b0SDimitry Andric   case CK_ZNVER5:
727*c80e69b0SDimitry Andric     defineCPUMacros(Builder, "znver5");
728*c80e69b0SDimitry Andric     break;
7290b57cec5SDimitry Andric   case CK_Geode:
7300b57cec5SDimitry Andric     defineCPUMacros(Builder, "geode");
7310b57cec5SDimitry Andric     break;
7320b57cec5SDimitry Andric   }
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric   // Target properties.
7350b57cec5SDimitry Andric   Builder.defineMacro("__REGISTER_PREFIX__", "");
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
7380b57cec5SDimitry Andric   // functions in glibc header files that use FP Stack inline asm which the
7390b57cec5SDimitry Andric   // backend can't deal with (PR879).
7400b57cec5SDimitry Andric   Builder.defineMacro("__NO_MATH_INLINES");
7410b57cec5SDimitry Andric 
7420b57cec5SDimitry Andric   if (HasAES)
7430b57cec5SDimitry Andric     Builder.defineMacro("__AES__");
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric   if (HasVAES)
7460b57cec5SDimitry Andric     Builder.defineMacro("__VAES__");
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric   if (HasPCLMUL)
7490b57cec5SDimitry Andric     Builder.defineMacro("__PCLMUL__");
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric   if (HasVPCLMULQDQ)
7520b57cec5SDimitry Andric     Builder.defineMacro("__VPCLMULQDQ__");
7530b57cec5SDimitry Andric 
754e8d8bef9SDimitry Andric   // Note, in 32-bit mode, GCC does not define the macro if -mno-sahf. In LLVM,
755e8d8bef9SDimitry Andric   // the feature flag only applies to 64-bit mode.
756e8d8bef9SDimitry Andric   if (HasLAHFSAHF || getTriple().getArch() == llvm::Triple::x86)
757e8d8bef9SDimitry Andric     Builder.defineMacro("__LAHF_SAHF__");
758e8d8bef9SDimitry Andric 
7590b57cec5SDimitry Andric   if (HasLZCNT)
7600b57cec5SDimitry Andric     Builder.defineMacro("__LZCNT__");
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric   if (HasRDRND)
7630b57cec5SDimitry Andric     Builder.defineMacro("__RDRND__");
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric   if (HasFSGSBASE)
7660b57cec5SDimitry Andric     Builder.defineMacro("__FSGSBASE__");
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric   if (HasBMI)
7690b57cec5SDimitry Andric     Builder.defineMacro("__BMI__");
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   if (HasBMI2)
7720b57cec5SDimitry Andric     Builder.defineMacro("__BMI2__");
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric   if (HasPOPCNT)
7750b57cec5SDimitry Andric     Builder.defineMacro("__POPCNT__");
7760b57cec5SDimitry Andric 
7770b57cec5SDimitry Andric   if (HasRTM)
7780b57cec5SDimitry Andric     Builder.defineMacro("__RTM__");
7790b57cec5SDimitry Andric 
7800b57cec5SDimitry Andric   if (HasPRFCHW)
7810b57cec5SDimitry Andric     Builder.defineMacro("__PRFCHW__");
7820b57cec5SDimitry Andric 
7830b57cec5SDimitry Andric   if (HasRDSEED)
7840b57cec5SDimitry Andric     Builder.defineMacro("__RDSEED__");
7850b57cec5SDimitry Andric 
7860b57cec5SDimitry Andric   if (HasADX)
7870b57cec5SDimitry Andric     Builder.defineMacro("__ADX__");
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric   if (HasTBM)
7900b57cec5SDimitry Andric     Builder.defineMacro("__TBM__");
7910b57cec5SDimitry Andric 
7920b57cec5SDimitry Andric   if (HasLWP)
7930b57cec5SDimitry Andric     Builder.defineMacro("__LWP__");
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric   if (HasMWAITX)
7960b57cec5SDimitry Andric     Builder.defineMacro("__MWAITX__");
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric   if (HasMOVBE)
7990b57cec5SDimitry Andric     Builder.defineMacro("__MOVBE__");
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric   switch (XOPLevel) {
8020b57cec5SDimitry Andric   case XOP:
8030b57cec5SDimitry Andric     Builder.defineMacro("__XOP__");
804bdd1243dSDimitry Andric     [[fallthrough]];
8050b57cec5SDimitry Andric   case FMA4:
8060b57cec5SDimitry Andric     Builder.defineMacro("__FMA4__");
807bdd1243dSDimitry Andric     [[fallthrough]];
8080b57cec5SDimitry Andric   case SSE4A:
8090b57cec5SDimitry Andric     Builder.defineMacro("__SSE4A__");
810bdd1243dSDimitry Andric     [[fallthrough]];
8110b57cec5SDimitry Andric   case NoXOP:
8120b57cec5SDimitry Andric     break;
8130b57cec5SDimitry Andric   }
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric   if (HasFMA)
8160b57cec5SDimitry Andric     Builder.defineMacro("__FMA__");
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric   if (HasF16C)
8190b57cec5SDimitry Andric     Builder.defineMacro("__F16C__");
8200b57cec5SDimitry Andric 
8210b57cec5SDimitry Andric   if (HasGFNI)
8220b57cec5SDimitry Andric     Builder.defineMacro("__GFNI__");
8230b57cec5SDimitry Andric 
8245f757f3fSDimitry Andric   if (HasEVEX512)
8255f757f3fSDimitry Andric     Builder.defineMacro("__EVEX512__");
8265f757f3fSDimitry Andric   if (HasAVX10_1)
8275f757f3fSDimitry Andric     Builder.defineMacro("__AVX10_1__");
8285f757f3fSDimitry Andric   if (HasAVX10_1_512)
8295f757f3fSDimitry Andric     Builder.defineMacro("__AVX10_1_512__");
8300b57cec5SDimitry Andric   if (HasAVX512CD)
8310b57cec5SDimitry Andric     Builder.defineMacro("__AVX512CD__");
8320b57cec5SDimitry Andric   if (HasAVX512VPOPCNTDQ)
8330b57cec5SDimitry Andric     Builder.defineMacro("__AVX512VPOPCNTDQ__");
8340b57cec5SDimitry Andric   if (HasAVX512VNNI)
8350b57cec5SDimitry Andric     Builder.defineMacro("__AVX512VNNI__");
8360b57cec5SDimitry Andric   if (HasAVX512BF16)
8370b57cec5SDimitry Andric     Builder.defineMacro("__AVX512BF16__");
838349cc55cSDimitry Andric   if (HasAVX512FP16)
839349cc55cSDimitry Andric     Builder.defineMacro("__AVX512FP16__");
8400b57cec5SDimitry Andric   if (HasAVX512DQ)
8410b57cec5SDimitry Andric     Builder.defineMacro("__AVX512DQ__");
8420b57cec5SDimitry Andric   if (HasAVX512BITALG)
8430b57cec5SDimitry Andric     Builder.defineMacro("__AVX512BITALG__");
8440b57cec5SDimitry Andric   if (HasAVX512BW)
8450b57cec5SDimitry Andric     Builder.defineMacro("__AVX512BW__");
8465f757f3fSDimitry Andric   if (HasAVX512VL) {
8470b57cec5SDimitry Andric     Builder.defineMacro("__AVX512VL__");
8485f757f3fSDimitry Andric     Builder.defineMacro("__EVEX256__");
8495f757f3fSDimitry Andric   }
8500b57cec5SDimitry Andric   if (HasAVX512VBMI)
8510b57cec5SDimitry Andric     Builder.defineMacro("__AVX512VBMI__");
8520b57cec5SDimitry Andric   if (HasAVX512VBMI2)
8530b57cec5SDimitry Andric     Builder.defineMacro("__AVX512VBMI2__");
8540b57cec5SDimitry Andric   if (HasAVX512IFMA)
8550b57cec5SDimitry Andric     Builder.defineMacro("__AVX512IFMA__");
8560b57cec5SDimitry Andric   if (HasAVX512VP2INTERSECT)
8570b57cec5SDimitry Andric     Builder.defineMacro("__AVX512VP2INTERSECT__");
8580b57cec5SDimitry Andric   if (HasSHA)
8590b57cec5SDimitry Andric     Builder.defineMacro("__SHA__");
86006c3fb27SDimitry Andric   if (HasSHA512)
86106c3fb27SDimitry Andric     Builder.defineMacro("__SHA512__");
8620b57cec5SDimitry Andric 
8630b57cec5SDimitry Andric   if (HasFXSR)
8640b57cec5SDimitry Andric     Builder.defineMacro("__FXSR__");
8650b57cec5SDimitry Andric   if (HasXSAVE)
8660b57cec5SDimitry Andric     Builder.defineMacro("__XSAVE__");
8670b57cec5SDimitry Andric   if (HasXSAVEOPT)
8680b57cec5SDimitry Andric     Builder.defineMacro("__XSAVEOPT__");
8690b57cec5SDimitry Andric   if (HasXSAVEC)
8700b57cec5SDimitry Andric     Builder.defineMacro("__XSAVEC__");
8710b57cec5SDimitry Andric   if (HasXSAVES)
8720b57cec5SDimitry Andric     Builder.defineMacro("__XSAVES__");
8730b57cec5SDimitry Andric   if (HasPKU)
8740b57cec5SDimitry Andric     Builder.defineMacro("__PKU__");
8750b57cec5SDimitry Andric   if (HasCLFLUSHOPT)
8760b57cec5SDimitry Andric     Builder.defineMacro("__CLFLUSHOPT__");
8770b57cec5SDimitry Andric   if (HasCLWB)
8780b57cec5SDimitry Andric     Builder.defineMacro("__CLWB__");
8790b57cec5SDimitry Andric   if (HasWBNOINVD)
8800b57cec5SDimitry Andric     Builder.defineMacro("__WBNOINVD__");
8810b57cec5SDimitry Andric   if (HasSHSTK)
8820b57cec5SDimitry Andric     Builder.defineMacro("__SHSTK__");
8830b57cec5SDimitry Andric   if (HasSGX)
8840b57cec5SDimitry Andric     Builder.defineMacro("__SGX__");
88506c3fb27SDimitry Andric   if (HasSM3)
88606c3fb27SDimitry Andric     Builder.defineMacro("__SM3__");
88706c3fb27SDimitry Andric   if (HasSM4)
88806c3fb27SDimitry Andric     Builder.defineMacro("__SM4__");
889bdd1243dSDimitry Andric   if (HasPREFETCHI)
890bdd1243dSDimitry Andric     Builder.defineMacro("__PREFETCHI__");
8910b57cec5SDimitry Andric   if (HasCLZERO)
8920b57cec5SDimitry Andric     Builder.defineMacro("__CLZERO__");
893e8d8bef9SDimitry Andric   if (HasKL)
894e8d8bef9SDimitry Andric     Builder.defineMacro("__KL__");
895e8d8bef9SDimitry Andric   if (HasWIDEKL)
896e8d8bef9SDimitry Andric     Builder.defineMacro("__WIDEKL__");
8970b57cec5SDimitry Andric   if (HasRDPID)
8980b57cec5SDimitry Andric     Builder.defineMacro("__RDPID__");
899753f127fSDimitry Andric   if (HasRDPRU)
900753f127fSDimitry Andric     Builder.defineMacro("__RDPRU__");
9010b57cec5SDimitry Andric   if (HasCLDEMOTE)
9020b57cec5SDimitry Andric     Builder.defineMacro("__CLDEMOTE__");
9030b57cec5SDimitry Andric   if (HasWAITPKG)
9040b57cec5SDimitry Andric     Builder.defineMacro("__WAITPKG__");
9050b57cec5SDimitry Andric   if (HasMOVDIRI)
9060b57cec5SDimitry Andric     Builder.defineMacro("__MOVDIRI__");
9070b57cec5SDimitry Andric   if (HasMOVDIR64B)
9080b57cec5SDimitry Andric     Builder.defineMacro("__MOVDIR64B__");
9090b57cec5SDimitry Andric   if (HasPCONFIG)
9100b57cec5SDimitry Andric     Builder.defineMacro("__PCONFIG__");
9110b57cec5SDimitry Andric   if (HasPTWRITE)
9120b57cec5SDimitry Andric     Builder.defineMacro("__PTWRITE__");
9130b57cec5SDimitry Andric   if (HasINVPCID)
9140b57cec5SDimitry Andric     Builder.defineMacro("__INVPCID__");
9150b57cec5SDimitry Andric   if (HasENQCMD)
9160b57cec5SDimitry Andric     Builder.defineMacro("__ENQCMD__");
917e8d8bef9SDimitry Andric   if (HasHRESET)
918e8d8bef9SDimitry Andric     Builder.defineMacro("__HRESET__");
9195ffd83dbSDimitry Andric   if (HasAMXTILE)
9201ac55f4cSDimitry Andric     Builder.defineMacro("__AMX_TILE__");
9215ffd83dbSDimitry Andric   if (HasAMXINT8)
9221ac55f4cSDimitry Andric     Builder.defineMacro("__AMX_INT8__");
9235ffd83dbSDimitry Andric   if (HasAMXBF16)
9241ac55f4cSDimitry Andric     Builder.defineMacro("__AMX_BF16__");
925bdd1243dSDimitry Andric   if (HasAMXFP16)
9261ac55f4cSDimitry Andric     Builder.defineMacro("__AMX_FP16__");
92706c3fb27SDimitry Andric   if (HasAMXCOMPLEX)
92806c3fb27SDimitry Andric     Builder.defineMacro("__AMX_COMPLEX__");
929bdd1243dSDimitry Andric   if (HasCMPCCXADD)
930bdd1243dSDimitry Andric     Builder.defineMacro("__CMPCCXADD__");
931bdd1243dSDimitry Andric   if (HasRAOINT)
932bdd1243dSDimitry Andric     Builder.defineMacro("__RAOINT__");
933bdd1243dSDimitry Andric   if (HasAVXIFMA)
934bdd1243dSDimitry Andric     Builder.defineMacro("__AVXIFMA__");
935bdd1243dSDimitry Andric   if (HasAVXNECONVERT)
936bdd1243dSDimitry Andric     Builder.defineMacro("__AVXNECONVERT__");
937e8d8bef9SDimitry Andric   if (HasAVXVNNI)
938e8d8bef9SDimitry Andric     Builder.defineMacro("__AVXVNNI__");
93906c3fb27SDimitry Andric   if (HasAVXVNNIINT16)
94006c3fb27SDimitry Andric     Builder.defineMacro("__AVXVNNIINT16__");
941bdd1243dSDimitry Andric   if (HasAVXVNNIINT8)
942bdd1243dSDimitry Andric     Builder.defineMacro("__AVXVNNIINT8__");
9435ffd83dbSDimitry Andric   if (HasSERIALIZE)
9445ffd83dbSDimitry Andric     Builder.defineMacro("__SERIALIZE__");
9455ffd83dbSDimitry Andric   if (HasTSXLDTRK)
9465ffd83dbSDimitry Andric     Builder.defineMacro("__TSXLDTRK__");
947e8d8bef9SDimitry Andric   if (HasUINTR)
948e8d8bef9SDimitry Andric     Builder.defineMacro("__UINTR__");
9495f757f3fSDimitry Andric   if (HasUSERMSR)
9505f757f3fSDimitry Andric     Builder.defineMacro("__USERMSR__");
951349cc55cSDimitry Andric   if (HasCRC32)
952349cc55cSDimitry Andric     Builder.defineMacro("__CRC32__");
9535f757f3fSDimitry Andric   if (HasEGPR)
9545f757f3fSDimitry Andric     Builder.defineMacro("__EGPR__");
9555f757f3fSDimitry Andric   if (HasPush2Pop2)
9565f757f3fSDimitry Andric     Builder.defineMacro("__PUSH2POP2__");
9575f757f3fSDimitry Andric   if (HasPPX)
9585f757f3fSDimitry Andric     Builder.defineMacro("__PPX__");
9595f757f3fSDimitry Andric   if (HasNDD)
9605f757f3fSDimitry Andric     Builder.defineMacro("__NDD__");
9615f757f3fSDimitry Andric   if (HasCCMP)
9625f757f3fSDimitry Andric     Builder.defineMacro("__CCMP__");
9630fca6ea1SDimitry Andric   if (HasNF)
9640fca6ea1SDimitry Andric     Builder.defineMacro("__NF__");
9655f757f3fSDimitry Andric   if (HasCF)
9665f757f3fSDimitry Andric     Builder.defineMacro("__CF__");
9670fca6ea1SDimitry Andric   if (HasZU)
9680fca6ea1SDimitry Andric     Builder.defineMacro("__ZU__");
9690fca6ea1SDimitry Andric   if (HasEGPR && HasPush2Pop2 && HasPPX && HasNDD && HasCCMP && HasNF &&
9700fca6ea1SDimitry Andric       HasCF && HasZU)
9710fca6ea1SDimitry Andric     Builder.defineMacro("__APX_F__");
9720fca6ea1SDimitry Andric   if (HasEGPR && HasInlineAsmUseGPR32)
9730fca6ea1SDimitry Andric     Builder.defineMacro("__APX_INLINE_ASM_USE_GPR32__");
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric   // Each case falls through to the previous one here.
9760b57cec5SDimitry Andric   switch (SSELevel) {
9770b57cec5SDimitry Andric   case AVX512F:
9780b57cec5SDimitry Andric     Builder.defineMacro("__AVX512F__");
979bdd1243dSDimitry Andric     [[fallthrough]];
9800b57cec5SDimitry Andric   case AVX2:
9810b57cec5SDimitry Andric     Builder.defineMacro("__AVX2__");
982bdd1243dSDimitry Andric     [[fallthrough]];
9830b57cec5SDimitry Andric   case AVX:
9840b57cec5SDimitry Andric     Builder.defineMacro("__AVX__");
985bdd1243dSDimitry Andric     [[fallthrough]];
9860b57cec5SDimitry Andric   case SSE42:
9870b57cec5SDimitry Andric     Builder.defineMacro("__SSE4_2__");
988bdd1243dSDimitry Andric     [[fallthrough]];
9890b57cec5SDimitry Andric   case SSE41:
9900b57cec5SDimitry Andric     Builder.defineMacro("__SSE4_1__");
991bdd1243dSDimitry Andric     [[fallthrough]];
9920b57cec5SDimitry Andric   case SSSE3:
9930b57cec5SDimitry Andric     Builder.defineMacro("__SSSE3__");
994bdd1243dSDimitry Andric     [[fallthrough]];
9950b57cec5SDimitry Andric   case SSE3:
9960b57cec5SDimitry Andric     Builder.defineMacro("__SSE3__");
997bdd1243dSDimitry Andric     [[fallthrough]];
9980b57cec5SDimitry Andric   case SSE2:
9990b57cec5SDimitry Andric     Builder.defineMacro("__SSE2__");
10000b57cec5SDimitry Andric     Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
1001bdd1243dSDimitry Andric     [[fallthrough]];
10020b57cec5SDimitry Andric   case SSE1:
10030b57cec5SDimitry Andric     Builder.defineMacro("__SSE__");
10040b57cec5SDimitry Andric     Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
1005bdd1243dSDimitry Andric     [[fallthrough]];
10060b57cec5SDimitry Andric   case NoSSE:
10070b57cec5SDimitry Andric     break;
10080b57cec5SDimitry Andric   }
10090b57cec5SDimitry Andric 
10100b57cec5SDimitry Andric   if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
10110b57cec5SDimitry Andric     switch (SSELevel) {
10120b57cec5SDimitry Andric     case AVX512F:
10130b57cec5SDimitry Andric     case AVX2:
10140b57cec5SDimitry Andric     case AVX:
10150b57cec5SDimitry Andric     case SSE42:
10160b57cec5SDimitry Andric     case SSE41:
10170b57cec5SDimitry Andric     case SSSE3:
10180b57cec5SDimitry Andric     case SSE3:
10190b57cec5SDimitry Andric     case SSE2:
10200b57cec5SDimitry Andric       Builder.defineMacro("_M_IX86_FP", Twine(2));
10210b57cec5SDimitry Andric       break;
10220b57cec5SDimitry Andric     case SSE1:
10230b57cec5SDimitry Andric       Builder.defineMacro("_M_IX86_FP", Twine(1));
10240b57cec5SDimitry Andric       break;
10250b57cec5SDimitry Andric     default:
10260b57cec5SDimitry Andric       Builder.defineMacro("_M_IX86_FP", Twine(0));
10270b57cec5SDimitry Andric       break;
10280b57cec5SDimitry Andric     }
10290b57cec5SDimitry Andric   }
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric   // Each case falls through to the previous one here.
10320fca6ea1SDimitry Andric   if (HasMMX) {
10330b57cec5SDimitry Andric     Builder.defineMacro("__MMX__");
10340b57cec5SDimitry Andric   }
10350b57cec5SDimitry Andric 
10365ffd83dbSDimitry Andric   if (CPU >= CK_i486 || CPU == CK_None) {
10370b57cec5SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
10380b57cec5SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
10390b57cec5SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
10400b57cec5SDimitry Andric   }
10410b57cec5SDimitry Andric   if (HasCX8)
10420b57cec5SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
10430b57cec5SDimitry Andric   if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)
10440b57cec5SDimitry Andric     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
10450b57cec5SDimitry Andric 
10460b57cec5SDimitry Andric   if (HasFloat128)
10470b57cec5SDimitry Andric     Builder.defineMacro("__SIZEOF_FLOAT128__", "16");
10480b57cec5SDimitry Andric }
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
10510b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(Name)
10520b57cec5SDimitry Andric       .Case("adx", true)
10530b57cec5SDimitry Andric       .Case("aes", true)
10545ffd83dbSDimitry Andric       .Case("amx-bf16", true)
105506c3fb27SDimitry Andric       .Case("amx-complex", true)
1056bdd1243dSDimitry Andric       .Case("amx-fp16", true)
10575ffd83dbSDimitry Andric       .Case("amx-int8", true)
10585ffd83dbSDimitry Andric       .Case("amx-tile", true)
10590b57cec5SDimitry Andric       .Case("avx", true)
10605f757f3fSDimitry Andric       .Case("avx10.1-256", true)
10615f757f3fSDimitry Andric       .Case("avx10.1-512", true)
10620b57cec5SDimitry Andric       .Case("avx2", true)
10630b57cec5SDimitry Andric       .Case("avx512f", true)
10640b57cec5SDimitry Andric       .Case("avx512cd", true)
10650b57cec5SDimitry Andric       .Case("avx512vpopcntdq", true)
10660b57cec5SDimitry Andric       .Case("avx512vnni", true)
10670b57cec5SDimitry Andric       .Case("avx512bf16", true)
1068349cc55cSDimitry Andric       .Case("avx512fp16", true)
10690b57cec5SDimitry Andric       .Case("avx512dq", true)
10700b57cec5SDimitry Andric       .Case("avx512bitalg", true)
10710b57cec5SDimitry Andric       .Case("avx512bw", true)
10720b57cec5SDimitry Andric       .Case("avx512vl", true)
10730b57cec5SDimitry Andric       .Case("avx512vbmi", true)
10740b57cec5SDimitry Andric       .Case("avx512vbmi2", true)
10750b57cec5SDimitry Andric       .Case("avx512ifma", true)
10760b57cec5SDimitry Andric       .Case("avx512vp2intersect", true)
1077bdd1243dSDimitry Andric       .Case("avxifma", true)
1078bdd1243dSDimitry Andric       .Case("avxneconvert", true)
1079e8d8bef9SDimitry Andric       .Case("avxvnni", true)
108006c3fb27SDimitry Andric       .Case("avxvnniint16", true)
1081bdd1243dSDimitry Andric       .Case("avxvnniint8", true)
10820b57cec5SDimitry Andric       .Case("bmi", true)
10830b57cec5SDimitry Andric       .Case("bmi2", true)
10840b57cec5SDimitry Andric       .Case("cldemote", true)
10850b57cec5SDimitry Andric       .Case("clflushopt", true)
10860b57cec5SDimitry Andric       .Case("clwb", true)
10870b57cec5SDimitry Andric       .Case("clzero", true)
1088bdd1243dSDimitry Andric       .Case("cmpccxadd", true)
1089349cc55cSDimitry Andric       .Case("crc32", true)
10900b57cec5SDimitry Andric       .Case("cx16", true)
10910b57cec5SDimitry Andric       .Case("enqcmd", true)
10925f757f3fSDimitry Andric       .Case("evex512", true)
10930b57cec5SDimitry Andric       .Case("f16c", true)
10940b57cec5SDimitry Andric       .Case("fma", true)
10950b57cec5SDimitry Andric       .Case("fma4", true)
10960b57cec5SDimitry Andric       .Case("fsgsbase", true)
10970b57cec5SDimitry Andric       .Case("fxsr", true)
1098fe6060f1SDimitry Andric       .Case("general-regs-only", true)
10990b57cec5SDimitry Andric       .Case("gfni", true)
1100e8d8bef9SDimitry Andric       .Case("hreset", true)
11010b57cec5SDimitry Andric       .Case("invpcid", true)
1102e8d8bef9SDimitry Andric       .Case("kl", true)
1103e8d8bef9SDimitry Andric       .Case("widekl", true)
11040b57cec5SDimitry Andric       .Case("lwp", true)
11050b57cec5SDimitry Andric       .Case("lzcnt", true)
11060b57cec5SDimitry Andric       .Case("mmx", true)
11070b57cec5SDimitry Andric       .Case("movbe", true)
11080b57cec5SDimitry Andric       .Case("movdiri", true)
11090b57cec5SDimitry Andric       .Case("movdir64b", true)
11100b57cec5SDimitry Andric       .Case("mwaitx", true)
11110b57cec5SDimitry Andric       .Case("pclmul", true)
11120b57cec5SDimitry Andric       .Case("pconfig", true)
11130b57cec5SDimitry Andric       .Case("pku", true)
11140b57cec5SDimitry Andric       .Case("popcnt", true)
1115bdd1243dSDimitry Andric       .Case("prefetchi", true)
11160b57cec5SDimitry Andric       .Case("prfchw", true)
11170b57cec5SDimitry Andric       .Case("ptwrite", true)
1118bdd1243dSDimitry Andric       .Case("raoint", true)
11190b57cec5SDimitry Andric       .Case("rdpid", true)
1120753f127fSDimitry Andric       .Case("rdpru", true)
11210b57cec5SDimitry Andric       .Case("rdrnd", true)
11220b57cec5SDimitry Andric       .Case("rdseed", true)
11230b57cec5SDimitry Andric       .Case("rtm", true)
11240b57cec5SDimitry Andric       .Case("sahf", true)
11255ffd83dbSDimitry Andric       .Case("serialize", true)
11260b57cec5SDimitry Andric       .Case("sgx", true)
11270b57cec5SDimitry Andric       .Case("sha", true)
112806c3fb27SDimitry Andric       .Case("sha512", true)
11290b57cec5SDimitry Andric       .Case("shstk", true)
113006c3fb27SDimitry Andric       .Case("sm3", true)
113106c3fb27SDimitry Andric       .Case("sm4", true)
11320b57cec5SDimitry Andric       .Case("sse", true)
11330b57cec5SDimitry Andric       .Case("sse2", true)
11340b57cec5SDimitry Andric       .Case("sse3", true)
11350b57cec5SDimitry Andric       .Case("ssse3", true)
11360b57cec5SDimitry Andric       .Case("sse4", true)
11370b57cec5SDimitry Andric       .Case("sse4.1", true)
11380b57cec5SDimitry Andric       .Case("sse4.2", true)
11390b57cec5SDimitry Andric       .Case("sse4a", true)
11400b57cec5SDimitry Andric       .Case("tbm", true)
11415ffd83dbSDimitry Andric       .Case("tsxldtrk", true)
1142e8d8bef9SDimitry Andric       .Case("uintr", true)
11435f757f3fSDimitry Andric       .Case("usermsr", true)
11440b57cec5SDimitry Andric       .Case("vaes", true)
11450b57cec5SDimitry Andric       .Case("vpclmulqdq", true)
11460b57cec5SDimitry Andric       .Case("wbnoinvd", true)
11470b57cec5SDimitry Andric       .Case("waitpkg", true)
11480b57cec5SDimitry Andric       .Case("x87", true)
11490b57cec5SDimitry Andric       .Case("xop", true)
11500b57cec5SDimitry Andric       .Case("xsave", true)
11510b57cec5SDimitry Andric       .Case("xsavec", true)
11520b57cec5SDimitry Andric       .Case("xsaves", true)
11530b57cec5SDimitry Andric       .Case("xsaveopt", true)
11545f757f3fSDimitry Andric       .Case("egpr", true)
11555f757f3fSDimitry Andric       .Case("push2pop2", true)
11565f757f3fSDimitry Andric       .Case("ppx", true)
11575f757f3fSDimitry Andric       .Case("ndd", true)
11585f757f3fSDimitry Andric       .Case("ccmp", true)
11590fca6ea1SDimitry Andric       .Case("nf", true)
11605f757f3fSDimitry Andric       .Case("cf", true)
11610fca6ea1SDimitry Andric       .Case("zu", true)
11620b57cec5SDimitry Andric       .Default(false);
11630b57cec5SDimitry Andric }
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric bool X86TargetInfo::hasFeature(StringRef Feature) const {
11660b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(Feature)
11670b57cec5SDimitry Andric       .Case("adx", HasADX)
11680b57cec5SDimitry Andric       .Case("aes", HasAES)
11695ffd83dbSDimitry Andric       .Case("amx-bf16", HasAMXBF16)
117006c3fb27SDimitry Andric       .Case("amx-complex", HasAMXCOMPLEX)
1171bdd1243dSDimitry Andric       .Case("amx-fp16", HasAMXFP16)
11725ffd83dbSDimitry Andric       .Case("amx-int8", HasAMXINT8)
11735ffd83dbSDimitry Andric       .Case("amx-tile", HasAMXTILE)
11740b57cec5SDimitry Andric       .Case("avx", SSELevel >= AVX)
11755f757f3fSDimitry Andric       .Case("avx10.1-256", HasAVX10_1)
11765f757f3fSDimitry Andric       .Case("avx10.1-512", HasAVX10_1_512)
11770b57cec5SDimitry Andric       .Case("avx2", SSELevel >= AVX2)
11780b57cec5SDimitry Andric       .Case("avx512f", SSELevel >= AVX512F)
11790b57cec5SDimitry Andric       .Case("avx512cd", HasAVX512CD)
11800b57cec5SDimitry Andric       .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ)
11810b57cec5SDimitry Andric       .Case("avx512vnni", HasAVX512VNNI)
11820b57cec5SDimitry Andric       .Case("avx512bf16", HasAVX512BF16)
1183349cc55cSDimitry Andric       .Case("avx512fp16", HasAVX512FP16)
11840b57cec5SDimitry Andric       .Case("avx512dq", HasAVX512DQ)
11850b57cec5SDimitry Andric       .Case("avx512bitalg", HasAVX512BITALG)
11860b57cec5SDimitry Andric       .Case("avx512bw", HasAVX512BW)
11870b57cec5SDimitry Andric       .Case("avx512vl", HasAVX512VL)
11880b57cec5SDimitry Andric       .Case("avx512vbmi", HasAVX512VBMI)
11890b57cec5SDimitry Andric       .Case("avx512vbmi2", HasAVX512VBMI2)
11900b57cec5SDimitry Andric       .Case("avx512ifma", HasAVX512IFMA)
11910b57cec5SDimitry Andric       .Case("avx512vp2intersect", HasAVX512VP2INTERSECT)
1192bdd1243dSDimitry Andric       .Case("avxifma", HasAVXIFMA)
1193bdd1243dSDimitry Andric       .Case("avxneconvert", HasAVXNECONVERT)
1194bdd1243dSDimitry Andric       .Case("avxvnni", HasAVXVNNI)
119506c3fb27SDimitry Andric       .Case("avxvnniint16", HasAVXVNNIINT16)
1196bdd1243dSDimitry Andric       .Case("avxvnniint8", HasAVXVNNIINT8)
11970b57cec5SDimitry Andric       .Case("bmi", HasBMI)
11980b57cec5SDimitry Andric       .Case("bmi2", HasBMI2)
11990b57cec5SDimitry Andric       .Case("cldemote", HasCLDEMOTE)
12000b57cec5SDimitry Andric       .Case("clflushopt", HasCLFLUSHOPT)
12010b57cec5SDimitry Andric       .Case("clwb", HasCLWB)
12020b57cec5SDimitry Andric       .Case("clzero", HasCLZERO)
1203bdd1243dSDimitry Andric       .Case("cmpccxadd", HasCMPCCXADD)
1204349cc55cSDimitry Andric       .Case("crc32", HasCRC32)
12050b57cec5SDimitry Andric       .Case("cx8", HasCX8)
12060b57cec5SDimitry Andric       .Case("cx16", HasCX16)
12070b57cec5SDimitry Andric       .Case("enqcmd", HasENQCMD)
12085f757f3fSDimitry Andric       .Case("evex512", HasEVEX512)
12090b57cec5SDimitry Andric       .Case("f16c", HasF16C)
12100b57cec5SDimitry Andric       .Case("fma", HasFMA)
12110b57cec5SDimitry Andric       .Case("fma4", XOPLevel >= FMA4)
12120b57cec5SDimitry Andric       .Case("fsgsbase", HasFSGSBASE)
12130b57cec5SDimitry Andric       .Case("fxsr", HasFXSR)
12140b57cec5SDimitry Andric       .Case("gfni", HasGFNI)
1215e8d8bef9SDimitry Andric       .Case("hreset", HasHRESET)
12160b57cec5SDimitry Andric       .Case("invpcid", HasINVPCID)
1217e8d8bef9SDimitry Andric       .Case("kl", HasKL)
1218e8d8bef9SDimitry Andric       .Case("widekl", HasWIDEKL)
12190b57cec5SDimitry Andric       .Case("lwp", HasLWP)
12200b57cec5SDimitry Andric       .Case("lzcnt", HasLZCNT)
12210fca6ea1SDimitry Andric       .Case("mmx", HasMMX)
12220b57cec5SDimitry Andric       .Case("movbe", HasMOVBE)
12230b57cec5SDimitry Andric       .Case("movdiri", HasMOVDIRI)
12240b57cec5SDimitry Andric       .Case("movdir64b", HasMOVDIR64B)
12250b57cec5SDimitry Andric       .Case("mwaitx", HasMWAITX)
12260b57cec5SDimitry Andric       .Case("pclmul", HasPCLMUL)
12270b57cec5SDimitry Andric       .Case("pconfig", HasPCONFIG)
12280b57cec5SDimitry Andric       .Case("pku", HasPKU)
12290b57cec5SDimitry Andric       .Case("popcnt", HasPOPCNT)
1230bdd1243dSDimitry Andric       .Case("prefetchi", HasPREFETCHI)
12310b57cec5SDimitry Andric       .Case("prfchw", HasPRFCHW)
12320b57cec5SDimitry Andric       .Case("ptwrite", HasPTWRITE)
1233bdd1243dSDimitry Andric       .Case("raoint", HasRAOINT)
12340b57cec5SDimitry Andric       .Case("rdpid", HasRDPID)
1235753f127fSDimitry Andric       .Case("rdpru", HasRDPRU)
12360b57cec5SDimitry Andric       .Case("rdrnd", HasRDRND)
12370b57cec5SDimitry Andric       .Case("rdseed", HasRDSEED)
12380b57cec5SDimitry Andric       .Case("retpoline-external-thunk", HasRetpolineExternalThunk)
12390b57cec5SDimitry Andric       .Case("rtm", HasRTM)
12400b57cec5SDimitry Andric       .Case("sahf", HasLAHFSAHF)
12415ffd83dbSDimitry Andric       .Case("serialize", HasSERIALIZE)
12420b57cec5SDimitry Andric       .Case("sgx", HasSGX)
12430b57cec5SDimitry Andric       .Case("sha", HasSHA)
124406c3fb27SDimitry Andric       .Case("sha512", HasSHA512)
12450b57cec5SDimitry Andric       .Case("shstk", HasSHSTK)
124606c3fb27SDimitry Andric       .Case("sm3", HasSM3)
124706c3fb27SDimitry Andric       .Case("sm4", HasSM4)
12480b57cec5SDimitry Andric       .Case("sse", SSELevel >= SSE1)
12490b57cec5SDimitry Andric       .Case("sse2", SSELevel >= SSE2)
12500b57cec5SDimitry Andric       .Case("sse3", SSELevel >= SSE3)
12510b57cec5SDimitry Andric       .Case("ssse3", SSELevel >= SSSE3)
12520b57cec5SDimitry Andric       .Case("sse4.1", SSELevel >= SSE41)
12530b57cec5SDimitry Andric       .Case("sse4.2", SSELevel >= SSE42)
12540b57cec5SDimitry Andric       .Case("sse4a", XOPLevel >= SSE4A)
12550b57cec5SDimitry Andric       .Case("tbm", HasTBM)
12565ffd83dbSDimitry Andric       .Case("tsxldtrk", HasTSXLDTRK)
1257e8d8bef9SDimitry Andric       .Case("uintr", HasUINTR)
12585f757f3fSDimitry Andric       .Case("usermsr", HasUSERMSR)
12590b57cec5SDimitry Andric       .Case("vaes", HasVAES)
12600b57cec5SDimitry Andric       .Case("vpclmulqdq", HasVPCLMULQDQ)
12610b57cec5SDimitry Andric       .Case("wbnoinvd", HasWBNOINVD)
12620b57cec5SDimitry Andric       .Case("waitpkg", HasWAITPKG)
12630b57cec5SDimitry Andric       .Case("x86", true)
12640b57cec5SDimitry Andric       .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
12650b57cec5SDimitry Andric       .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
1266349cc55cSDimitry Andric       .Case("x87", HasX87)
12670b57cec5SDimitry Andric       .Case("xop", XOPLevel >= XOP)
12680b57cec5SDimitry Andric       .Case("xsave", HasXSAVE)
12690b57cec5SDimitry Andric       .Case("xsavec", HasXSAVEC)
12700b57cec5SDimitry Andric       .Case("xsaves", HasXSAVES)
12710b57cec5SDimitry Andric       .Case("xsaveopt", HasXSAVEOPT)
127206c3fb27SDimitry Andric       .Case("fullbf16", HasFullBFloat16)
12735f757f3fSDimitry Andric       .Case("egpr", HasEGPR)
12745f757f3fSDimitry Andric       .Case("push2pop2", HasPush2Pop2)
12755f757f3fSDimitry Andric       .Case("ppx", HasPPX)
12765f757f3fSDimitry Andric       .Case("ndd", HasNDD)
12775f757f3fSDimitry Andric       .Case("ccmp", HasCCMP)
12780fca6ea1SDimitry Andric       .Case("nf", HasNF)
12795f757f3fSDimitry Andric       .Case("cf", HasCF)
12800fca6ea1SDimitry Andric       .Case("zu", HasZU)
12810fca6ea1SDimitry Andric       .Case("branch-hint", HasBranchHint)
12820b57cec5SDimitry Andric       .Default(false);
12830b57cec5SDimitry Andric }
12840b57cec5SDimitry Andric 
12850b57cec5SDimitry Andric // We can't use a generic validation scheme for the features accepted here
12860b57cec5SDimitry Andric // versus subtarget features accepted in the target attribute because the
12870b57cec5SDimitry Andric // bitfield structure that's initialized in the runtime only supports the
12880b57cec5SDimitry Andric // below currently rather than the full range of subtarget features. (See
12890b57cec5SDimitry Andric // X86TargetInfo::hasFeature for a somewhat comprehensive list).
12900b57cec5SDimitry Andric bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
12910b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(FeatureStr)
1292349cc55cSDimitry Andric #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) .Case(STR, true)
12935f757f3fSDimitry Andric #define X86_MICROARCH_LEVEL(ENUM, STR, PRIORITY) .Case(STR, true)
1294bdd1243dSDimitry Andric #include "llvm/TargetParser/X86TargetParser.def"
12950b57cec5SDimitry Andric       .Default(false);
12960b57cec5SDimitry Andric }
12970b57cec5SDimitry Andric 
12980b57cec5SDimitry Andric static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {
12990b57cec5SDimitry Andric   return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)
1300349cc55cSDimitry Andric #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY)                                \
1301349cc55cSDimitry Andric   .Case(STR, llvm::X86::FEATURE_##ENUM)
1302349cc55cSDimitry Andric 
1303bdd1243dSDimitry Andric #include "llvm/TargetParser/X86TargetParser.def"
13040b57cec5SDimitry Andric       ;
13050b57cec5SDimitry Andric   // Note, this function should only be used after ensuring the value is
13060b57cec5SDimitry Andric   // correct, so it asserts if the value is out of range.
13070b57cec5SDimitry Andric }
13080b57cec5SDimitry Andric 
13090b57cec5SDimitry Andric unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
13100b57cec5SDimitry Andric   // Valid CPUs have a 'key feature' that compares just better than its key
13110b57cec5SDimitry Andric   // feature.
13125ffd83dbSDimitry Andric   using namespace llvm::X86;
13135ffd83dbSDimitry Andric   CPUKind Kind = parseArchX86(Name);
13145ffd83dbSDimitry Andric   if (Kind != CK_None) {
13155ffd83dbSDimitry Andric     ProcessorFeatures KeyFeature = getKeyFeature(Kind);
13165ffd83dbSDimitry Andric     return (getFeaturePriority(KeyFeature) << 1) + 1;
13170b57cec5SDimitry Andric   }
13180b57cec5SDimitry Andric 
13190b57cec5SDimitry Andric   // Now we know we have a feature, so get its priority and shift it a few so
13200b57cec5SDimitry Andric   // that we have sufficient room for the CPUs (above).
13210b57cec5SDimitry Andric   return getFeaturePriority(getFeature(Name)) << 1;
13220b57cec5SDimitry Andric }
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const {
132506c3fb27SDimitry Andric   return llvm::X86::validateCPUSpecificCPUDispatch(Name);
13260b57cec5SDimitry Andric }
13270b57cec5SDimitry Andric 
13280b57cec5SDimitry Andric char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const {
132906c3fb27SDimitry Andric   return llvm::X86::getCPUDispatchMangling(Name);
13300b57cec5SDimitry Andric }
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(
13330b57cec5SDimitry Andric     StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
133406c3fb27SDimitry Andric   SmallVector<StringRef, 32> TargetCPUFeatures;
133506c3fb27SDimitry Andric   llvm::X86::getFeaturesForCPU(Name, TargetCPUFeatures, true);
133606c3fb27SDimitry Andric   for (auto &F : TargetCPUFeatures)
133706c3fb27SDimitry Andric     Features.push_back(F);
133881ad6265SDimitry Andric }
133981ad6265SDimitry Andric 
13400b57cec5SDimitry Andric // We can't use a generic validation scheme for the cpus accepted here
13410b57cec5SDimitry Andric // versus subtarget cpus accepted in the target attribute because the
13420b57cec5SDimitry Andric // variables intitialized by the runtime only support the below currently
13430b57cec5SDimitry Andric // rather than the full range of cpus.
13440b57cec5SDimitry Andric bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
13450b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(FeatureStr)
13460b57cec5SDimitry Andric #define X86_VENDOR(ENUM, STRING) .Case(STRING, true)
13475ffd83dbSDimitry Andric #define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
13485ffd83dbSDimitry Andric #define X86_CPU_TYPE(ENUM, STR) .Case(STR, true)
1349bdd1243dSDimitry Andric #define X86_CPU_SUBTYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
13505ffd83dbSDimitry Andric #define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true)
1351bdd1243dSDimitry Andric #include "llvm/TargetParser/X86TargetParser.def"
13520b57cec5SDimitry Andric       .Default(false);
13530b57cec5SDimitry Andric }
13540b57cec5SDimitry Andric 
135506c3fb27SDimitry Andric static unsigned matchAsmCCConstraint(const char *Name) {
13560b57cec5SDimitry Andric   auto RV = llvm::StringSwitch<unsigned>(Name)
13570b57cec5SDimitry Andric                 .Case("@cca", 4)
13580b57cec5SDimitry Andric                 .Case("@ccae", 5)
13590b57cec5SDimitry Andric                 .Case("@ccb", 4)
13600b57cec5SDimitry Andric                 .Case("@ccbe", 5)
13610b57cec5SDimitry Andric                 .Case("@ccc", 4)
13620b57cec5SDimitry Andric                 .Case("@cce", 4)
13630b57cec5SDimitry Andric                 .Case("@ccz", 4)
13640b57cec5SDimitry Andric                 .Case("@ccg", 4)
13650b57cec5SDimitry Andric                 .Case("@ccge", 5)
13660b57cec5SDimitry Andric                 .Case("@ccl", 4)
13670b57cec5SDimitry Andric                 .Case("@ccle", 5)
13680b57cec5SDimitry Andric                 .Case("@ccna", 5)
13690b57cec5SDimitry Andric                 .Case("@ccnae", 6)
13700b57cec5SDimitry Andric                 .Case("@ccnb", 5)
13710b57cec5SDimitry Andric                 .Case("@ccnbe", 6)
13720b57cec5SDimitry Andric                 .Case("@ccnc", 5)
13730b57cec5SDimitry Andric                 .Case("@ccne", 5)
13740b57cec5SDimitry Andric                 .Case("@ccnz", 5)
13750b57cec5SDimitry Andric                 .Case("@ccng", 5)
13760b57cec5SDimitry Andric                 .Case("@ccnge", 6)
13770b57cec5SDimitry Andric                 .Case("@ccnl", 5)
13780b57cec5SDimitry Andric                 .Case("@ccnle", 6)
13790b57cec5SDimitry Andric                 .Case("@ccno", 5)
13800b57cec5SDimitry Andric                 .Case("@ccnp", 5)
13810b57cec5SDimitry Andric                 .Case("@ccns", 5)
13820b57cec5SDimitry Andric                 .Case("@cco", 4)
13830b57cec5SDimitry Andric                 .Case("@ccp", 4)
13840b57cec5SDimitry Andric                 .Case("@ccs", 4)
13850b57cec5SDimitry Andric                 .Default(0);
13860b57cec5SDimitry Andric   return RV;
13870b57cec5SDimitry Andric }
13880b57cec5SDimitry Andric 
13890b57cec5SDimitry Andric bool X86TargetInfo::validateAsmConstraint(
13900b57cec5SDimitry Andric     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
13910b57cec5SDimitry Andric   switch (*Name) {
13920b57cec5SDimitry Andric   default:
13930b57cec5SDimitry Andric     return false;
13940b57cec5SDimitry Andric   // Constant constraints.
13950b57cec5SDimitry Andric   case 'e': // 32-bit signed integer constant for use with sign-extending x86_64
13960b57cec5SDimitry Andric             // instructions.
13970b57cec5SDimitry Andric   case 'Z': // 32-bit unsigned integer constant for use with zero-extending
13980b57cec5SDimitry Andric             // x86_64 instructions.
13990b57cec5SDimitry Andric   case 's':
14000b57cec5SDimitry Andric     Info.setRequiresImmediate();
14010b57cec5SDimitry Andric     return true;
14020b57cec5SDimitry Andric   case 'I':
14030b57cec5SDimitry Andric     Info.setRequiresImmediate(0, 31);
14040b57cec5SDimitry Andric     return true;
14050b57cec5SDimitry Andric   case 'J':
14060b57cec5SDimitry Andric     Info.setRequiresImmediate(0, 63);
14070b57cec5SDimitry Andric     return true;
14080b57cec5SDimitry Andric   case 'K':
14090b57cec5SDimitry Andric     Info.setRequiresImmediate(-128, 127);
14100b57cec5SDimitry Andric     return true;
14110b57cec5SDimitry Andric   case 'L':
14120b57cec5SDimitry Andric     Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)});
14130b57cec5SDimitry Andric     return true;
14140b57cec5SDimitry Andric   case 'M':
14150b57cec5SDimitry Andric     Info.setRequiresImmediate(0, 3);
14160b57cec5SDimitry Andric     return true;
14170b57cec5SDimitry Andric   case 'N':
14180b57cec5SDimitry Andric     Info.setRequiresImmediate(0, 255);
14190b57cec5SDimitry Andric     return true;
14200b57cec5SDimitry Andric   case 'O':
14210b57cec5SDimitry Andric     Info.setRequiresImmediate(0, 127);
14220b57cec5SDimitry Andric     return true;
14237a6dacacSDimitry Andric   case 'W':
14247a6dacacSDimitry Andric     switch (*++Name) {
14257a6dacacSDimitry Andric     default:
14267a6dacacSDimitry Andric       return false;
14277a6dacacSDimitry Andric     case 's':
14287a6dacacSDimitry Andric       Info.setAllowsRegister();
14297a6dacacSDimitry Andric       return true;
14307a6dacacSDimitry Andric     }
14310b57cec5SDimitry Andric   // Register constraints.
14320b57cec5SDimitry Andric   case 'Y': // 'Y' is the first character for several 2-character constraints.
14330b57cec5SDimitry Andric     // Shift the pointer to the second character of the constraint.
14340b57cec5SDimitry Andric     Name++;
14350b57cec5SDimitry Andric     switch (*Name) {
14360b57cec5SDimitry Andric     default:
14370b57cec5SDimitry Andric       return false;
14385ffd83dbSDimitry Andric     case 'z': // First SSE register.
14390b57cec5SDimitry Andric     case '2':
14400b57cec5SDimitry Andric     case 't': // Any SSE register, when SSE2 is enabled.
14410b57cec5SDimitry Andric     case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
14420b57cec5SDimitry Andric     case 'm': // Any MMX register, when inter-unit moves enabled.
14430b57cec5SDimitry Andric     case 'k': // AVX512 arch mask registers: k1-k7.
14440b57cec5SDimitry Andric       Info.setAllowsRegister();
14450b57cec5SDimitry Andric       return true;
14460b57cec5SDimitry Andric     }
14470b57cec5SDimitry Andric   case 'f': // Any x87 floating point stack register.
14480b57cec5SDimitry Andric     // Constraint 'f' cannot be used for output operands.
14490b57cec5SDimitry Andric     if (Info.ConstraintStr[0] == '=')
14500b57cec5SDimitry Andric       return false;
14510b57cec5SDimitry Andric     Info.setAllowsRegister();
14520b57cec5SDimitry Andric     return true;
14530b57cec5SDimitry Andric   case 'a': // eax.
14540b57cec5SDimitry Andric   case 'b': // ebx.
14550b57cec5SDimitry Andric   case 'c': // ecx.
14560b57cec5SDimitry Andric   case 'd': // edx.
14570b57cec5SDimitry Andric   case 'S': // esi.
14580b57cec5SDimitry Andric   case 'D': // edi.
14590b57cec5SDimitry Andric   case 'A': // edx:eax.
14600b57cec5SDimitry Andric   case 't': // Top of floating point stack.
14610b57cec5SDimitry Andric   case 'u': // Second from top of floating point stack.
14620b57cec5SDimitry Andric   case 'q': // Any register accessible as [r]l: a, b, c, and d.
14630b57cec5SDimitry Andric   case 'y': // Any MMX register.
14640b57cec5SDimitry Andric   case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)
14650b57cec5SDimitry Andric   case 'x': // Any SSE register.
14660b57cec5SDimitry Andric   case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0
14670b57cec5SDimitry Andric             // for intermideate k reg operations).
14680b57cec5SDimitry Andric   case 'Q': // Any register accessible as [r]h: a, b, c, and d.
14690b57cec5SDimitry Andric   case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
14700b57cec5SDimitry Andric   case 'l': // "Index" registers: any general register that can be used as an
14710b57cec5SDimitry Andric             // index in a base+index memory access.
14720b57cec5SDimitry Andric     Info.setAllowsRegister();
14730b57cec5SDimitry Andric     return true;
14740b57cec5SDimitry Andric   // Floating point constant constraints.
14750b57cec5SDimitry Andric   case 'C': // SSE floating point constant.
14760b57cec5SDimitry Andric   case 'G': // x87 floating point constant.
14770b57cec5SDimitry Andric     return true;
14780fca6ea1SDimitry Andric   case 'j':
14790fca6ea1SDimitry Andric     Name++;
14800fca6ea1SDimitry Andric     switch (*Name) {
14810fca6ea1SDimitry Andric     default:
14820fca6ea1SDimitry Andric       return false;
14830fca6ea1SDimitry Andric     case 'r':
14840fca6ea1SDimitry Andric       Info.setAllowsRegister();
14850fca6ea1SDimitry Andric       return true;
14860fca6ea1SDimitry Andric     case 'R':
14870fca6ea1SDimitry Andric       Info.setAllowsRegister();
14880fca6ea1SDimitry Andric       return true;
14890fca6ea1SDimitry Andric     }
14900b57cec5SDimitry Andric   case '@':
14910b57cec5SDimitry Andric     // CC condition changes.
14920b57cec5SDimitry Andric     if (auto Len = matchAsmCCConstraint(Name)) {
14930b57cec5SDimitry Andric       Name += Len - 1;
14940b57cec5SDimitry Andric       Info.setAllowsRegister();
14950b57cec5SDimitry Andric       return true;
14960b57cec5SDimitry Andric     }
14970b57cec5SDimitry Andric     return false;
14980b57cec5SDimitry Andric   }
14990b57cec5SDimitry Andric }
15000b57cec5SDimitry Andric 
15015ffd83dbSDimitry Andric // Below is based on the following information:
15025ffd83dbSDimitry Andric // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
15035ffd83dbSDimitry Andric // |           Processor Name           | Cache Line Size (Bytes) |                                                                            Source                                                                            |
15045ffd83dbSDimitry Andric // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
15055ffd83dbSDimitry Andric // | i386                               |                      64 | https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf                                          |
15065ffd83dbSDimitry Andric // | 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) |
15075ffd83dbSDimitry Andric // | i586/Pentium MMX                   |                      32 | https://www.7-cpu.com/cpu/P-MMX.html                                                                                                                         |
15085ffd83dbSDimitry Andric // | i686/Pentium                       |                      32 | https://www.7-cpu.com/cpu/P6.html                                                                                                                            |
15095ffd83dbSDimitry Andric // | Netburst/Pentium4                  |                      64 | https://www.7-cpu.com/cpu/P4-180.html                                                                                                                        |
15105ffd83dbSDimitry Andric // | Atom                               |                      64 | https://www.7-cpu.com/cpu/Atom.html                                                                                                                          |
15115ffd83dbSDimitry Andric // | Westmere                           |                      64 | https://en.wikichip.org/wiki/intel/microarchitectures/sandy_bridge_(client) "Cache Architecture"                                                             |
15125ffd83dbSDimitry Andric // | Sandy Bridge                       |                      64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html                                                                    |
15135ffd83dbSDimitry Andric // | Ivy Bridge                         |                      64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html                                                      |
15145ffd83dbSDimitry Andric // | Haswell                            |                      64 | https://www.7-cpu.com/cpu/Haswell.html                                                                                                                       |
151506c3fb27SDimitry Andric // | Broadwell                          |                      64 | https://www.7-cpu.com/cpu/Broadwell.html                                                                                                                     |
15165ffd83dbSDimitry Andric // | Skylake (including skylake-avx512) |                      64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy"                                                                       |
15175ffd83dbSDimitry Andric // | Cascade Lake                       |                      64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy"                                                                  |
15185ffd83dbSDimitry Andric // | Skylake                            |                      64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy"                                                                           |
15195ffd83dbSDimitry Andric // | Ice Lake                           |                      64 | https://www.7-cpu.com/cpu/Ice_Lake.html                                                                                                                      |
15205ffd83dbSDimitry Andric // | 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" |
15215ffd83dbSDimitry Andric // | 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 "       |
15225ffd83dbSDimitry Andric // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1523bdd1243dSDimitry Andric std::optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
15245ffd83dbSDimitry Andric   using namespace llvm::X86;
15255ffd83dbSDimitry Andric   switch (CPU) {
15265ffd83dbSDimitry Andric     // i386
15275ffd83dbSDimitry Andric     case CK_i386:
15285ffd83dbSDimitry Andric     // i486
15295ffd83dbSDimitry Andric     case CK_i486:
15305ffd83dbSDimitry Andric     case CK_WinChipC6:
15315ffd83dbSDimitry Andric     case CK_WinChip2:
15325ffd83dbSDimitry Andric     case CK_C3:
15335ffd83dbSDimitry Andric     // Lakemont
15345ffd83dbSDimitry Andric     case CK_Lakemont:
15355ffd83dbSDimitry Andric       return 16;
15365ffd83dbSDimitry Andric 
15375ffd83dbSDimitry Andric     // i586
15385ffd83dbSDimitry Andric     case CK_i586:
15395ffd83dbSDimitry Andric     case CK_Pentium:
15405ffd83dbSDimitry Andric     case CK_PentiumMMX:
15415ffd83dbSDimitry Andric     // i686
15425ffd83dbSDimitry Andric     case CK_PentiumPro:
15435ffd83dbSDimitry Andric     case CK_i686:
15445ffd83dbSDimitry Andric     case CK_Pentium2:
15455ffd83dbSDimitry Andric     case CK_Pentium3:
15465ffd83dbSDimitry Andric     case CK_PentiumM:
15475ffd83dbSDimitry Andric     case CK_C3_2:
15485ffd83dbSDimitry Andric     // K6
15495ffd83dbSDimitry Andric     case CK_K6:
15505ffd83dbSDimitry Andric     case CK_K6_2:
15515ffd83dbSDimitry Andric     case CK_K6_3:
15525ffd83dbSDimitry Andric     // Geode
15535ffd83dbSDimitry Andric     case CK_Geode:
15545ffd83dbSDimitry Andric       return 32;
15555ffd83dbSDimitry Andric 
15565ffd83dbSDimitry Andric     // Netburst
15575ffd83dbSDimitry Andric     case CK_Pentium4:
15585ffd83dbSDimitry Andric     case CK_Prescott:
15595ffd83dbSDimitry Andric     case CK_Nocona:
15605ffd83dbSDimitry Andric     // Atom
15615ffd83dbSDimitry Andric     case CK_Bonnell:
15625ffd83dbSDimitry Andric     case CK_Silvermont:
15635ffd83dbSDimitry Andric     case CK_Goldmont:
15645ffd83dbSDimitry Andric     case CK_GoldmontPlus:
15655ffd83dbSDimitry Andric     case CK_Tremont:
15665f757f3fSDimitry Andric     case CK_Gracemont:
15675ffd83dbSDimitry Andric 
15685ffd83dbSDimitry Andric     case CK_Westmere:
15695ffd83dbSDimitry Andric     case CK_SandyBridge:
15705ffd83dbSDimitry Andric     case CK_IvyBridge:
15715ffd83dbSDimitry Andric     case CK_Haswell:
15725ffd83dbSDimitry Andric     case CK_Broadwell:
15735ffd83dbSDimitry Andric     case CK_SkylakeClient:
15745ffd83dbSDimitry Andric     case CK_SkylakeServer:
15755ffd83dbSDimitry Andric     case CK_Cascadelake:
15765ffd83dbSDimitry Andric     case CK_Nehalem:
15775ffd83dbSDimitry Andric     case CK_Cooperlake:
15785ffd83dbSDimitry Andric     case CK_Cannonlake:
15795ffd83dbSDimitry Andric     case CK_Tigerlake:
1580e8d8bef9SDimitry Andric     case CK_SapphireRapids:
15815ffd83dbSDimitry Andric     case CK_IcelakeClient:
1582fe6060f1SDimitry Andric     case CK_Rocketlake:
15835ffd83dbSDimitry Andric     case CK_IcelakeServer:
1584e8d8bef9SDimitry Andric     case CK_Alderlake:
1585bdd1243dSDimitry Andric     case CK_Raptorlake:
1586bdd1243dSDimitry Andric     case CK_Meteorlake:
15875f757f3fSDimitry Andric     case CK_Arrowlake:
15885f757f3fSDimitry Andric     case CK_ArrowlakeS:
15895f757f3fSDimitry Andric     case CK_Lunarlake:
15905f757f3fSDimitry Andric     case CK_Pantherlake:
1591bdd1243dSDimitry Andric     case CK_Sierraforest:
1592bdd1243dSDimitry Andric     case CK_Grandridge:
1593bdd1243dSDimitry Andric     case CK_Graniterapids:
159406c3fb27SDimitry Andric     case CK_GraniterapidsD:
1595bdd1243dSDimitry Andric     case CK_Emeraldrapids:
15965f757f3fSDimitry Andric     case CK_Clearwaterforest:
15975ffd83dbSDimitry Andric     case CK_KNL:
15985ffd83dbSDimitry Andric     case CK_KNM:
15995ffd83dbSDimitry Andric     // K7
16005ffd83dbSDimitry Andric     case CK_Athlon:
16015ffd83dbSDimitry Andric     case CK_AthlonXP:
16025ffd83dbSDimitry Andric     // K8
16035ffd83dbSDimitry Andric     case CK_K8:
16045ffd83dbSDimitry Andric     case CK_K8SSE3:
16055ffd83dbSDimitry Andric     case CK_AMDFAM10:
16065ffd83dbSDimitry Andric     // Bobcat
16075ffd83dbSDimitry Andric     case CK_BTVER1:
16085ffd83dbSDimitry Andric     case CK_BTVER2:
16095ffd83dbSDimitry Andric     // Bulldozer
16105ffd83dbSDimitry Andric     case CK_BDVER1:
16115ffd83dbSDimitry Andric     case CK_BDVER2:
16125ffd83dbSDimitry Andric     case CK_BDVER3:
16135ffd83dbSDimitry Andric     case CK_BDVER4:
16145ffd83dbSDimitry Andric     // Zen
16155ffd83dbSDimitry Andric     case CK_ZNVER1:
16165ffd83dbSDimitry Andric     case CK_ZNVER2:
1617e8d8bef9SDimitry Andric     case CK_ZNVER3:
1618bdd1243dSDimitry Andric     case CK_ZNVER4:
1619*c80e69b0SDimitry Andric     case CK_ZNVER5:
16205ffd83dbSDimitry Andric     // Deprecated
16215ffd83dbSDimitry Andric     case CK_x86_64:
1622e8d8bef9SDimitry Andric     case CK_x86_64_v2:
1623e8d8bef9SDimitry Andric     case CK_x86_64_v3:
1624e8d8bef9SDimitry Andric     case CK_x86_64_v4:
16255ffd83dbSDimitry Andric     case CK_Yonah:
16265ffd83dbSDimitry Andric     case CK_Penryn:
16275ffd83dbSDimitry Andric     case CK_Core2:
16285ffd83dbSDimitry Andric       return 64;
16295ffd83dbSDimitry Andric 
16305ffd83dbSDimitry Andric     // The following currently have unknown cache line sizes (but they are probably all 64):
16315ffd83dbSDimitry Andric     // Core
16325ffd83dbSDimitry Andric     case CK_None:
1633bdd1243dSDimitry Andric       return std::nullopt;
16345ffd83dbSDimitry Andric   }
16355ffd83dbSDimitry Andric   llvm_unreachable("Unknown CPU kind");
16365ffd83dbSDimitry Andric }
16375ffd83dbSDimitry Andric 
1638480093f4SDimitry Andric bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
1639480093f4SDimitry Andric                                        StringRef Constraint,
16400b57cec5SDimitry Andric                                        unsigned Size) const {
16410b57cec5SDimitry Andric   // Strip off constraint modifiers.
1642647cbc5dSDimitry Andric   Constraint = Constraint.ltrim("=+&");
16430b57cec5SDimitry Andric 
1644480093f4SDimitry Andric   return validateOperandSize(FeatureMap, Constraint, Size);
16450b57cec5SDimitry Andric }
16460b57cec5SDimitry Andric 
1647480093f4SDimitry Andric bool X86TargetInfo::validateInputSize(const llvm::StringMap<bool> &FeatureMap,
1648480093f4SDimitry Andric                                       StringRef Constraint,
16490b57cec5SDimitry Andric                                       unsigned Size) const {
1650480093f4SDimitry Andric   return validateOperandSize(FeatureMap, Constraint, Size);
16510b57cec5SDimitry Andric }
16520b57cec5SDimitry Andric 
1653480093f4SDimitry Andric bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
1654480093f4SDimitry Andric                                         StringRef Constraint,
16550b57cec5SDimitry Andric                                         unsigned Size) const {
16560b57cec5SDimitry Andric   switch (Constraint[0]) {
16570b57cec5SDimitry Andric   default:
16580b57cec5SDimitry Andric     break;
16590b57cec5SDimitry Andric   case 'k':
16600b57cec5SDimitry Andric   // Registers k0-k7 (AVX512) size limit is 64 bit.
16610b57cec5SDimitry Andric   case 'y':
16620b57cec5SDimitry Andric     return Size <= 64;
16630b57cec5SDimitry Andric   case 'f':
16640b57cec5SDimitry Andric   case 't':
16650b57cec5SDimitry Andric   case 'u':
16660b57cec5SDimitry Andric     return Size <= 128;
16670b57cec5SDimitry Andric   case 'Y':
16680b57cec5SDimitry Andric     // 'Y' is the first character for several 2-character constraints.
16690b57cec5SDimitry Andric     switch (Constraint[1]) {
16700b57cec5SDimitry Andric     default:
16710b57cec5SDimitry Andric       return false;
16720b57cec5SDimitry Andric     case 'm':
16730b57cec5SDimitry Andric       // 'Ym' is synonymous with 'y'.
16740b57cec5SDimitry Andric     case 'k':
16750b57cec5SDimitry Andric       return Size <= 64;
16760b57cec5SDimitry Andric     case 'z':
16775ffd83dbSDimitry Andric       // XMM0/YMM/ZMM0
16785f757f3fSDimitry Andric       if (hasFeatureEnabled(FeatureMap, "avx512f") &&
16795f757f3fSDimitry Andric           hasFeatureEnabled(FeatureMap, "evex512"))
16805f757f3fSDimitry Andric         // ZMM0 can be used if target supports AVX512F and EVEX512 is set.
16815ffd83dbSDimitry Andric         return Size <= 512U;
1682fe6060f1SDimitry Andric       else if (hasFeatureEnabled(FeatureMap, "avx"))
16835ffd83dbSDimitry Andric         // YMM0 can be used if target supports AVX.
16845ffd83dbSDimitry Andric         return Size <= 256U;
1685fe6060f1SDimitry Andric       else if (hasFeatureEnabled(FeatureMap, "sse"))
16860b57cec5SDimitry Andric         return Size <= 128U;
16870b57cec5SDimitry Andric       return false;
16880b57cec5SDimitry Andric     case 'i':
16890b57cec5SDimitry Andric     case 't':
16900b57cec5SDimitry Andric     case '2':
16910b57cec5SDimitry Andric       // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled.
16920b57cec5SDimitry Andric       if (SSELevel < SSE2)
16930b57cec5SDimitry Andric         return false;
16940b57cec5SDimitry Andric       break;
16950b57cec5SDimitry Andric     }
16965ffd83dbSDimitry Andric     break;
16970b57cec5SDimitry Andric   case 'v':
16980b57cec5SDimitry Andric   case 'x':
16995f757f3fSDimitry Andric     if (hasFeatureEnabled(FeatureMap, "avx512f") &&
17005f757f3fSDimitry Andric         hasFeatureEnabled(FeatureMap, "evex512"))
17015f757f3fSDimitry Andric       // 512-bit zmm registers can be used if target supports AVX512F and
17025f757f3fSDimitry Andric       // EVEX512 is set.
17030b57cec5SDimitry Andric       return Size <= 512U;
1704fe6060f1SDimitry Andric     else if (hasFeatureEnabled(FeatureMap, "avx"))
17050b57cec5SDimitry Andric       // 256-bit ymm registers can be used if target supports AVX.
17060b57cec5SDimitry Andric       return Size <= 256U;
17070b57cec5SDimitry Andric     return Size <= 128U;
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric   }
17100b57cec5SDimitry Andric 
17110b57cec5SDimitry Andric   return true;
17120b57cec5SDimitry Andric }
17130b57cec5SDimitry Andric 
17140b57cec5SDimitry Andric std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
17150b57cec5SDimitry Andric   switch (*Constraint) {
17160b57cec5SDimitry Andric   case '@':
17170b57cec5SDimitry Andric     if (auto Len = matchAsmCCConstraint(Constraint)) {
17180b57cec5SDimitry Andric       std::string Converted = "{" + std::string(Constraint, Len) + "}";
17190b57cec5SDimitry Andric       Constraint += Len - 1;
17200b57cec5SDimitry Andric       return Converted;
17210b57cec5SDimitry Andric     }
17220b57cec5SDimitry Andric     return std::string(1, *Constraint);
17230b57cec5SDimitry Andric   case 'a':
17240b57cec5SDimitry Andric     return std::string("{ax}");
17250b57cec5SDimitry Andric   case 'b':
17260b57cec5SDimitry Andric     return std::string("{bx}");
17270b57cec5SDimitry Andric   case 'c':
17280b57cec5SDimitry Andric     return std::string("{cx}");
17290b57cec5SDimitry Andric   case 'd':
17300b57cec5SDimitry Andric     return std::string("{dx}");
17310b57cec5SDimitry Andric   case 'S':
17320b57cec5SDimitry Andric     return std::string("{si}");
17330b57cec5SDimitry Andric   case 'D':
17340b57cec5SDimitry Andric     return std::string("{di}");
173581ad6265SDimitry Andric   case 'p': // Keep 'p' constraint (address).
173681ad6265SDimitry Andric     return std::string("p");
17370b57cec5SDimitry Andric   case 't': // top of floating point stack.
17380b57cec5SDimitry Andric     return std::string("{st}");
17390b57cec5SDimitry Andric   case 'u':                        // second from top of floating point stack.
17400b57cec5SDimitry Andric     return std::string("{st(1)}"); // second from top of floating point stack.
17417a6dacacSDimitry Andric   case 'W':
17427a6dacacSDimitry Andric     assert(Constraint[1] == 's');
17437a6dacacSDimitry Andric     return '^' + std::string(Constraint++, 2);
17440b57cec5SDimitry Andric   case 'Y':
17450b57cec5SDimitry Andric     switch (Constraint[1]) {
17460b57cec5SDimitry Andric     default:
17470b57cec5SDimitry Andric       // Break from inner switch and fall through (copy single char),
17480b57cec5SDimitry Andric       // continue parsing after copying the current constraint into
17490b57cec5SDimitry Andric       // the return string.
17500b57cec5SDimitry Andric       break;
17510b57cec5SDimitry Andric     case 'k':
17520b57cec5SDimitry Andric     case 'm':
17530b57cec5SDimitry Andric     case 'i':
17540b57cec5SDimitry Andric     case 't':
17550b57cec5SDimitry Andric     case 'z':
17560b57cec5SDimitry Andric     case '2':
17570b57cec5SDimitry Andric       // "^" hints llvm that this is a 2 letter constraint.
17580b57cec5SDimitry Andric       // "Constraint++" is used to promote the string iterator
17590b57cec5SDimitry Andric       // to the next constraint.
17600b57cec5SDimitry Andric       return std::string("^") + std::string(Constraint++, 2);
17610b57cec5SDimitry Andric     }
1762bdd1243dSDimitry Andric     [[fallthrough]];
17630fca6ea1SDimitry Andric   case 'j':
17640fca6ea1SDimitry Andric     switch (Constraint[1]) {
17650fca6ea1SDimitry Andric     default:
17660fca6ea1SDimitry Andric       // Break from inner switch and fall through (copy single char),
17670fca6ea1SDimitry Andric       // continue parsing after copying the current constraint into
17680fca6ea1SDimitry Andric       // the return string.
17690fca6ea1SDimitry Andric       break;
17700fca6ea1SDimitry Andric     case 'r':
17710fca6ea1SDimitry Andric     case 'R':
17720fca6ea1SDimitry Andric       // "^" hints llvm that this is a 2 letter constraint.
17730fca6ea1SDimitry Andric       // "Constraint++" is used to promote the string iterator
17740fca6ea1SDimitry Andric       // to the next constraint.
17750fca6ea1SDimitry Andric       return std::string("^") + std::string(Constraint++, 2);
17760fca6ea1SDimitry Andric     }
17770fca6ea1SDimitry Andric     [[fallthrough]];
17780b57cec5SDimitry Andric   default:
17790b57cec5SDimitry Andric     return std::string(1, *Constraint);
17800b57cec5SDimitry Andric   }
17810b57cec5SDimitry Andric }
17820b57cec5SDimitry Andric 
17830b57cec5SDimitry Andric void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
17845ffd83dbSDimitry Andric   bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
17855ffd83dbSDimitry Andric   llvm::X86::fillValidCPUArchList(Values, Only64Bit);
17860b57cec5SDimitry Andric }
17870b57cec5SDimitry Andric 
1788e8d8bef9SDimitry Andric void X86TargetInfo::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const {
1789e8d8bef9SDimitry Andric   llvm::X86::fillValidTuneCPUList(Values);
1790e8d8bef9SDimitry Andric }
1791e8d8bef9SDimitry Andric 
17920b57cec5SDimitry Andric ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {
1793bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegNames);
17940b57cec5SDimitry Andric }
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
1797bdd1243dSDimitry Andric   return llvm::ArrayRef(AddlRegNames);
17980b57cec5SDimitry Andric }
17990b57cec5SDimitry Andric 
18000b57cec5SDimitry Andric ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
1801bdd1243dSDimitry Andric   return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
18020b57cec5SDimitry Andric                                             Builtin::FirstTSBuiltin + 1);
18030b57cec5SDimitry Andric }
18040b57cec5SDimitry Andric 
18050b57cec5SDimitry Andric ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
1806bdd1243dSDimitry Andric   return llvm::ArrayRef(BuiltinInfoX86,
18070b57cec5SDimitry Andric                         X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
18080b57cec5SDimitry Andric }
1809