1839 lines · cpp
1//===--- X86.cpp - Implement X86 target feature support -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements X86 TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#include "X86.h"14#include "clang/Basic/Builtins.h"15#include "clang/Basic/Diagnostic.h"16#include "clang/Basic/TargetBuiltins.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/ADT/StringSwitch.h"19#include "llvm/TargetParser/X86TargetParser.h"20#include <optional>21 22namespace clang {23namespace targets {24 25// The x86-32 builtins are a subset and prefix of the x86-64 builtins.26static constexpr int NumX86Builtins =27 X86::LastX86CommonBuiltin - Builtin::FirstTSBuiltin + 1;28static constexpr int NumX86_64Builtins =29 X86::LastTSBuiltin - X86::FirstX86_64Builtin;30static constexpr int NumBuiltins = X86::LastTSBuiltin - Builtin::FirstTSBuiltin;31static_assert(NumBuiltins == (NumX86Builtins + NumX86_64Builtins));32 33namespace X86 {34#define GET_BUILTIN_STR_TABLE35#include "clang/Basic/BuiltinsX86.inc"36#undef GET_BUILTIN_STR_TABLE37 38static constexpr Builtin::Info BuiltinInfos[] = {39#define GET_BUILTIN_INFOS40#include "clang/Basic/BuiltinsX86.inc"41#undef GET_BUILTIN_INFOS42};43 44static constexpr Builtin::Info PrefixedBuiltinInfos[] = {45#define GET_BUILTIN_PREFIXED_INFOS46#include "clang/Basic/BuiltinsX86.inc"47#undef GET_BUILTIN_PREFIXED_INFOS48};49static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==50 NumX86Builtins);51} // namespace X8652 53namespace X86_64 {54#define GET_BUILTIN_STR_TABLE55#include "clang/Basic/BuiltinsX86_64.inc"56#undef GET_BUILTIN_STR_TABLE57 58static constexpr Builtin::Info BuiltinInfos[] = {59#define GET_BUILTIN_INFOS60#include "clang/Basic/BuiltinsX86_64.inc"61#undef GET_BUILTIN_INFOS62};63 64static constexpr Builtin::Info PrefixedBuiltinInfos[] = {65#define GET_BUILTIN_PREFIXED_INFOS66#include "clang/Basic/BuiltinsX86_64.inc"67#undef GET_BUILTIN_PREFIXED_INFOS68};69static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==70 NumX86_64Builtins);71} // namespace X86_6472 73static const char *const GCCRegNames[] = {74 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",75 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",76 "argp", "flags", "fpcr", "fpsr", "dirflag", "frame", "xmm0", "xmm1",77 "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "mm0", "mm1",78 "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "r8", "r9",79 "r10", "r11", "r12", "r13", "r14", "r15", "xmm8", "xmm9",80 "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", "ymm0", "ymm1",81 "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9",82 "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", "xmm16", "xmm17",83 "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", "xmm24", "xmm25",84 "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31", "ymm16", "ymm17",85 "ymm18", "ymm19", "ymm20", "ymm21", "ymm22", "ymm23", "ymm24", "ymm25",86 "ymm26", "ymm27", "ymm28", "ymm29", "ymm30", "ymm31", "zmm0", "zmm1",87 "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9",88 "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17",89 "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25",90 "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", "k0", "k1",91 "k2", "k3", "k4", "k5", "k6", "k7",92 "cr0", "cr2", "cr3", "cr4", "cr8",93 "dr0", "dr1", "dr2", "dr3", "dr6", "dr7",94 "bnd0", "bnd1", "bnd2", "bnd3",95 "tmm0", "tmm1", "tmm2", "tmm3", "tmm4", "tmm5", "tmm6", "tmm7",96 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",97 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",98};99 100const TargetInfo::AddlRegName AddlRegNames[] = {101 {{"al", "ah", "eax", "rax"}, 0},102 {{"bl", "bh", "ebx", "rbx"}, 3},103 {{"cl", "ch", "ecx", "rcx"}, 2},104 {{"dl", "dh", "edx", "rdx"}, 1},105 {{"esi", "rsi"}, 4},106 {{"edi", "rdi"}, 5},107 {{"esp", "rsp"}, 7},108 {{"ebp", "rbp"}, 6},109 {{"r8d", "r8w", "r8b"}, 38},110 {{"r9d", "r9w", "r9b"}, 39},111 {{"r10d", "r10w", "r10b"}, 40},112 {{"r11d", "r11w", "r11b"}, 41},113 {{"r12d", "r12w", "r12b"}, 42},114 {{"r13d", "r13w", "r13b"}, 43},115 {{"r14d", "r14w", "r14b"}, 44},116 {{"r15d", "r15w", "r15b"}, 45},117 {{"r16d", "r16w", "r16b"}, 165},118 {{"r17d", "r17w", "r17b"}, 166},119 {{"r18d", "r18w", "r18b"}, 167},120 {{"r19d", "r19w", "r19b"}, 168},121 {{"r20d", "r20w", "r20b"}, 169},122 {{"r21d", "r21w", "r21b"}, 170},123 {{"r22d", "r22w", "r22b"}, 171},124 {{"r23d", "r23w", "r23b"}, 172},125 {{"r24d", "r24w", "r24b"}, 173},126 {{"r25d", "r25w", "r25b"}, 174},127 {{"r26d", "r26w", "r26b"}, 175},128 {{"r27d", "r27w", "r27b"}, 176},129 {{"r28d", "r28w", "r28b"}, 177},130 {{"r29d", "r29w", "r29b"}, 178},131 {{"r30d", "r30w", "r30b"}, 179},132 {{"r31d", "r31w", "r31b"}, 180},133};134} // namespace targets135} // namespace clang136 137using namespace clang;138using namespace clang::targets;139 140bool X86TargetInfo::setFPMath(StringRef Name) {141 if (Name == "387") {142 FPMath = FP_387;143 return true;144 }145 if (Name == "sse") {146 FPMath = FP_SSE;147 return true;148 }149 return false;150}151 152bool X86TargetInfo::initFeatureMap(153 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,154 const std::vector<std::string> &FeaturesVec) const {155 // FIXME: This *really* should not be here.156 // X86_64 always has SSE2.157 if (getTriple().getArch() == llvm::Triple::x86_64)158 setFeatureEnabled(Features, "sse2", true);159 160 using namespace llvm::X86;161 162 SmallVector<StringRef, 16> CPUFeatures;163 getFeaturesForCPU(CPU, CPUFeatures);164 for (auto &F : CPUFeatures)165 setFeatureEnabled(Features, F, true);166 167 std::vector<std::string> UpdatedFeaturesVec;168 for (const auto &Feature : FeaturesVec) {169 // Expand general-regs-only to -x86, -mmx and -sse170 if (Feature == "+general-regs-only") {171 UpdatedFeaturesVec.push_back("-x87");172 UpdatedFeaturesVec.push_back("-mmx");173 UpdatedFeaturesVec.push_back("-sse");174 continue;175 }176 177 UpdatedFeaturesVec.push_back(Feature);178 }179 180 if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec))181 return false;182 183 // Can't do this earlier because we need to be able to explicitly enable184 // or disable these features and the things that they depend upon.185 186 // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.187 auto I = Features.find("sse4.2");188 if (I != Features.end() && I->getValue() &&189 !llvm::is_contained(UpdatedFeaturesVec, "-popcnt"))190 Features["popcnt"] = true;191 192 // Additionally, if SSE is enabled and mmx is not explicitly disabled,193 // then enable MMX.194 I = Features.find("sse");195 if (I != Features.end() && I->getValue() &&196 !llvm::is_contained(UpdatedFeaturesVec, "-mmx"))197 Features["mmx"] = true;198 199 // Enable xsave if avx is enabled and xsave is not explicitly disabled.200 I = Features.find("avx");201 if (I != Features.end() && I->getValue() &&202 !llvm::is_contained(UpdatedFeaturesVec, "-xsave"))203 Features["xsave"] = true;204 205 // Enable CRC32 if SSE4.2 is enabled and CRC32 is not explicitly disabled.206 I = Features.find("sse4.2");207 if (I != Features.end() && I->getValue() &&208 !llvm::is_contained(UpdatedFeaturesVec, "-crc32"))209 Features["crc32"] = true;210 211 return true;212}213 214void X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,215 StringRef Name, bool Enabled) const {216 if (Name == "sse4") {217 // We can get here via the __target__ attribute since that's not controlled218 // via the -msse4/-mno-sse4 command line alias. Handle this the same way219 // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if220 // disabled.221 if (Enabled)222 Name = "sse4.2";223 else224 Name = "sse4.1";225 }226 227 Features[Name] = Enabled;228 llvm::X86::updateImpliedFeatures(Name, Enabled, Features);229}230 231/// handleTargetFeatures - Perform initialization based on the user232/// configured set of features.233bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,234 DiagnosticsEngine &Diags) {235 for (const auto &Feature : Features) {236 if (Feature[0] != '+')237 continue;238 239 if (Feature == "+mmx") {240 HasMMX = true;241 } else if (Feature == "+aes") {242 HasAES = true;243 } else if (Feature == "+vaes") {244 HasVAES = true;245 } else if (Feature == "+pclmul") {246 HasPCLMUL = true;247 } else if (Feature == "+vpclmulqdq") {248 HasVPCLMULQDQ = true;249 } else if (Feature == "+lzcnt") {250 HasLZCNT = true;251 } else if (Feature == "+rdrnd") {252 HasRDRND = true;253 } else if (Feature == "+fsgsbase") {254 HasFSGSBASE = true;255 } else if (Feature == "+bmi") {256 HasBMI = true;257 } else if (Feature == "+bmi2") {258 HasBMI2 = true;259 } else if (Feature == "+popcnt") {260 HasPOPCNT = true;261 } else if (Feature == "+rtm") {262 HasRTM = true;263 } else if (Feature == "+prfchw") {264 HasPRFCHW = true;265 } else if (Feature == "+rdseed") {266 HasRDSEED = true;267 } else if (Feature == "+adx") {268 HasADX = true;269 } else if (Feature == "+tbm") {270 HasTBM = true;271 } else if (Feature == "+lwp") {272 HasLWP = true;273 } else if (Feature == "+fma") {274 HasFMA = true;275 } else if (Feature == "+f16c") {276 HasF16C = true;277 } else if (Feature == "+gfni") {278 HasGFNI = true;279 } else if (Feature == "+avx10.1") {280 HasAVX10_1 = true;281 } else if (Feature == "+avx10.2") {282 HasAVX10_2 = true;283 HasFullBFloat16 = true;284 } else if (Feature == "+avx512cd") {285 HasAVX512CD = true;286 } else if (Feature == "+avx512vpopcntdq") {287 HasAVX512VPOPCNTDQ = true;288 } else if (Feature == "+avx512vnni") {289 HasAVX512VNNI = true;290 } else if (Feature == "+avx512bf16") {291 HasAVX512BF16 = true;292 } else if (Feature == "+avx512fp16") {293 HasAVX512FP16 = true;294 HasFastHalfType = true;295 } else if (Feature == "+avx512dq") {296 HasAVX512DQ = true;297 } else if (Feature == "+avx512bitalg") {298 HasAVX512BITALG = true;299 } else if (Feature == "+avx512bw") {300 HasAVX512BW = true;301 } else if (Feature == "+avx512vl") {302 HasAVX512VL = true;303 } else if (Feature == "+avx512vbmi") {304 HasAVX512VBMI = true;305 } else if (Feature == "+avx512vbmi2") {306 HasAVX512VBMI2 = true;307 } else if (Feature == "+avx512ifma") {308 HasAVX512IFMA = true;309 } else if (Feature == "+avx512vp2intersect") {310 HasAVX512VP2INTERSECT = true;311 } else if (Feature == "+sha") {312 HasSHA = true;313 } else if (Feature == "+sha512") {314 HasSHA512 = true;315 } else if (Feature == "+shstk") {316 HasSHSTK = true;317 } else if (Feature == "+sm3") {318 HasSM3 = true;319 } else if (Feature == "+sm4") {320 HasSM4 = true;321 } else if (Feature == "+movbe") {322 HasMOVBE = true;323 } else if (Feature == "+movrs") {324 HasMOVRS = true;325 } else if (Feature == "+sgx") {326 HasSGX = true;327 } else if (Feature == "+cx8") {328 HasCX8 = true;329 } else if (Feature == "+cx16") {330 HasCX16 = true;331 } else if (Feature == "+fxsr") {332 HasFXSR = true;333 } else if (Feature == "+xsave") {334 HasXSAVE = true;335 } else if (Feature == "+xsaveopt") {336 HasXSAVEOPT = true;337 } else if (Feature == "+xsavec") {338 HasXSAVEC = true;339 } else if (Feature == "+xsaves") {340 HasXSAVES = true;341 } else if (Feature == "+mwaitx") {342 HasMWAITX = true;343 } else if (Feature == "+pku") {344 HasPKU = true;345 } else if (Feature == "+clflushopt") {346 HasCLFLUSHOPT = true;347 } else if (Feature == "+clwb") {348 HasCLWB = true;349 } else if (Feature == "+wbnoinvd") {350 HasWBNOINVD = true;351 } else if (Feature == "+prefetchi") {352 HasPREFETCHI = true;353 } else if (Feature == "+clzero") {354 HasCLZERO = true;355 } else if (Feature == "+cldemote") {356 HasCLDEMOTE = true;357 } else if (Feature == "+rdpid") {358 HasRDPID = true;359 } else if (Feature == "+rdpru") {360 HasRDPRU = true;361 } else if (Feature == "+kl") {362 HasKL = true;363 } else if (Feature == "+widekl") {364 HasWIDEKL = true;365 } else if (Feature == "+retpoline-external-thunk") {366 HasRetpolineExternalThunk = true;367 } else if (Feature == "+sahf") {368 HasLAHFSAHF = true;369 } else if (Feature == "+waitpkg") {370 HasWAITPKG = true;371 } else if (Feature == "+movdiri") {372 HasMOVDIRI = true;373 } else if (Feature == "+movdir64b") {374 HasMOVDIR64B = true;375 } else if (Feature == "+pconfig") {376 HasPCONFIG = true;377 } else if (Feature == "+ptwrite") {378 HasPTWRITE = true;379 } else if (Feature == "+invpcid") {380 HasINVPCID = true;381 } else if (Feature == "+enqcmd") {382 HasENQCMD = true;383 } else if (Feature == "+hreset") {384 HasHRESET = true;385 } else if (Feature == "+amx-bf16") {386 HasAMXBF16 = true;387 } else if (Feature == "+amx-fp16") {388 HasAMXFP16 = true;389 } else if (Feature == "+amx-int8") {390 HasAMXINT8 = true;391 } else if (Feature == "+amx-tile") {392 HasAMXTILE = true;393 } else if (Feature == "+amx-complex") {394 HasAMXCOMPLEX = true;395 } else if (Feature == "+amx-fp8") {396 HasAMXFP8 = true;397 } else if (Feature == "+amx-movrs") {398 HasAMXMOVRS = true;399 } else if (Feature == "+amx-avx512") {400 HasAMXAVX512 = true;401 } else if (Feature == "+amx-tf32") {402 HasAMXTF32 = true;403 } else if (Feature == "+cmpccxadd") {404 HasCMPCCXADD = true;405 } else if (Feature == "+raoint") {406 HasRAOINT = true;407 } else if (Feature == "+avxifma") {408 HasAVXIFMA = true;409 } else if (Feature == "+avxneconvert") {410 HasAVXNECONVERT= true;411 } else if (Feature == "+avxvnni") {412 HasAVXVNNI = true;413 } else if (Feature == "+avxvnniint16") {414 HasAVXVNNIINT16 = true;415 } else if (Feature == "+avxvnniint8") {416 HasAVXVNNIINT8 = true;417 } else if (Feature == "+serialize") {418 HasSERIALIZE = true;419 } else if (Feature == "+tsxldtrk") {420 HasTSXLDTRK = true;421 } else if (Feature == "+uintr") {422 HasUINTR = true;423 } else if (Feature == "+usermsr") {424 HasUSERMSR = true;425 } else if (Feature == "+crc32") {426 HasCRC32 = true;427 } else if (Feature == "+x87") {428 HasX87 = true;429 } else if (Feature == "+fullbf16") {430 HasFullBFloat16 = true;431 } else if (Feature == "+egpr") {432 HasEGPR = true;433 } else if (Feature == "+inline-asm-use-gpr32") {434 HasInlineAsmUseGPR32 = true;435 } else if (Feature == "+push2pop2") {436 HasPush2Pop2 = true;437 } else if (Feature == "+ppx") {438 HasPPX = true;439 } else if (Feature == "+ndd") {440 HasNDD = true;441 } else if (Feature == "+ccmp") {442 HasCCMP = true;443 } else if (Feature == "+nf") {444 HasNF = true;445 } else if (Feature == "+cf") {446 HasCF = true;447 } else if (Feature == "+zu") {448 HasZU = true;449 } else if (Feature == "+branch-hint") {450 HasBranchHint = true;451 }452 453 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)454 .Case("+avx512f", AVX512F)455 .Case("+avx2", AVX2)456 .Case("+avx", AVX)457 .Case("+sse4.2", SSE42)458 .Case("+sse4.1", SSE41)459 .Case("+ssse3", SSSE3)460 .Case("+sse3", SSE3)461 .Case("+sse2", SSE2)462 .Case("+sse", SSE1)463 .Default(NoSSE);464 SSELevel = std::max(SSELevel, Level);465 466 HasFloat16 = SSELevel >= SSE2;467 468 // X86 target has bfloat16 emulation support in the backend, where469 // bfloat16 is treated as a 32-bit float, arithmetic operations are470 // performed in 32-bit, and the result is converted back to bfloat16.471 // Truncation and extension between bfloat16 and 32-bit float are supported472 // by the compiler-rt library. However, native bfloat16 support is currently473 // not available in the X86 target. Hence, HasFullBFloat16 will be false474 // until native bfloat16 support is available. HasFullBFloat16 is used to475 // determine whether to automatically use excess floating point precision476 // for bfloat16 arithmetic operations in the front-end.477 HasBFloat16 = SSELevel >= SSE2;478 479 XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)480 .Case("+xop", XOP)481 .Case("+fma4", FMA4)482 .Case("+sse4a", SSE4A)483 .Default(NoXOP);484 XOPLevel = std::max(XOPLevel, XLevel);485 }486 487 // LLVM doesn't have a separate switch for fpmath, so only accept it if it488 // matches the selected sse level.489 if ((FPMath == FP_SSE && SSELevel < SSE1) ||490 (FPMath == FP_387 && SSELevel >= SSE1)) {491 Diags.Report(diag::err_target_unsupported_fpmath)492 << (FPMath == FP_SSE ? "sse" : "387");493 return false;494 }495 496 // FIXME: We should allow long double type on 32-bits to match with GCC.497 // This requires backend to be able to lower f80 without x87 first.498 if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended())499 HasLongDouble = false;500 501 return true;502}503 504/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro505/// definitions for this particular subtarget.506void X86TargetInfo::getTargetDefines(const LangOptions &Opts,507 MacroBuilder &Builder) const {508 // Inline assembly supports X86 flag outputs.509 Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");510 511 std::string CodeModel = getTargetOpts().CodeModel;512 if (CodeModel == "default")513 CodeModel = "small";514 Builder.defineMacro("__code_model_" + CodeModel + "__");515 516 // Target identification.517 if (getTriple().getArch() == llvm::Triple::x86_64) {518 Builder.defineMacro("__amd64__");519 Builder.defineMacro("__amd64");520 Builder.defineMacro("__x86_64");521 Builder.defineMacro("__x86_64__");522 if (getTriple().getArchName() == "x86_64h") {523 Builder.defineMacro("__x86_64h");524 Builder.defineMacro("__x86_64h__");525 }526 } else {527 DefineStd(Builder, "i386", Opts);528 }529 530 Builder.defineMacro("__SEG_GS");531 Builder.defineMacro("__SEG_FS");532 Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))");533 Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))");534 535 // Subtarget options.536 // FIXME: We are hard-coding the tune parameters based on the CPU, but they537 // truly should be based on -mtune options.538 using namespace llvm::X86;539 switch (CPU) {540 case CK_None:541 break;542 case CK_i386:543 // The rest are coming from the i386 define above.544 Builder.defineMacro("__tune_i386__");545 break;546 case CK_i486:547 case CK_WinChipC6:548 case CK_WinChip2:549 case CK_C3:550 defineCPUMacros(Builder, "i486");551 break;552 case CK_PentiumMMX:553 Builder.defineMacro("__pentium_mmx__");554 Builder.defineMacro("__tune_pentium_mmx__");555 [[fallthrough]];556 case CK_i586:557 case CK_Pentium:558 defineCPUMacros(Builder, "i586");559 defineCPUMacros(Builder, "pentium");560 break;561 case CK_Pentium3:562 case CK_PentiumM:563 Builder.defineMacro("__tune_pentium3__");564 [[fallthrough]];565 case CK_Pentium2:566 case CK_C3_2:567 Builder.defineMacro("__tune_pentium2__");568 [[fallthrough]];569 case CK_PentiumPro:570 case CK_i686:571 defineCPUMacros(Builder, "i686");572 defineCPUMacros(Builder, "pentiumpro");573 break;574 case CK_Pentium4:575 defineCPUMacros(Builder, "pentium4");576 break;577 case CK_Yonah:578 case CK_Prescott:579 case CK_Nocona:580 defineCPUMacros(Builder, "nocona");581 break;582 case CK_Core2:583 case CK_Penryn:584 defineCPUMacros(Builder, "core2");585 break;586 case CK_Bonnell:587 defineCPUMacros(Builder, "atom");588 break;589 case CK_Silvermont:590 defineCPUMacros(Builder, "slm");591 break;592 case CK_Goldmont:593 defineCPUMacros(Builder, "goldmont");594 break;595 case CK_GoldmontPlus:596 defineCPUMacros(Builder, "goldmont_plus");597 break;598 case CK_Tremont:599 defineCPUMacros(Builder, "tremont");600 break;601 // Gracemont and later atom-cores use P-core cpu macros.602 case CK_Gracemont:603 case CK_Nehalem:604 case CK_Westmere:605 case CK_SandyBridge:606 case CK_IvyBridge:607 case CK_Haswell:608 case CK_Broadwell:609 case CK_SkylakeClient:610 case CK_SkylakeServer:611 case CK_Cascadelake:612 case CK_Cooperlake:613 case CK_Cannonlake:614 case CK_IcelakeClient:615 case CK_Rocketlake:616 case CK_IcelakeServer:617 case CK_Tigerlake:618 case CK_SapphireRapids:619 case CK_Alderlake:620 case CK_Raptorlake:621 case CK_Meteorlake:622 case CK_Arrowlake:623 case CK_ArrowlakeS:624 case CK_Lunarlake:625 case CK_Pantherlake:626 case CK_Wildcatlake:627 case CK_Novalake:628 case CK_Sierraforest:629 case CK_Grandridge:630 case CK_Graniterapids:631 case CK_GraniterapidsD:632 case CK_Emeraldrapids:633 case CK_Clearwaterforest:634 case CK_Diamondrapids:635 // FIXME: Historically, we defined this legacy name, it would be nice to636 // remove it at some point. We've never exposed fine-grained names for637 // recent primary x86 CPUs, and we should keep it that way.638 defineCPUMacros(Builder, "corei7");639 break;640 case CK_KNL:641 defineCPUMacros(Builder, "knl");642 break;643 case CK_KNM:644 break;645 case CK_Lakemont:646 defineCPUMacros(Builder, "i586", /*Tuning*/false);647 defineCPUMacros(Builder, "pentium", /*Tuning*/false);648 Builder.defineMacro("__tune_lakemont__");649 break;650 case CK_K6_2:651 Builder.defineMacro("__k6_2__");652 Builder.defineMacro("__tune_k6_2__");653 [[fallthrough]];654 case CK_K6_3:655 if (CPU != CK_K6_2) { // In case of fallthrough656 // FIXME: GCC may be enabling these in cases where some other k6657 // architecture is specified but -m3dnow is explicitly provided. The658 // exact semantics need to be determined and emulated here.659 Builder.defineMacro("__k6_3__");660 Builder.defineMacro("__tune_k6_3__");661 }662 [[fallthrough]];663 case CK_K6:664 defineCPUMacros(Builder, "k6");665 break;666 case CK_Athlon:667 case CK_AthlonXP:668 defineCPUMacros(Builder, "athlon");669 if (SSELevel != NoSSE) {670 Builder.defineMacro("__athlon_sse__");671 Builder.defineMacro("__tune_athlon_sse__");672 }673 break;674 case CK_K8:675 case CK_K8SSE3:676 case CK_x86_64:677 defineCPUMacros(Builder, "k8");678 break;679 case CK_x86_64_v2:680 case CK_x86_64_v3:681 case CK_x86_64_v4:682 break;683 case CK_AMDFAM10:684 defineCPUMacros(Builder, "amdfam10");685 break;686 case CK_BTVER1:687 defineCPUMacros(Builder, "btver1");688 break;689 case CK_BTVER2:690 defineCPUMacros(Builder, "btver2");691 break;692 case CK_BDVER1:693 defineCPUMacros(Builder, "bdver1");694 break;695 case CK_BDVER2:696 defineCPUMacros(Builder, "bdver2");697 break;698 case CK_BDVER3:699 defineCPUMacros(Builder, "bdver3");700 break;701 case CK_BDVER4:702 defineCPUMacros(Builder, "bdver4");703 break;704 case CK_ZNVER1:705 defineCPUMacros(Builder, "znver1");706 break;707 case CK_ZNVER2:708 defineCPUMacros(Builder, "znver2");709 break;710 case CK_ZNVER3:711 defineCPUMacros(Builder, "znver3");712 break;713 case CK_ZNVER4:714 defineCPUMacros(Builder, "znver4");715 break;716 case CK_ZNVER5:717 defineCPUMacros(Builder, "znver5");718 break;719 case CK_Geode:720 defineCPUMacros(Builder, "geode");721 break;722 }723 724 // Target properties.725 Builder.defineMacro("__REGISTER_PREFIX__", "");726 727 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline728 // functions in glibc header files that use FP Stack inline asm which the729 // backend can't deal with (PR879).730 Builder.defineMacro("__NO_MATH_INLINES");731 732 if (HasAES)733 Builder.defineMacro("__AES__");734 735 if (HasVAES)736 Builder.defineMacro("__VAES__");737 738 if (HasPCLMUL)739 Builder.defineMacro("__PCLMUL__");740 741 if (HasVPCLMULQDQ)742 Builder.defineMacro("__VPCLMULQDQ__");743 744 // Note, in 32-bit mode, GCC does not define the macro if -mno-sahf. In LLVM,745 // the feature flag only applies to 64-bit mode.746 if (HasLAHFSAHF || getTriple().getArch() == llvm::Triple::x86)747 Builder.defineMacro("__LAHF_SAHF__");748 749 if (HasLZCNT)750 Builder.defineMacro("__LZCNT__");751 752 if (HasRDRND)753 Builder.defineMacro("__RDRND__");754 755 if (HasFSGSBASE)756 Builder.defineMacro("__FSGSBASE__");757 758 if (HasBMI)759 Builder.defineMacro("__BMI__");760 761 if (HasBMI2)762 Builder.defineMacro("__BMI2__");763 764 if (HasPOPCNT)765 Builder.defineMacro("__POPCNT__");766 767 if (HasRTM)768 Builder.defineMacro("__RTM__");769 770 if (HasPRFCHW)771 Builder.defineMacro("__PRFCHW__");772 773 if (HasRDSEED)774 Builder.defineMacro("__RDSEED__");775 776 if (HasADX)777 Builder.defineMacro("__ADX__");778 779 if (HasTBM)780 Builder.defineMacro("__TBM__");781 782 if (HasLWP)783 Builder.defineMacro("__LWP__");784 785 if (HasMWAITX)786 Builder.defineMacro("__MWAITX__");787 788 if (HasMOVBE)789 Builder.defineMacro("__MOVBE__");790 791 switch (XOPLevel) {792 case XOP:793 Builder.defineMacro("__XOP__");794 [[fallthrough]];795 case FMA4:796 Builder.defineMacro("__FMA4__");797 [[fallthrough]];798 case SSE4A:799 Builder.defineMacro("__SSE4A__");800 [[fallthrough]];801 case NoXOP:802 break;803 }804 805 if (HasFMA)806 Builder.defineMacro("__FMA__");807 808 if (HasF16C)809 Builder.defineMacro("__F16C__");810 811 if (HasGFNI)812 Builder.defineMacro("__GFNI__");813 814 if (HasAVX10_1) {815 Builder.defineMacro("__AVX10_1__");816 Builder.defineMacro("__AVX10_1_512__");817 }818 if (HasAVX10_2) {819 Builder.defineMacro("__AVX10_2__");820 Builder.defineMacro("__AVX10_2_512__");821 }822 if (HasAVX512CD)823 Builder.defineMacro("__AVX512CD__");824 if (HasAVX512VPOPCNTDQ)825 Builder.defineMacro("__AVX512VPOPCNTDQ__");826 if (HasAVX512VNNI)827 Builder.defineMacro("__AVX512VNNI__");828 if (HasAVX512BF16)829 Builder.defineMacro("__AVX512BF16__");830 if (HasAVX512FP16)831 Builder.defineMacro("__AVX512FP16__");832 if (HasAVX512DQ)833 Builder.defineMacro("__AVX512DQ__");834 if (HasAVX512BITALG)835 Builder.defineMacro("__AVX512BITALG__");836 if (HasAVX512BW)837 Builder.defineMacro("__AVX512BW__");838 if (HasAVX512VL) {839 Builder.defineMacro("__AVX512VL__");840 }841 if (HasAVX512VBMI)842 Builder.defineMacro("__AVX512VBMI__");843 if (HasAVX512VBMI2)844 Builder.defineMacro("__AVX512VBMI2__");845 if (HasAVX512IFMA)846 Builder.defineMacro("__AVX512IFMA__");847 if (HasAVX512VP2INTERSECT)848 Builder.defineMacro("__AVX512VP2INTERSECT__");849 if (HasSHA)850 Builder.defineMacro("__SHA__");851 if (HasSHA512)852 Builder.defineMacro("__SHA512__");853 854 if (HasFXSR)855 Builder.defineMacro("__FXSR__");856 if (HasXSAVE)857 Builder.defineMacro("__XSAVE__");858 if (HasXSAVEOPT)859 Builder.defineMacro("__XSAVEOPT__");860 if (HasXSAVEC)861 Builder.defineMacro("__XSAVEC__");862 if (HasXSAVES)863 Builder.defineMacro("__XSAVES__");864 if (HasPKU)865 Builder.defineMacro("__PKU__");866 if (HasCLFLUSHOPT)867 Builder.defineMacro("__CLFLUSHOPT__");868 if (HasCLWB)869 Builder.defineMacro("__CLWB__");870 if (HasWBNOINVD)871 Builder.defineMacro("__WBNOINVD__");872 if (HasSHSTK)873 Builder.defineMacro("__SHSTK__");874 if (HasSGX)875 Builder.defineMacro("__SGX__");876 if (HasSM3)877 Builder.defineMacro("__SM3__");878 if (HasSM4)879 Builder.defineMacro("__SM4__");880 if (HasPREFETCHI)881 Builder.defineMacro("__PREFETCHI__");882 if (HasCLZERO)883 Builder.defineMacro("__CLZERO__");884 if (HasKL)885 Builder.defineMacro("__KL__");886 if (HasWIDEKL)887 Builder.defineMacro("__WIDEKL__");888 if (HasRDPID)889 Builder.defineMacro("__RDPID__");890 if (HasRDPRU)891 Builder.defineMacro("__RDPRU__");892 if (HasCLDEMOTE)893 Builder.defineMacro("__CLDEMOTE__");894 if (HasWAITPKG)895 Builder.defineMacro("__WAITPKG__");896 if (HasMOVDIRI)897 Builder.defineMacro("__MOVDIRI__");898 if (HasMOVDIR64B)899 Builder.defineMacro("__MOVDIR64B__");900 if (HasMOVRS)901 Builder.defineMacro("__MOVRS__");902 if (HasPCONFIG)903 Builder.defineMacro("__PCONFIG__");904 if (HasPTWRITE)905 Builder.defineMacro("__PTWRITE__");906 if (HasINVPCID)907 Builder.defineMacro("__INVPCID__");908 if (HasENQCMD)909 Builder.defineMacro("__ENQCMD__");910 if (HasHRESET)911 Builder.defineMacro("__HRESET__");912 if (HasAMXTILE)913 Builder.defineMacro("__AMX_TILE__");914 if (HasAMXINT8)915 Builder.defineMacro("__AMX_INT8__");916 if (HasAMXBF16)917 Builder.defineMacro("__AMX_BF16__");918 if (HasAMXFP16)919 Builder.defineMacro("__AMX_FP16__");920 if (HasAMXCOMPLEX)921 Builder.defineMacro("__AMX_COMPLEX__");922 if (HasAMXFP8)923 Builder.defineMacro("__AMX_FP8__");924 if (HasAMXMOVRS)925 Builder.defineMacro("__AMX_MOVRS__");926 if (HasAMXAVX512)927 Builder.defineMacro("__AMX_AVX512__");928 if (HasAMXTF32)929 Builder.defineMacro("__AMX_TF32__");930 if (HasCMPCCXADD)931 Builder.defineMacro("__CMPCCXADD__");932 if (HasRAOINT)933 Builder.defineMacro("__RAOINT__");934 if (HasAVXIFMA)935 Builder.defineMacro("__AVXIFMA__");936 if (HasAVXNECONVERT)937 Builder.defineMacro("__AVXNECONVERT__");938 if (HasAVXVNNI)939 Builder.defineMacro("__AVXVNNI__");940 if (HasAVXVNNIINT16)941 Builder.defineMacro("__AVXVNNIINT16__");942 if (HasAVXVNNIINT8)943 Builder.defineMacro("__AVXVNNIINT8__");944 if (HasSERIALIZE)945 Builder.defineMacro("__SERIALIZE__");946 if (HasTSXLDTRK)947 Builder.defineMacro("__TSXLDTRK__");948 if (HasUINTR)949 Builder.defineMacro("__UINTR__");950 if (HasUSERMSR)951 Builder.defineMacro("__USERMSR__");952 if (HasCRC32)953 Builder.defineMacro("__CRC32__");954 if (HasEGPR)955 Builder.defineMacro("__EGPR__");956 if (HasPush2Pop2)957 Builder.defineMacro("__PUSH2POP2__");958 if (HasPPX)959 Builder.defineMacro("__PPX__");960 if (HasNDD)961 Builder.defineMacro("__NDD__");962 if (HasCCMP)963 Builder.defineMacro("__CCMP__");964 if (HasNF)965 Builder.defineMacro("__NF__");966 if (HasCF)967 Builder.defineMacro("__CF__");968 if (HasZU)969 Builder.defineMacro("__ZU__");970 if (HasEGPR && HasPush2Pop2 && HasPPX && HasNDD && HasCCMP && HasNF && HasZU)971 Builder.defineMacro("__APX_F__");972 if (HasEGPR && HasInlineAsmUseGPR32)973 Builder.defineMacro("__APX_INLINE_ASM_USE_GPR32__");974 975 // Each case falls through to the previous one here.976 switch (SSELevel) {977 case AVX512F:978 Builder.defineMacro("__AVX512F__");979 [[fallthrough]];980 case AVX2:981 Builder.defineMacro("__AVX2__");982 [[fallthrough]];983 case AVX:984 Builder.defineMacro("__AVX__");985 [[fallthrough]];986 case SSE42:987 Builder.defineMacro("__SSE4_2__");988 [[fallthrough]];989 case SSE41:990 Builder.defineMacro("__SSE4_1__");991 [[fallthrough]];992 case SSSE3:993 Builder.defineMacro("__SSSE3__");994 [[fallthrough]];995 case SSE3:996 Builder.defineMacro("__SSE3__");997 [[fallthrough]];998 case SSE2:999 Builder.defineMacro("__SSE2__");1000 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.1001 [[fallthrough]];1002 case SSE1:1003 Builder.defineMacro("__SSE__");1004 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.1005 [[fallthrough]];1006 case NoSSE:1007 break;1008 }1009 1010 if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {1011 switch (SSELevel) {1012 case AVX512F:1013 case AVX2:1014 case AVX:1015 case SSE42:1016 case SSE41:1017 case SSSE3:1018 case SSE3:1019 case SSE2:1020 Builder.defineMacro("_M_IX86_FP", Twine(2));1021 break;1022 case SSE1:1023 Builder.defineMacro("_M_IX86_FP", Twine(1));1024 break;1025 default:1026 Builder.defineMacro("_M_IX86_FP", Twine(0));1027 break;1028 }1029 }1030 1031 // Each case falls through to the previous one here.1032 if (HasMMX) {1033 Builder.defineMacro("__MMX__");1034 }1035 1036 if (CPU >= CK_i486 || CPU == CK_None) {1037 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");1038 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");1039 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");1040 }1041 if (HasCX8)1042 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");1043 if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)1044 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");1045 1046 if (HasFloat128)1047 Builder.defineMacro("__SIZEOF_FLOAT128__", "16");1048 1049 if (Opts.CFProtectionReturn || Opts.CFProtectionBranch)1050 Builder.defineMacro("__CET__", Twine{(Opts.CFProtectionReturn << 1) |1051 Opts.CFProtectionBranch});1052}1053 1054bool X86TargetInfo::isValidFeatureName(StringRef Name) const {1055 return llvm::StringSwitch<bool>(Name)1056 .Case("adx", true)1057 .Case("aes", true)1058 .Case("amx-avx512", true)1059 .Case("amx-bf16", true)1060 .Case("amx-complex", true)1061 .Case("amx-fp16", true)1062 .Case("amx-fp8", true)1063 .Case("amx-int8", true)1064 .Case("amx-movrs", true)1065 .Case("amx-tf32", true)1066 .Case("amx-tile", true)1067 .Case("avx", true)1068 .Case("avx10.1", true)1069 .Case("avx10.2", true)1070 .Case("avx2", true)1071 .Case("avx512f", true)1072 .Case("avx512cd", true)1073 .Case("avx512vpopcntdq", true)1074 .Case("avx512vnni", true)1075 .Case("avx512bf16", true)1076 .Case("avx512fp16", true)1077 .Case("avx512dq", true)1078 .Case("avx512bitalg", true)1079 .Case("avx512bw", true)1080 .Case("avx512vl", true)1081 .Case("avx512vbmi", true)1082 .Case("avx512vbmi2", true)1083 .Case("avx512ifma", true)1084 .Case("avx512vp2intersect", true)1085 .Case("avxifma", true)1086 .Case("avxneconvert", true)1087 .Case("avxvnni", true)1088 .Case("avxvnniint16", true)1089 .Case("avxvnniint8", true)1090 .Case("bmi", true)1091 .Case("bmi2", true)1092 .Case("cldemote", true)1093 .Case("clflushopt", true)1094 .Case("clwb", true)1095 .Case("clzero", true)1096 .Case("cmpccxadd", true)1097 .Case("crc32", true)1098 .Case("cx16", true)1099 .Case("enqcmd", true)1100 .Case("f16c", true)1101 .Case("fma", true)1102 .Case("fma4", true)1103 .Case("fsgsbase", true)1104 .Case("fxsr", true)1105 .Case("general-regs-only", true)1106 .Case("gfni", true)1107 .Case("hreset", true)1108 .Case("invpcid", true)1109 .Case("kl", true)1110 .Case("widekl", true)1111 .Case("lwp", true)1112 .Case("lzcnt", true)1113 .Case("mmx", true)1114 .Case("movbe", true)1115 .Case("movrs", true)1116 .Case("movdiri", true)1117 .Case("movdir64b", true)1118 .Case("mwaitx", true)1119 .Case("pclmul", true)1120 .Case("pconfig", true)1121 .Case("pku", true)1122 .Case("popcnt", true)1123 .Case("prefer-256-bit", true)1124 .Case("prefetchi", true)1125 .Case("prfchw", true)1126 .Case("ptwrite", true)1127 .Case("raoint", true)1128 .Case("rdpid", true)1129 .Case("rdpru", true)1130 .Case("rdrnd", true)1131 .Case("rdseed", true)1132 .Case("rtm", true)1133 .Case("sahf", true)1134 .Case("serialize", true)1135 .Case("sgx", true)1136 .Case("sha", true)1137 .Case("sha512", true)1138 .Case("shstk", true)1139 .Case("sm3", true)1140 .Case("sm4", true)1141 .Case("sse", true)1142 .Case("sse2", true)1143 .Case("sse3", true)1144 .Case("ssse3", true)1145 .Case("sse4", true)1146 .Case("sse4.1", true)1147 .Case("sse4.2", true)1148 .Case("sse4a", true)1149 .Case("tbm", true)1150 .Case("tsxldtrk", true)1151 .Case("uintr", true)1152 .Case("usermsr", true)1153 .Case("vaes", true)1154 .Case("vpclmulqdq", true)1155 .Case("wbnoinvd", true)1156 .Case("waitpkg", true)1157 .Case("x87", true)1158 .Case("xop", true)1159 .Case("xsave", true)1160 .Case("xsavec", true)1161 .Case("xsaves", true)1162 .Case("xsaveopt", true)1163 .Case("egpr", true)1164 .Case("push2pop2", true)1165 .Case("ppx", true)1166 .Case("ndd", true)1167 .Case("ccmp", true)1168 .Case("nf", true)1169 .Case("cf", true)1170 .Case("zu", true)1171 .Default(false);1172}1173 1174bool X86TargetInfo::hasFeature(StringRef Feature) const {1175 return llvm::StringSwitch<bool>(Feature)1176 .Case("adx", HasADX)1177 .Case("aes", HasAES)1178 .Case("amx-avx512", HasAMXAVX512)1179 .Case("amx-bf16", HasAMXBF16)1180 .Case("amx-complex", HasAMXCOMPLEX)1181 .Case("amx-fp16", HasAMXFP16)1182 .Case("amx-fp8", HasAMXFP8)1183 .Case("amx-int8", HasAMXINT8)1184 .Case("amx-movrs", HasAMXMOVRS)1185 .Case("amx-tf32", HasAMXTF32)1186 .Case("amx-tile", HasAMXTILE)1187 .Case("avx", SSELevel >= AVX)1188 .Case("avx10.1", HasAVX10_1)1189 .Case("avx10.2", HasAVX10_2)1190 .Case("avx2", SSELevel >= AVX2)1191 .Case("avx512f", SSELevel >= AVX512F)1192 .Case("avx512cd", HasAVX512CD)1193 .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ)1194 .Case("avx512vnni", HasAVX512VNNI)1195 .Case("avx512bf16", HasAVX512BF16)1196 .Case("avx512fp16", HasAVX512FP16)1197 .Case("avx512dq", HasAVX512DQ)1198 .Case("avx512bitalg", HasAVX512BITALG)1199 .Case("avx512bw", HasAVX512BW)1200 .Case("avx512vl", HasAVX512VL)1201 .Case("avx512vbmi", HasAVX512VBMI)1202 .Case("avx512vbmi2", HasAVX512VBMI2)1203 .Case("avx512ifma", HasAVX512IFMA)1204 .Case("avx512vp2intersect", HasAVX512VP2INTERSECT)1205 .Case("avxifma", HasAVXIFMA)1206 .Case("avxneconvert", HasAVXNECONVERT)1207 .Case("avxvnni", HasAVXVNNI)1208 .Case("avxvnniint16", HasAVXVNNIINT16)1209 .Case("avxvnniint8", HasAVXVNNIINT8)1210 .Case("bmi", HasBMI)1211 .Case("bmi2", HasBMI2)1212 .Case("cldemote", HasCLDEMOTE)1213 .Case("clflushopt", HasCLFLUSHOPT)1214 .Case("clwb", HasCLWB)1215 .Case("clzero", HasCLZERO)1216 .Case("cmpccxadd", HasCMPCCXADD)1217 .Case("crc32", HasCRC32)1218 .Case("cx8", HasCX8)1219 .Case("cx16", HasCX16)1220 .Case("enqcmd", HasENQCMD)1221 .Case("f16c", HasF16C)1222 .Case("fma", HasFMA)1223 .Case("fma4", XOPLevel >= FMA4)1224 .Case("fsgsbase", HasFSGSBASE)1225 .Case("fxsr", HasFXSR)1226 .Case("gfni", HasGFNI)1227 .Case("hreset", HasHRESET)1228 .Case("invpcid", HasINVPCID)1229 .Case("kl", HasKL)1230 .Case("widekl", HasWIDEKL)1231 .Case("lwp", HasLWP)1232 .Case("lzcnt", HasLZCNT)1233 .Case("mmx", HasMMX)1234 .Case("movbe", HasMOVBE)1235 .Case("movrs", HasMOVRS)1236 .Case("movdiri", HasMOVDIRI)1237 .Case("movdir64b", HasMOVDIR64B)1238 .Case("mwaitx", HasMWAITX)1239 .Case("pclmul", HasPCLMUL)1240 .Case("pconfig", HasPCONFIG)1241 .Case("pku", HasPKU)1242 .Case("popcnt", HasPOPCNT)1243 .Case("prefetchi", HasPREFETCHI)1244 .Case("prfchw", HasPRFCHW)1245 .Case("ptwrite", HasPTWRITE)1246 .Case("raoint", HasRAOINT)1247 .Case("rdpid", HasRDPID)1248 .Case("rdpru", HasRDPRU)1249 .Case("rdrnd", HasRDRND)1250 .Case("rdseed", HasRDSEED)1251 .Case("retpoline-external-thunk", HasRetpolineExternalThunk)1252 .Case("rtm", HasRTM)1253 .Case("sahf", HasLAHFSAHF)1254 .Case("serialize", HasSERIALIZE)1255 .Case("sgx", HasSGX)1256 .Case("sha", HasSHA)1257 .Case("sha512", HasSHA512)1258 .Case("shstk", HasSHSTK)1259 .Case("sm3", HasSM3)1260 .Case("sm4", HasSM4)1261 .Case("sse", SSELevel >= SSE1)1262 .Case("sse2", SSELevel >= SSE2)1263 .Case("sse3", SSELevel >= SSE3)1264 .Case("ssse3", SSELevel >= SSSE3)1265 .Case("sse4.1", SSELevel >= SSE41)1266 .Case("sse4.2", SSELevel >= SSE42)1267 .Case("sse4a", XOPLevel >= SSE4A)1268 .Case("tbm", HasTBM)1269 .Case("tsxldtrk", HasTSXLDTRK)1270 .Case("uintr", HasUINTR)1271 .Case("usermsr", HasUSERMSR)1272 .Case("vaes", HasVAES)1273 .Case("vpclmulqdq", HasVPCLMULQDQ)1274 .Case("wbnoinvd", HasWBNOINVD)1275 .Case("waitpkg", HasWAITPKG)1276 .Case("x86", true)1277 .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)1278 .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)1279 .Case("x87", HasX87)1280 .Case("xop", XOPLevel >= XOP)1281 .Case("xsave", HasXSAVE)1282 .Case("xsavec", HasXSAVEC)1283 .Case("xsaves", HasXSAVES)1284 .Case("xsaveopt", HasXSAVEOPT)1285 .Case("fullbf16", HasFullBFloat16)1286 .Case("egpr", HasEGPR)1287 .Case("push2pop2", HasPush2Pop2)1288 .Case("ppx", HasPPX)1289 .Case("ndd", HasNDD)1290 .Case("ccmp", HasCCMP)1291 .Case("nf", HasNF)1292 .Case("cf", HasCF)1293 .Case("zu", HasZU)1294 .Case("branch-hint", HasBranchHint)1295 .Default(false);1296}1297 1298// We can't use a generic validation scheme for the features accepted here1299// versus subtarget features accepted in the target attribute because the1300// bitfield structure that's initialized in the runtime only supports the1301// below currently rather than the full range of subtarget features. (See1302// X86TargetInfo::hasFeature for a somewhat comprehensive list).1303bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {1304 return llvm::StringSwitch<bool>(FeatureStr)1305#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY, ABI_VALUE) .Case(STR, true)1306#define X86_MICROARCH_LEVEL(ENUM, STR, PRIORITY, ABI_VALUE) .Case(STR, true)1307#include "llvm/TargetParser/X86TargetParser.def"1308 .Default(false);1309}1310 1311static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {1312 return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)1313#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY, ABI_VALUE) \1314 .Case(STR, llvm::X86::FEATURE_##ENUM)1315 1316#include "llvm/TargetParser/X86TargetParser.def"1317 ;1318 // Note, this function should only be used after ensuring the value is1319 // correct, so it asserts if the value is out of range.1320}1321 1322llvm::APInt X86TargetInfo::getFMVPriority(ArrayRef<StringRef> Features) const {1323 auto getPriority = [](StringRef Feature) -> unsigned {1324 // Valid CPUs have a 'key feature' that compares just better than its key1325 // feature.1326 using namespace llvm::X86;1327 CPUKind Kind = parseArchX86(Feature);1328 if (Kind != CK_None) {1329 ProcessorFeatures KeyFeature = getKeyFeature(Kind);1330 return (getFeaturePriority(KeyFeature) << 1) + 1;1331 }1332 // Now we know we have a feature, so get its priority and shift it a few so1333 // that we have sufficient room for the CPUs (above).1334 return getFeaturePriority(getFeature(Feature)) << 1;1335 };1336 1337 unsigned Priority = 0;1338 for (StringRef Feature : Features)1339 if (!Feature.empty())1340 Priority = std::max(Priority, getPriority(Feature));1341 return llvm::APInt(32, Priority);1342}1343 1344bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const {1345 return llvm::X86::validateCPUSpecificCPUDispatch(Name);1346}1347 1348char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const {1349 return llvm::X86::getCPUDispatchMangling(Name);1350}1351 1352void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(1353 StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {1354 SmallVector<StringRef, 32> TargetCPUFeatures;1355 llvm::X86::getFeaturesForCPU(Name, TargetCPUFeatures, true);1356 for (auto &F : TargetCPUFeatures)1357 Features.push_back(F);1358}1359 1360// We can't use a generic validation scheme for the cpus accepted here1361// versus subtarget cpus accepted in the target attribute because the1362// variables intitialized by the runtime only support the below currently1363// rather than the full range of cpus.1364bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {1365 return llvm::StringSwitch<bool>(FeatureStr)1366#define X86_VENDOR(ENUM, STRING) .Case(STRING, true)1367#define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)1368#define X86_CPU_TYPE(ENUM, STR) .Case(STR, true)1369#define X86_CPU_SUBTYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)1370#define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true)1371#include "llvm/TargetParser/X86TargetParser.def"1372 .Default(false);1373}1374 1375static unsigned matchAsmCCConstraint(const char *Name) {1376 auto RV = llvm::StringSwitch<unsigned>(Name)1377 .Case("@cca", 4)1378 .Case("@ccae", 5)1379 .Case("@ccb", 4)1380 .Case("@ccbe", 5)1381 .Case("@ccc", 4)1382 .Case("@cce", 4)1383 .Case("@ccz", 4)1384 .Case("@ccg", 4)1385 .Case("@ccge", 5)1386 .Case("@ccl", 4)1387 .Case("@ccle", 5)1388 .Case("@ccna", 5)1389 .Case("@ccnae", 6)1390 .Case("@ccnb", 5)1391 .Case("@ccnbe", 6)1392 .Case("@ccnc", 5)1393 .Case("@ccne", 5)1394 .Case("@ccnz", 5)1395 .Case("@ccng", 5)1396 .Case("@ccnge", 6)1397 .Case("@ccnl", 5)1398 .Case("@ccnle", 6)1399 .Case("@ccno", 5)1400 .Case("@ccnp", 5)1401 .Case("@ccns", 5)1402 .Case("@cco", 4)1403 .Case("@ccp", 4)1404 .Case("@ccs", 4)1405 .Default(0);1406 return RV;1407}1408 1409bool X86TargetInfo::validateAsmConstraint(1410 const char *&Name, TargetInfo::ConstraintInfo &Info) const {1411 switch (*Name) {1412 default:1413 return false;1414 // Constant constraints.1415 case 'e': // 32-bit signed integer constant for use with sign-extending x86_641416 // instructions.1417 case 'Z': // 32-bit unsigned integer constant for use with zero-extending1418 // x86_64 instructions.1419 case 's':1420 Info.setRequiresImmediate();1421 return true;1422 case 'I':1423 Info.setRequiresImmediate(0, 31);1424 return true;1425 case 'J':1426 Info.setRequiresImmediate(0, 63);1427 return true;1428 case 'K':1429 Info.setRequiresImmediate(-128, 127);1430 return true;1431 case 'L':1432 Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)});1433 return true;1434 case 'M':1435 Info.setRequiresImmediate(0, 3);1436 return true;1437 case 'N':1438 Info.setRequiresImmediate(0, 255);1439 return true;1440 case 'O':1441 Info.setRequiresImmediate(0, 127);1442 return true;1443 case 'W':1444 switch (*++Name) {1445 default:1446 return false;1447 case 's':1448 Info.setAllowsRegister();1449 return true;1450 }1451 // Register constraints.1452 case 'Y': // 'Y' is the first character for several 2-character constraints.1453 // Shift the pointer to the second character of the constraint.1454 Name++;1455 switch (*Name) {1456 default:1457 return false;1458 case 'z': // First SSE register.1459 case '2':1460 case 't': // Any SSE register, when SSE2 is enabled.1461 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.1462 case 'm': // Any MMX register, when inter-unit moves enabled.1463 case 'k': // AVX512 arch mask registers: k1-k7.1464 Info.setAllowsRegister();1465 return true;1466 }1467 case 'f': // Any x87 floating point stack register.1468 // Constraint 'f' cannot be used for output operands.1469 if (Info.ConstraintStr[0] == '=' || Info.ConstraintStr[0] == '+')1470 return false;1471 Info.setAllowsRegister();1472 return true;1473 case 'a': // eax.1474 case 'b': // ebx.1475 case 'c': // ecx.1476 case 'd': // edx.1477 case 'S': // esi.1478 case 'D': // edi.1479 case 'A': // edx:eax.1480 case 't': // Top of floating point stack.1481 case 'u': // Second from top of floating point stack.1482 case 'q': // Any register accessible as [r]l: a, b, c, and d.1483 case 'y': // Any MMX register.1484 case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)1485 case 'x': // Any SSE register.1486 case 'k': // Any AVX512 mask register (same as Yk, additionally allows k01487 // for intermideate k reg operations).1488 case 'Q': // Any register accessible as [r]h: a, b, c, and d.1489 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.1490 case 'l': // "Index" registers: any general register that can be used as an1491 // index in a base+index memory access.1492 Info.setAllowsRegister();1493 return true;1494 // Floating point constant constraints.1495 case 'C': // SSE floating point constant.1496 case 'G': // x87 floating point constant.1497 return true;1498 case 'j':1499 Name++;1500 switch (*Name) {1501 default:1502 return false;1503 case 'r':1504 Info.setAllowsRegister();1505 return true;1506 case 'R':1507 Info.setAllowsRegister();1508 return true;1509 }1510 case '@':1511 // CC condition changes.1512 if (auto Len = matchAsmCCConstraint(Name)) {1513 Name += Len - 1;1514 Info.setAllowsRegister();1515 Info.setOutputOperandBounds(0, 2);1516 return true;1517 }1518 return false;1519 }1520}1521 1522// Below is based on the following information:1523// +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+1524// | Processor Name | Cache Line Size (Bytes) | Source |1525// +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+1526// | i386 | 64 | https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf |1527// | 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) |1528// | i586/Pentium MMX | 32 | https://www.7-cpu.com/cpu/P-MMX.html |1529// | i686/Pentium | 32 | https://www.7-cpu.com/cpu/P6.html |1530// | Netburst/Pentium4 | 64 | https://www.7-cpu.com/cpu/P4-180.html |1531// | Atom | 64 | https://www.7-cpu.com/cpu/Atom.html |1532// | Westmere | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/sandy_bridge_(client) "Cache Architecture" |1533// | Sandy Bridge | 64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html |1534// | Ivy Bridge | 64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html |1535// | Haswell | 64 | https://www.7-cpu.com/cpu/Haswell.html |1536// | Broadwell | 64 | https://www.7-cpu.com/cpu/Broadwell.html |1537// | Skylake (including skylake-avx512) | 64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy" |1538// | Cascade Lake | 64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy" |1539// | Skylake | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy" |1540// | Ice Lake | 64 | https://www.7-cpu.com/cpu/Ice_Lake.html |1541// | 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" |1542// | 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 " |1543// +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+1544std::optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {1545 using namespace llvm::X86;1546 switch (CPU) {1547 // i3861548 case CK_i386:1549 // i4861550 case CK_i486:1551 case CK_WinChipC6:1552 case CK_WinChip2:1553 case CK_C3:1554 // Lakemont1555 case CK_Lakemont:1556 return 16;1557 1558 // i5861559 case CK_i586:1560 case CK_Pentium:1561 case CK_PentiumMMX:1562 // i6861563 case CK_PentiumPro:1564 case CK_i686:1565 case CK_Pentium2:1566 case CK_Pentium3:1567 case CK_PentiumM:1568 case CK_C3_2:1569 // K61570 case CK_K6:1571 case CK_K6_2:1572 case CK_K6_3:1573 // Geode1574 case CK_Geode:1575 return 32;1576 1577 // Netburst1578 case CK_Pentium4:1579 case CK_Prescott:1580 case CK_Nocona:1581 // Atom1582 case CK_Bonnell:1583 case CK_Silvermont:1584 case CK_Goldmont:1585 case CK_GoldmontPlus:1586 case CK_Tremont:1587 case CK_Gracemont:1588 1589 case CK_Westmere:1590 case CK_SandyBridge:1591 case CK_IvyBridge:1592 case CK_Haswell:1593 case CK_Broadwell:1594 case CK_SkylakeClient:1595 case CK_SkylakeServer:1596 case CK_Cascadelake:1597 case CK_Nehalem:1598 case CK_Cooperlake:1599 case CK_Cannonlake:1600 case CK_Tigerlake:1601 case CK_SapphireRapids:1602 case CK_IcelakeClient:1603 case CK_Rocketlake:1604 case CK_IcelakeServer:1605 case CK_Alderlake:1606 case CK_Raptorlake:1607 case CK_Meteorlake:1608 case CK_Arrowlake:1609 case CK_ArrowlakeS:1610 case CK_Lunarlake:1611 case CK_Pantherlake:1612 case CK_Wildcatlake:1613 case CK_Novalake:1614 case CK_Sierraforest:1615 case CK_Grandridge:1616 case CK_Graniterapids:1617 case CK_GraniterapidsD:1618 case CK_Emeraldrapids:1619 case CK_Clearwaterforest:1620 case CK_Diamondrapids:1621 case CK_KNL:1622 case CK_KNM:1623 // K71624 case CK_Athlon:1625 case CK_AthlonXP:1626 // K81627 case CK_K8:1628 case CK_K8SSE3:1629 case CK_AMDFAM10:1630 // Bobcat1631 case CK_BTVER1:1632 case CK_BTVER2:1633 // Bulldozer1634 case CK_BDVER1:1635 case CK_BDVER2:1636 case CK_BDVER3:1637 case CK_BDVER4:1638 // Zen1639 case CK_ZNVER1:1640 case CK_ZNVER2:1641 case CK_ZNVER3:1642 case CK_ZNVER4:1643 case CK_ZNVER5:1644 // Deprecated1645 case CK_x86_64:1646 case CK_x86_64_v2:1647 case CK_x86_64_v3:1648 case CK_x86_64_v4:1649 case CK_Yonah:1650 case CK_Penryn:1651 case CK_Core2:1652 return 64;1653 1654 // The following currently have unknown cache line sizes (but they are probably all 64):1655 // Core1656 case CK_None:1657 return std::nullopt;1658 }1659 llvm_unreachable("Unknown CPU kind");1660}1661 1662bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap,1663 StringRef Constraint,1664 unsigned Size) const {1665 // Strip off constraint modifiers.1666 Constraint = Constraint.ltrim("=+&");1667 1668 return validateOperandSize(FeatureMap, Constraint, Size);1669}1670 1671bool X86TargetInfo::validateInputSize(const llvm::StringMap<bool> &FeatureMap,1672 StringRef Constraint,1673 unsigned Size) const {1674 return validateOperandSize(FeatureMap, Constraint, Size);1675}1676 1677bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,1678 StringRef Constraint,1679 unsigned Size) const {1680 switch (Constraint[0]) {1681 default:1682 break;1683 case 'k':1684 // Registers k0-k7 (AVX512) size limit is 64 bit.1685 case 'y':1686 return Size <= 64;1687 case 'f':1688 case 't':1689 case 'u':1690 return Size <= 128;1691 case 'Y':1692 // 'Y' is the first character for several 2-character constraints.1693 switch (Constraint[1]) {1694 default:1695 return false;1696 case 'm':1697 // 'Ym' is synonymous with 'y'.1698 case 'k':1699 return Size <= 64;1700 case 'z':1701 // XMM0/YMM/ZMM01702 if (hasFeatureEnabled(FeatureMap, "avx512f"))1703 // ZMM0 can be used if target supports AVX512F.1704 return Size <= 512U;1705 else if (hasFeatureEnabled(FeatureMap, "avx"))1706 // YMM0 can be used if target supports AVX.1707 return Size <= 256U;1708 else if (hasFeatureEnabled(FeatureMap, "sse"))1709 return Size <= 128U;1710 return false;1711 case 'i':1712 case 't':1713 case '2':1714 // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled.1715 if (SSELevel < SSE2)1716 return false;1717 break;1718 }1719 break;1720 case 'v':1721 case 'x':1722 if (hasFeatureEnabled(FeatureMap, "avx512f"))1723 // 512-bit zmm registers can be used if target supports AVX512F.1724 return Size <= 512U;1725 else if (hasFeatureEnabled(FeatureMap, "avx"))1726 // 256-bit ymm registers can be used if target supports AVX.1727 return Size <= 256U;1728 return Size <= 128U;1729 1730 }1731 1732 return true;1733}1734 1735std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {1736 switch (*Constraint) {1737 case '@':1738 if (auto Len = matchAsmCCConstraint(Constraint)) {1739 std::string Converted = "{" + std::string(Constraint, Len) + "}";1740 Constraint += Len - 1;1741 return Converted;1742 }1743 return std::string(1, *Constraint);1744 case 'a':1745 return std::string("{ax}");1746 case 'b':1747 return std::string("{bx}");1748 case 'c':1749 return std::string("{cx}");1750 case 'd':1751 return std::string("{dx}");1752 case 'S':1753 return std::string("{si}");1754 case 'D':1755 return std::string("{di}");1756 case 'p': // Keep 'p' constraint (address).1757 return std::string("p");1758 case 't': // top of floating point stack.1759 return std::string("{st}");1760 case 'u': // second from top of floating point stack.1761 return std::string("{st(1)}"); // second from top of floating point stack.1762 case 'W':1763 assert(Constraint[1] == 's');1764 return '^' + std::string(Constraint++, 2);1765 case 'Y':1766 switch (Constraint[1]) {1767 default:1768 // Break from inner switch and fall through (copy single char),1769 // continue parsing after copying the current constraint into1770 // the return string.1771 break;1772 case 'k':1773 case 'm':1774 case 'i':1775 case 't':1776 case 'z':1777 case '2':1778 // "^" hints llvm that this is a 2 letter constraint.1779 // "Constraint++" is used to promote the string iterator1780 // to the next constraint.1781 return std::string("^") + std::string(Constraint++, 2);1782 }1783 [[fallthrough]];1784 case 'j':1785 switch (Constraint[1]) {1786 default:1787 // Break from inner switch and fall through (copy single char),1788 // continue parsing after copying the current constraint into1789 // the return string.1790 break;1791 case 'r':1792 case 'R':1793 // "^" hints llvm that this is a 2 letter constraint.1794 // "Constraint++" is used to promote the string iterator1795 // to the next constraint.1796 return std::string("^") + std::string(Constraint++, 2);1797 }1798 [[fallthrough]];1799 default:1800 return std::string(1, *Constraint);1801 }1802}1803 1804void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {1805 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;1806 llvm::X86::fillValidCPUArchList(Values, Only64Bit);1807}1808 1809void X86TargetInfo::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const {1810 llvm::X86::fillValidTuneCPUList(Values);1811}1812 1813ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {1814 return llvm::ArrayRef(GCCRegNames);1815}1816 1817ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {1818 return llvm::ArrayRef(AddlRegNames);1819}1820 1821llvm::SmallVector<Builtin::InfosShard>1822X86_32TargetInfo::getTargetBuiltins() const {1823 return {1824 {&X86::BuiltinStrings, X86::BuiltinInfos},1825 {&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"},1826 };1827}1828 1829llvm::SmallVector<Builtin::InfosShard>1830X86_64TargetInfo::getTargetBuiltins() const {1831 return {1832 {&X86::BuiltinStrings, X86::BuiltinInfos},1833 {&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"},1834 {&X86_64::BuiltinStrings, X86_64::BuiltinInfos},1835 {&X86_64::BuiltinStrings, X86_64::PrefixedBuiltinInfos,1836 "__builtin_ia32_"},1837 };1838}1839