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