1326941Sdim//===--- X86.cpp - Implement X86 target feature support -------------------===// 2326941Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6326941Sdim// 7326941Sdim//===----------------------------------------------------------------------===// 8326941Sdim// 9326941Sdim// This file implements X86 TargetInfo objects. 10326941Sdim// 11326941Sdim//===----------------------------------------------------------------------===// 12326941Sdim 13326941Sdim#include "X86.h" 14326941Sdim#include "clang/Basic/Builtins.h" 15326941Sdim#include "clang/Basic/Diagnostic.h" 16326941Sdim#include "clang/Basic/TargetBuiltins.h" 17341825Sdim#include "llvm/ADT/StringExtras.h" 18326941Sdim#include "llvm/ADT/StringRef.h" 19326941Sdim#include "llvm/ADT/StringSwitch.h" 20341825Sdim#include "llvm/Support/TargetParser.h" 21326941Sdim 22326941Sdimnamespace clang { 23326941Sdimnamespace targets { 24326941Sdim 25326941Sdimconst Builtin::Info BuiltinInfoX86[] = { 26326941Sdim#define BUILTIN(ID, TYPE, ATTRS) \ 27326941Sdim {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 28326941Sdim#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 29326941Sdim {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, 30326941Sdim#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 31326941Sdim {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 32326941Sdim#include "clang/Basic/BuiltinsX86.def" 33326941Sdim 34326941Sdim#define BUILTIN(ID, TYPE, ATTRS) \ 35326941Sdim {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 36326941Sdim#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 37326941Sdim {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, 38326941Sdim#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 39326941Sdim {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 40326941Sdim#include "clang/Basic/BuiltinsX86_64.def" 41326941Sdim}; 42326941Sdim 43326941Sdimstatic const char *const GCCRegNames[] = { 44326941Sdim "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", 45326941Sdim "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", 46326941Sdim "argp", "flags", "fpcr", "fpsr", "dirflag", "frame", "xmm0", "xmm1", 47326941Sdim "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "mm0", "mm1", 48326941Sdim "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "r8", "r9", 49326941Sdim "r10", "r11", "r12", "r13", "r14", "r15", "xmm8", "xmm9", 50326941Sdim "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", "ymm0", "ymm1", 51326941Sdim "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", 52326941Sdim "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", "xmm16", "xmm17", 53326941Sdim "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", "xmm24", "xmm25", 54326941Sdim "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31", "ymm16", "ymm17", 55326941Sdim "ymm18", "ymm19", "ymm20", "ymm21", "ymm22", "ymm23", "ymm24", "ymm25", 56326941Sdim "ymm26", "ymm27", "ymm28", "ymm29", "ymm30", "ymm31", "zmm0", "zmm1", 57326941Sdim "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9", 58326941Sdim "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17", 59326941Sdim "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25", 60326941Sdim "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", "k0", "k1", 61326941Sdim "k2", "k3", "k4", "k5", "k6", "k7", 62326941Sdim "cr0", "cr2", "cr3", "cr4", "cr8", 63326941Sdim "dr0", "dr1", "dr2", "dr3", "dr6", "dr7", 64326941Sdim "bnd0", "bnd1", "bnd2", "bnd3", 65326941Sdim}; 66326941Sdim 67326941Sdimconst TargetInfo::AddlRegName AddlRegNames[] = { 68326941Sdim {{"al", "ah", "eax", "rax"}, 0}, 69326941Sdim {{"bl", "bh", "ebx", "rbx"}, 3}, 70326941Sdim {{"cl", "ch", "ecx", "rcx"}, 2}, 71326941Sdim {{"dl", "dh", "edx", "rdx"}, 1}, 72326941Sdim {{"esi", "rsi"}, 4}, 73326941Sdim {{"edi", "rdi"}, 5}, 74326941Sdim {{"esp", "rsp"}, 7}, 75326941Sdim {{"ebp", "rbp"}, 6}, 76326941Sdim {{"r8d", "r8w", "r8b"}, 38}, 77326941Sdim {{"r9d", "r9w", "r9b"}, 39}, 78326941Sdim {{"r10d", "r10w", "r10b"}, 40}, 79326941Sdim {{"r11d", "r11w", "r11b"}, 41}, 80326941Sdim {{"r12d", "r12w", "r12b"}, 42}, 81326941Sdim {{"r13d", "r13w", "r13b"}, 43}, 82326941Sdim {{"r14d", "r14w", "r14b"}, 44}, 83326941Sdim {{"r15d", "r15w", "r15b"}, 45}, 84326941Sdim}; 85326941Sdim 86326941Sdim} // namespace targets 87326941Sdim} // namespace clang 88326941Sdim 89326941Sdimusing namespace clang; 90326941Sdimusing namespace clang::targets; 91326941Sdim 92326941Sdimbool X86TargetInfo::setFPMath(StringRef Name) { 93326941Sdim if (Name == "387") { 94326941Sdim FPMath = FP_387; 95326941Sdim return true; 96326941Sdim } 97326941Sdim if (Name == "sse") { 98326941Sdim FPMath = FP_SSE; 99326941Sdim return true; 100326941Sdim } 101326941Sdim return false; 102326941Sdim} 103326941Sdim 104326941Sdimbool X86TargetInfo::initFeatureMap( 105326941Sdim llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, 106326941Sdim const std::vector<std::string> &FeaturesVec) const { 107326941Sdim // FIXME: This *really* should not be here. 108326941Sdim // X86_64 always has SSE2. 109326941Sdim if (getTriple().getArch() == llvm::Triple::x86_64) 110326941Sdim setFeatureEnabledImpl(Features, "sse2", true); 111326941Sdim 112326941Sdim const CPUKind Kind = getCPUKind(CPU); 113326941Sdim 114326941Sdim // Enable X87 for all X86 processors but Lakemont. 115326941Sdim if (Kind != CK_Lakemont) 116326941Sdim setFeatureEnabledImpl(Features, "x87", true); 117326941Sdim 118353358Sdim // Enable cmpxchg8 for i586 and greater CPUs. Include generic for backwards 119353358Sdim // compatibility. 120353358Sdim if (Kind >= CK_i586 || Kind == CK_Generic) 121353358Sdim setFeatureEnabledImpl(Features, "cx8", true); 122353358Sdim 123326941Sdim switch (Kind) { 124326941Sdim case CK_Generic: 125326941Sdim case CK_i386: 126326941Sdim case CK_i486: 127326941Sdim case CK_i586: 128326941Sdim case CK_Pentium: 129326941Sdim case CK_PentiumPro: 130353358Sdim case CK_i686: 131326941Sdim case CK_Lakemont: 132326941Sdim break; 133326941Sdim 134353358Sdim case CK_Cooperlake: 135353358Sdim // CPX inherits all CLX features plus AVX512BF16 136353358Sdim setFeatureEnabledImpl(Features, "avx512bf16", true); 137353358Sdim LLVM_FALLTHROUGH; 138353358Sdim case CK_Cascadelake: 139353358Sdim // CLX inherits all SKX features plus AVX512VNNI 140353358Sdim setFeatureEnabledImpl(Features, "avx512vnni", true); 141353358Sdim LLVM_FALLTHROUGH; 142353358Sdim case CK_SkylakeServer: 143353358Sdim setFeatureEnabledImpl(Features, "avx512f", true); 144353358Sdim setFeatureEnabledImpl(Features, "avx512cd", true); 145353358Sdim setFeatureEnabledImpl(Features, "avx512dq", true); 146353358Sdim setFeatureEnabledImpl(Features, "avx512bw", true); 147353358Sdim setFeatureEnabledImpl(Features, "avx512vl", true); 148353358Sdim setFeatureEnabledImpl(Features, "clwb", true); 149353358Sdim setFeatureEnabledImpl(Features, "pku", true); 150353358Sdim // SkylakeServer cores inherits all SKL features, except SGX 151353358Sdim goto SkylakeCommon; 152353358Sdim 153360784Sdim case CK_Tigerlake: 154360784Sdim setFeatureEnabledImpl(Features, "avx512vp2intersect", true); 155360784Sdim setFeatureEnabledImpl(Features, "movdiri", true); 156360784Sdim setFeatureEnabledImpl(Features, "movdir64b", true); 157360784Sdim setFeatureEnabledImpl(Features, "shstk", true); 158360784Sdim // Tigerlake cores inherits IcelakeClient, except pconfig and wbnoinvd 159360784Sdim goto IcelakeCommon; 160360784Sdim 161341825Sdim case CK_IcelakeServer: 162341825Sdim setFeatureEnabledImpl(Features, "pconfig", true); 163341825Sdim setFeatureEnabledImpl(Features, "wbnoinvd", true); 164341825Sdim LLVM_FALLTHROUGH; 165341825Sdim case CK_IcelakeClient: 166360784SdimIcelakeCommon: 167327330Sdim setFeatureEnabledImpl(Features, "vaes", true); 168327330Sdim setFeatureEnabledImpl(Features, "gfni", true); 169327330Sdim setFeatureEnabledImpl(Features, "vpclmulqdq", true); 170327330Sdim setFeatureEnabledImpl(Features, "avx512bitalg", true); 171327330Sdim setFeatureEnabledImpl(Features, "avx512vbmi2", true); 172353358Sdim setFeatureEnabledImpl(Features, "avx512vnni", true); 173327330Sdim setFeatureEnabledImpl(Features, "avx512vpopcntdq", true); 174341825Sdim setFeatureEnabledImpl(Features, "rdpid", true); 175353358Sdim setFeatureEnabledImpl(Features, "clwb", true); 176326941Sdim LLVM_FALLTHROUGH; 177326941Sdim case CK_Cannonlake: 178326941Sdim setFeatureEnabledImpl(Features, "avx512f", true); 179326941Sdim setFeatureEnabledImpl(Features, "avx512cd", true); 180326941Sdim setFeatureEnabledImpl(Features, "avx512dq", true); 181326941Sdim setFeatureEnabledImpl(Features, "avx512bw", true); 182326941Sdim setFeatureEnabledImpl(Features, "avx512vl", true); 183353358Sdim setFeatureEnabledImpl(Features, "avx512ifma", true); 184353358Sdim setFeatureEnabledImpl(Features, "avx512vbmi", true); 185327657Sdim setFeatureEnabledImpl(Features, "pku", true); 186353358Sdim setFeatureEnabledImpl(Features, "sha", true); 187326941Sdim LLVM_FALLTHROUGH; 188326941Sdim case CK_SkylakeClient: 189353358Sdim setFeatureEnabledImpl(Features, "sgx", true); 190353358Sdim // SkylakeServer cores inherits all SKL features, except SGX 191353358SdimSkylakeCommon: 192326941Sdim setFeatureEnabledImpl(Features, "xsavec", true); 193326941Sdim setFeatureEnabledImpl(Features, "xsaves", true); 194326941Sdim setFeatureEnabledImpl(Features, "clflushopt", true); 195344779Sdim setFeatureEnabledImpl(Features, "aes", true); 196326941Sdim LLVM_FALLTHROUGH; 197326941Sdim case CK_Broadwell: 198326941Sdim setFeatureEnabledImpl(Features, "rdseed", true); 199326941Sdim setFeatureEnabledImpl(Features, "adx", true); 200327135Sdim setFeatureEnabledImpl(Features, "prfchw", true); 201326941Sdim LLVM_FALLTHROUGH; 202326941Sdim case CK_Haswell: 203326941Sdim setFeatureEnabledImpl(Features, "avx2", true); 204326941Sdim setFeatureEnabledImpl(Features, "lzcnt", true); 205326941Sdim setFeatureEnabledImpl(Features, "bmi", true); 206326941Sdim setFeatureEnabledImpl(Features, "bmi2", true); 207326941Sdim setFeatureEnabledImpl(Features, "fma", true); 208341825Sdim setFeatureEnabledImpl(Features, "invpcid", true); 209326941Sdim setFeatureEnabledImpl(Features, "movbe", true); 210326941Sdim LLVM_FALLTHROUGH; 211326941Sdim case CK_IvyBridge: 212326941Sdim setFeatureEnabledImpl(Features, "rdrnd", true); 213326941Sdim setFeatureEnabledImpl(Features, "f16c", true); 214326941Sdim setFeatureEnabledImpl(Features, "fsgsbase", true); 215326941Sdim LLVM_FALLTHROUGH; 216326941Sdim case CK_SandyBridge: 217326941Sdim setFeatureEnabledImpl(Features, "avx", true); 218326941Sdim setFeatureEnabledImpl(Features, "xsave", true); 219326941Sdim setFeatureEnabledImpl(Features, "xsaveopt", true); 220326941Sdim LLVM_FALLTHROUGH; 221326941Sdim case CK_Westmere: 222326941Sdim setFeatureEnabledImpl(Features, "pclmul", true); 223326941Sdim LLVM_FALLTHROUGH; 224326941Sdim case CK_Nehalem: 225326941Sdim setFeatureEnabledImpl(Features, "sse4.2", true); 226326941Sdim LLVM_FALLTHROUGH; 227326941Sdim case CK_Penryn: 228326941Sdim setFeatureEnabledImpl(Features, "sse4.1", true); 229326941Sdim LLVM_FALLTHROUGH; 230326941Sdim case CK_Core2: 231326941Sdim setFeatureEnabledImpl(Features, "ssse3", true); 232332833Sdim setFeatureEnabledImpl(Features, "sahf", true); 233326941Sdim LLVM_FALLTHROUGH; 234353358Sdim case CK_Nocona: 235353358Sdim setFeatureEnabledImpl(Features, "cx16", true); 236353358Sdim LLVM_FALLTHROUGH; 237326941Sdim case CK_Yonah: 238326941Sdim case CK_Prescott: 239326941Sdim setFeatureEnabledImpl(Features, "sse3", true); 240326941Sdim LLVM_FALLTHROUGH; 241326941Sdim case CK_PentiumM: 242326941Sdim case CK_Pentium4: 243326941Sdim case CK_x86_64: 244326941Sdim setFeatureEnabledImpl(Features, "sse2", true); 245326941Sdim LLVM_FALLTHROUGH; 246326941Sdim case CK_Pentium3: 247326941Sdim case CK_C3_2: 248326941Sdim setFeatureEnabledImpl(Features, "sse", true); 249360784Sdim LLVM_FALLTHROUGH; 250360784Sdim case CK_Pentium2: 251326941Sdim setFeatureEnabledImpl(Features, "fxsr", true); 252360784Sdim LLVM_FALLTHROUGH; 253360784Sdim case CK_PentiumMMX: 254360784Sdim case CK_K6: 255360784Sdim case CK_WinChipC6: 256360784Sdim setFeatureEnabledImpl(Features, "mmx", true); 257326941Sdim break; 258326941Sdim 259341825Sdim case CK_Tremont: 260341825Sdim setFeatureEnabledImpl(Features, "cldemote", true); 261341825Sdim setFeatureEnabledImpl(Features, "movdiri", true); 262341825Sdim setFeatureEnabledImpl(Features, "movdir64b", true); 263341825Sdim setFeatureEnabledImpl(Features, "gfni", true); 264341825Sdim setFeatureEnabledImpl(Features, "waitpkg", true); 265341825Sdim LLVM_FALLTHROUGH; 266341825Sdim case CK_GoldmontPlus: 267341825Sdim setFeatureEnabledImpl(Features, "ptwrite", true); 268341825Sdim setFeatureEnabledImpl(Features, "rdpid", true); 269341825Sdim setFeatureEnabledImpl(Features, "sgx", true); 270341825Sdim LLVM_FALLTHROUGH; 271326941Sdim case CK_Goldmont: 272326941Sdim setFeatureEnabledImpl(Features, "sha", true); 273326941Sdim setFeatureEnabledImpl(Features, "rdseed", true); 274326941Sdim setFeatureEnabledImpl(Features, "xsave", true); 275326941Sdim setFeatureEnabledImpl(Features, "xsaveopt", true); 276326941Sdim setFeatureEnabledImpl(Features, "xsavec", true); 277326941Sdim setFeatureEnabledImpl(Features, "xsaves", true); 278326941Sdim setFeatureEnabledImpl(Features, "clflushopt", true); 279326941Sdim setFeatureEnabledImpl(Features, "fsgsbase", true); 280344779Sdim setFeatureEnabledImpl(Features, "aes", true); 281326941Sdim LLVM_FALLTHROUGH; 282326941Sdim case CK_Silvermont: 283341825Sdim setFeatureEnabledImpl(Features, "rdrnd", true); 284326941Sdim setFeatureEnabledImpl(Features, "pclmul", true); 285326941Sdim setFeatureEnabledImpl(Features, "sse4.2", true); 286327135Sdim setFeatureEnabledImpl(Features, "prfchw", true); 287326941Sdim LLVM_FALLTHROUGH; 288326941Sdim case CK_Bonnell: 289326941Sdim setFeatureEnabledImpl(Features, "movbe", true); 290326941Sdim setFeatureEnabledImpl(Features, "ssse3", true); 291326941Sdim setFeatureEnabledImpl(Features, "fxsr", true); 292326941Sdim setFeatureEnabledImpl(Features, "cx16", true); 293332833Sdim setFeatureEnabledImpl(Features, "sahf", true); 294360784Sdim setFeatureEnabledImpl(Features, "mmx", true); 295326941Sdim break; 296326941Sdim 297326941Sdim case CK_KNM: 298326941Sdim // TODO: Add avx5124fmaps/avx5124vnniw. 299326941Sdim setFeatureEnabledImpl(Features, "avx512vpopcntdq", true); 300326941Sdim LLVM_FALLTHROUGH; 301326941Sdim case CK_KNL: 302326941Sdim setFeatureEnabledImpl(Features, "avx512f", true); 303326941Sdim setFeatureEnabledImpl(Features, "avx512cd", true); 304326941Sdim setFeatureEnabledImpl(Features, "avx512er", true); 305326941Sdim setFeatureEnabledImpl(Features, "avx512pf", true); 306327135Sdim setFeatureEnabledImpl(Features, "prfchw", true); 307326941Sdim setFeatureEnabledImpl(Features, "prefetchwt1", true); 308326941Sdim setFeatureEnabledImpl(Features, "fxsr", true); 309326941Sdim setFeatureEnabledImpl(Features, "rdseed", true); 310326941Sdim setFeatureEnabledImpl(Features, "adx", true); 311326941Sdim setFeatureEnabledImpl(Features, "lzcnt", true); 312326941Sdim setFeatureEnabledImpl(Features, "bmi", true); 313326941Sdim setFeatureEnabledImpl(Features, "bmi2", true); 314326941Sdim setFeatureEnabledImpl(Features, "fma", true); 315326941Sdim setFeatureEnabledImpl(Features, "rdrnd", true); 316326941Sdim setFeatureEnabledImpl(Features, "f16c", true); 317326941Sdim setFeatureEnabledImpl(Features, "fsgsbase", true); 318326941Sdim setFeatureEnabledImpl(Features, "aes", true); 319326941Sdim setFeatureEnabledImpl(Features, "pclmul", true); 320326941Sdim setFeatureEnabledImpl(Features, "cx16", true); 321326941Sdim setFeatureEnabledImpl(Features, "xsaveopt", true); 322326941Sdim setFeatureEnabledImpl(Features, "xsave", true); 323326941Sdim setFeatureEnabledImpl(Features, "movbe", true); 324332833Sdim setFeatureEnabledImpl(Features, "sahf", true); 325360784Sdim setFeatureEnabledImpl(Features, "mmx", true); 326326941Sdim break; 327326941Sdim 328326941Sdim case CK_K6_2: 329326941Sdim case CK_K6_3: 330326941Sdim case CK_WinChip2: 331326941Sdim case CK_C3: 332326941Sdim setFeatureEnabledImpl(Features, "3dnow", true); 333326941Sdim break; 334326941Sdim 335326941Sdim case CK_AMDFAM10: 336326941Sdim setFeatureEnabledImpl(Features, "sse4a", true); 337326941Sdim setFeatureEnabledImpl(Features, "lzcnt", true); 338326941Sdim setFeatureEnabledImpl(Features, "popcnt", true); 339332833Sdim setFeatureEnabledImpl(Features, "sahf", true); 340326941Sdim LLVM_FALLTHROUGH; 341326941Sdim case CK_K8SSE3: 342326941Sdim setFeatureEnabledImpl(Features, "sse3", true); 343326941Sdim LLVM_FALLTHROUGH; 344326941Sdim case CK_K8: 345326941Sdim setFeatureEnabledImpl(Features, "sse2", true); 346326941Sdim LLVM_FALLTHROUGH; 347326941Sdim case CK_AthlonXP: 348326941Sdim setFeatureEnabledImpl(Features, "sse", true); 349326941Sdim setFeatureEnabledImpl(Features, "fxsr", true); 350326941Sdim LLVM_FALLTHROUGH; 351326941Sdim case CK_Athlon: 352326941Sdim case CK_Geode: 353326941Sdim setFeatureEnabledImpl(Features, "3dnowa", true); 354326941Sdim break; 355326941Sdim 356326941Sdim case CK_BTVER2: 357326941Sdim setFeatureEnabledImpl(Features, "avx", true); 358326941Sdim setFeatureEnabledImpl(Features, "aes", true); 359326941Sdim setFeatureEnabledImpl(Features, "pclmul", true); 360326941Sdim setFeatureEnabledImpl(Features, "bmi", true); 361326941Sdim setFeatureEnabledImpl(Features, "f16c", true); 362326941Sdim setFeatureEnabledImpl(Features, "xsaveopt", true); 363326941Sdim setFeatureEnabledImpl(Features, "movbe", true); 364326941Sdim LLVM_FALLTHROUGH; 365326941Sdim case CK_BTVER1: 366326941Sdim setFeatureEnabledImpl(Features, "ssse3", true); 367326941Sdim setFeatureEnabledImpl(Features, "sse4a", true); 368326941Sdim setFeatureEnabledImpl(Features, "lzcnt", true); 369326941Sdim setFeatureEnabledImpl(Features, "popcnt", true); 370326941Sdim setFeatureEnabledImpl(Features, "prfchw", true); 371326941Sdim setFeatureEnabledImpl(Features, "cx16", true); 372326941Sdim setFeatureEnabledImpl(Features, "fxsr", true); 373332833Sdim setFeatureEnabledImpl(Features, "sahf", true); 374360784Sdim setFeatureEnabledImpl(Features, "mmx", true); 375326941Sdim break; 376326941Sdim 377353358Sdim case CK_ZNVER2: 378353358Sdim setFeatureEnabledImpl(Features, "clwb", true); 379353358Sdim setFeatureEnabledImpl(Features, "rdpid", true); 380353358Sdim setFeatureEnabledImpl(Features, "wbnoinvd", true); 381353358Sdim LLVM_FALLTHROUGH; 382326941Sdim case CK_ZNVER1: 383326941Sdim setFeatureEnabledImpl(Features, "adx", true); 384326941Sdim setFeatureEnabledImpl(Features, "aes", true); 385326941Sdim setFeatureEnabledImpl(Features, "avx2", true); 386326941Sdim setFeatureEnabledImpl(Features, "bmi", true); 387326941Sdim setFeatureEnabledImpl(Features, "bmi2", true); 388326941Sdim setFeatureEnabledImpl(Features, "clflushopt", true); 389326941Sdim setFeatureEnabledImpl(Features, "clzero", true); 390326941Sdim setFeatureEnabledImpl(Features, "cx16", true); 391326941Sdim setFeatureEnabledImpl(Features, "f16c", true); 392326941Sdim setFeatureEnabledImpl(Features, "fma", true); 393326941Sdim setFeatureEnabledImpl(Features, "fsgsbase", true); 394326941Sdim setFeatureEnabledImpl(Features, "fxsr", true); 395326941Sdim setFeatureEnabledImpl(Features, "lzcnt", true); 396360784Sdim setFeatureEnabledImpl(Features, "mmx", true); 397326941Sdim setFeatureEnabledImpl(Features, "mwaitx", true); 398326941Sdim setFeatureEnabledImpl(Features, "movbe", true); 399326941Sdim setFeatureEnabledImpl(Features, "pclmul", true); 400326941Sdim setFeatureEnabledImpl(Features, "popcnt", true); 401326941Sdim setFeatureEnabledImpl(Features, "prfchw", true); 402326941Sdim setFeatureEnabledImpl(Features, "rdrnd", true); 403326941Sdim setFeatureEnabledImpl(Features, "rdseed", true); 404332833Sdim setFeatureEnabledImpl(Features, "sahf", true); 405326941Sdim setFeatureEnabledImpl(Features, "sha", true); 406326941Sdim setFeatureEnabledImpl(Features, "sse4a", true); 407326941Sdim setFeatureEnabledImpl(Features, "xsave", true); 408326941Sdim setFeatureEnabledImpl(Features, "xsavec", true); 409326941Sdim setFeatureEnabledImpl(Features, "xsaveopt", true); 410326941Sdim setFeatureEnabledImpl(Features, "xsaves", true); 411326941Sdim break; 412326941Sdim 413326941Sdim case CK_BDVER4: 414326941Sdim setFeatureEnabledImpl(Features, "avx2", true); 415326941Sdim setFeatureEnabledImpl(Features, "bmi2", true); 416326941Sdim setFeatureEnabledImpl(Features, "mwaitx", true); 417326941Sdim LLVM_FALLTHROUGH; 418326941Sdim case CK_BDVER3: 419326941Sdim setFeatureEnabledImpl(Features, "fsgsbase", true); 420326941Sdim setFeatureEnabledImpl(Features, "xsaveopt", true); 421326941Sdim LLVM_FALLTHROUGH; 422326941Sdim case CK_BDVER2: 423326941Sdim setFeatureEnabledImpl(Features, "bmi", true); 424326941Sdim setFeatureEnabledImpl(Features, "fma", true); 425326941Sdim setFeatureEnabledImpl(Features, "f16c", true); 426326941Sdim setFeatureEnabledImpl(Features, "tbm", true); 427326941Sdim LLVM_FALLTHROUGH; 428326941Sdim case CK_BDVER1: 429326941Sdim // xop implies avx, sse4a and fma4. 430326941Sdim setFeatureEnabledImpl(Features, "xop", true); 431326941Sdim setFeatureEnabledImpl(Features, "lwp", true); 432326941Sdim setFeatureEnabledImpl(Features, "lzcnt", true); 433326941Sdim setFeatureEnabledImpl(Features, "aes", true); 434326941Sdim setFeatureEnabledImpl(Features, "pclmul", true); 435326941Sdim setFeatureEnabledImpl(Features, "prfchw", true); 436326941Sdim setFeatureEnabledImpl(Features, "cx16", true); 437326941Sdim setFeatureEnabledImpl(Features, "fxsr", true); 438326941Sdim setFeatureEnabledImpl(Features, "xsave", true); 439332833Sdim setFeatureEnabledImpl(Features, "sahf", true); 440360784Sdim setFeatureEnabledImpl(Features, "mmx", true); 441326941Sdim break; 442326941Sdim } 443326941Sdim if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec)) 444326941Sdim return false; 445326941Sdim 446326941Sdim // Can't do this earlier because we need to be able to explicitly enable 447326941Sdim // or disable these features and the things that they depend upon. 448326941Sdim 449326941Sdim // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled. 450326941Sdim auto I = Features.find("sse4.2"); 451326941Sdim if (I != Features.end() && I->getValue() && 452353358Sdim llvm::find(FeaturesVec, "-popcnt") == FeaturesVec.end()) 453326941Sdim Features["popcnt"] = true; 454326941Sdim 455326941Sdim // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled. 456326941Sdim I = Features.find("3dnow"); 457326941Sdim if (I != Features.end() && I->getValue() && 458353358Sdim llvm::find(FeaturesVec, "-prfchw") == FeaturesVec.end()) 459326941Sdim Features["prfchw"] = true; 460326941Sdim 461326941Sdim // Additionally, if SSE is enabled and mmx is not explicitly disabled, 462326941Sdim // then enable MMX. 463326941Sdim I = Features.find("sse"); 464326941Sdim if (I != Features.end() && I->getValue() && 465353358Sdim llvm::find(FeaturesVec, "-mmx") == FeaturesVec.end()) 466326941Sdim Features["mmx"] = true; 467326941Sdim 468326941Sdim return true; 469326941Sdim} 470326941Sdim 471326941Sdimvoid X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features, 472326941Sdim X86SSEEnum Level, bool Enabled) { 473326941Sdim if (Enabled) { 474326941Sdim switch (Level) { 475326941Sdim case AVX512F: 476353358Sdim Features["avx512f"] = true; 477353358Sdim Features["fma"] = true; 478353358Sdim Features["f16c"] = true; 479326941Sdim LLVM_FALLTHROUGH; 480326941Sdim case AVX2: 481326941Sdim Features["avx2"] = true; 482326941Sdim LLVM_FALLTHROUGH; 483326941Sdim case AVX: 484326941Sdim Features["avx"] = true; 485326941Sdim Features["xsave"] = true; 486326941Sdim LLVM_FALLTHROUGH; 487326941Sdim case SSE42: 488326941Sdim Features["sse4.2"] = true; 489326941Sdim LLVM_FALLTHROUGH; 490326941Sdim case SSE41: 491326941Sdim Features["sse4.1"] = true; 492326941Sdim LLVM_FALLTHROUGH; 493326941Sdim case SSSE3: 494326941Sdim Features["ssse3"] = true; 495326941Sdim LLVM_FALLTHROUGH; 496326941Sdim case SSE3: 497326941Sdim Features["sse3"] = true; 498326941Sdim LLVM_FALLTHROUGH; 499326941Sdim case SSE2: 500326941Sdim Features["sse2"] = true; 501326941Sdim LLVM_FALLTHROUGH; 502326941Sdim case SSE1: 503326941Sdim Features["sse"] = true; 504326941Sdim LLVM_FALLTHROUGH; 505326941Sdim case NoSSE: 506326941Sdim break; 507326941Sdim } 508326941Sdim return; 509326941Sdim } 510326941Sdim 511326941Sdim switch (Level) { 512326941Sdim case NoSSE: 513326941Sdim case SSE1: 514326941Sdim Features["sse"] = false; 515326941Sdim LLVM_FALLTHROUGH; 516326941Sdim case SSE2: 517353358Sdim Features["sse2"] = Features["pclmul"] = Features["aes"] = false; 518353358Sdim Features["sha"] = Features["gfni"] = false; 519326941Sdim LLVM_FALLTHROUGH; 520326941Sdim case SSE3: 521326941Sdim Features["sse3"] = false; 522326941Sdim setXOPLevel(Features, NoXOP, false); 523326941Sdim LLVM_FALLTHROUGH; 524326941Sdim case SSSE3: 525326941Sdim Features["ssse3"] = false; 526326941Sdim LLVM_FALLTHROUGH; 527326941Sdim case SSE41: 528326941Sdim Features["sse4.1"] = false; 529326941Sdim LLVM_FALLTHROUGH; 530326941Sdim case SSE42: 531326941Sdim Features["sse4.2"] = false; 532326941Sdim LLVM_FALLTHROUGH; 533326941Sdim case AVX: 534353358Sdim Features["fma"] = Features["avx"] = Features["f16c"] = false; 535353358Sdim Features["xsave"] = Features["xsaveopt"] = Features["vaes"] = false; 536353358Sdim Features["vpclmulqdq"] = false; 537326941Sdim setXOPLevel(Features, FMA4, false); 538326941Sdim LLVM_FALLTHROUGH; 539326941Sdim case AVX2: 540326941Sdim Features["avx2"] = false; 541326941Sdim LLVM_FALLTHROUGH; 542326941Sdim case AVX512F: 543353358Sdim Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] = false; 544353358Sdim Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] = false; 545353358Sdim Features["avx512vl"] = Features["avx512vbmi"] = false; 546353358Sdim Features["avx512ifma"] = Features["avx512vpopcntdq"] = false; 547353358Sdim Features["avx512bitalg"] = Features["avx512vnni"] = false; 548353358Sdim Features["avx512vbmi2"] = Features["avx512bf16"] = false; 549353358Sdim Features["avx512vp2intersect"] = false; 550326941Sdim break; 551326941Sdim } 552326941Sdim} 553326941Sdim 554326941Sdimvoid X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features, 555326941Sdim MMX3DNowEnum Level, bool Enabled) { 556326941Sdim if (Enabled) { 557326941Sdim switch (Level) { 558326941Sdim case AMD3DNowAthlon: 559326941Sdim Features["3dnowa"] = true; 560326941Sdim LLVM_FALLTHROUGH; 561326941Sdim case AMD3DNow: 562326941Sdim Features["3dnow"] = true; 563326941Sdim LLVM_FALLTHROUGH; 564326941Sdim case MMX: 565326941Sdim Features["mmx"] = true; 566326941Sdim LLVM_FALLTHROUGH; 567326941Sdim case NoMMX3DNow: 568326941Sdim break; 569326941Sdim } 570326941Sdim return; 571326941Sdim } 572326941Sdim 573326941Sdim switch (Level) { 574326941Sdim case NoMMX3DNow: 575326941Sdim case MMX: 576326941Sdim Features["mmx"] = false; 577326941Sdim LLVM_FALLTHROUGH; 578326941Sdim case AMD3DNow: 579326941Sdim Features["3dnow"] = false; 580326941Sdim LLVM_FALLTHROUGH; 581326941Sdim case AMD3DNowAthlon: 582326941Sdim Features["3dnowa"] = false; 583326941Sdim break; 584326941Sdim } 585326941Sdim} 586326941Sdim 587326941Sdimvoid X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level, 588326941Sdim bool Enabled) { 589326941Sdim if (Enabled) { 590326941Sdim switch (Level) { 591326941Sdim case XOP: 592326941Sdim Features["xop"] = true; 593326941Sdim LLVM_FALLTHROUGH; 594326941Sdim case FMA4: 595326941Sdim Features["fma4"] = true; 596326941Sdim setSSELevel(Features, AVX, true); 597326941Sdim LLVM_FALLTHROUGH; 598326941Sdim case SSE4A: 599326941Sdim Features["sse4a"] = true; 600326941Sdim setSSELevel(Features, SSE3, true); 601326941Sdim LLVM_FALLTHROUGH; 602326941Sdim case NoXOP: 603326941Sdim break; 604326941Sdim } 605326941Sdim return; 606326941Sdim } 607326941Sdim 608326941Sdim switch (Level) { 609326941Sdim case NoXOP: 610326941Sdim case SSE4A: 611326941Sdim Features["sse4a"] = false; 612326941Sdim LLVM_FALLTHROUGH; 613326941Sdim case FMA4: 614326941Sdim Features["fma4"] = false; 615326941Sdim LLVM_FALLTHROUGH; 616326941Sdim case XOP: 617326941Sdim Features["xop"] = false; 618326941Sdim break; 619326941Sdim } 620326941Sdim} 621326941Sdim 622326941Sdimvoid X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, 623326941Sdim StringRef Name, bool Enabled) { 624326941Sdim // This is a bit of a hack to deal with the sse4 target feature when used 625326941Sdim // as part of the target attribute. We handle sse4 correctly everywhere 626326941Sdim // else. See below for more information on how we handle the sse4 options. 627326941Sdim if (Name != "sse4") 628326941Sdim Features[Name] = Enabled; 629326941Sdim 630326941Sdim if (Name == "mmx") { 631326941Sdim setMMXLevel(Features, MMX, Enabled); 632326941Sdim } else if (Name == "sse") { 633326941Sdim setSSELevel(Features, SSE1, Enabled); 634326941Sdim } else if (Name == "sse2") { 635326941Sdim setSSELevel(Features, SSE2, Enabled); 636326941Sdim } else if (Name == "sse3") { 637326941Sdim setSSELevel(Features, SSE3, Enabled); 638326941Sdim } else if (Name == "ssse3") { 639326941Sdim setSSELevel(Features, SSSE3, Enabled); 640326941Sdim } else if (Name == "sse4.2") { 641326941Sdim setSSELevel(Features, SSE42, Enabled); 642326941Sdim } else if (Name == "sse4.1") { 643326941Sdim setSSELevel(Features, SSE41, Enabled); 644326941Sdim } else if (Name == "3dnow") { 645326941Sdim setMMXLevel(Features, AMD3DNow, Enabled); 646326941Sdim } else if (Name == "3dnowa") { 647326941Sdim setMMXLevel(Features, AMD3DNowAthlon, Enabled); 648326941Sdim } else if (Name == "aes") { 649326941Sdim if (Enabled) 650326941Sdim setSSELevel(Features, SSE2, Enabled); 651327330Sdim else 652327330Sdim Features["vaes"] = false; 653327330Sdim } else if (Name == "vaes") { 654327330Sdim if (Enabled) { 655327330Sdim setSSELevel(Features, AVX, Enabled); 656327330Sdim Features["aes"] = true; 657327330Sdim } 658326941Sdim } else if (Name == "pclmul") { 659326941Sdim if (Enabled) 660326941Sdim setSSELevel(Features, SSE2, Enabled); 661327330Sdim else 662327330Sdim Features["vpclmulqdq"] = false; 663327330Sdim } else if (Name == "vpclmulqdq") { 664327330Sdim if (Enabled) { 665327330Sdim setSSELevel(Features, AVX, Enabled); 666327330Sdim Features["pclmul"] = true; 667327330Sdim } 668327330Sdim } else if (Name == "gfni") { 669327330Sdim if (Enabled) 670327330Sdim setSSELevel(Features, SSE2, Enabled); 671326941Sdim } else if (Name == "avx") { 672326941Sdim setSSELevel(Features, AVX, Enabled); 673326941Sdim } else if (Name == "avx2") { 674326941Sdim setSSELevel(Features, AVX2, Enabled); 675326941Sdim } else if (Name == "avx512f") { 676326941Sdim setSSELevel(Features, AVX512F, Enabled); 677353358Sdim } else if (Name.startswith("avx512")) { 678326941Sdim if (Enabled) 679326941Sdim setSSELevel(Features, AVX512F, Enabled); 680353358Sdim // Enable BWI instruction if certain features are being enabled. 681353358Sdim if ((Name == "avx512vbmi" || Name == "avx512vbmi2" || 682353358Sdim Name == "avx512bitalg" || Name == "avx512bf16") && Enabled) 683326941Sdim Features["avx512bw"] = true; 684353358Sdim // Also disable some features if BWI is being disabled. 685353358Sdim if (Name == "avx512bw" && !Enabled) { 686353358Sdim Features["avx512vbmi"] = false; 687353358Sdim Features["avx512vbmi2"] = false; 688327330Sdim Features["avx512bitalg"] = false; 689353358Sdim Features["avx512bf16"] = false; 690353358Sdim } 691326941Sdim } else if (Name == "fma") { 692326941Sdim if (Enabled) 693326941Sdim setSSELevel(Features, AVX, Enabled); 694328513Sdim else 695328513Sdim setSSELevel(Features, AVX512F, Enabled); 696326941Sdim } else if (Name == "fma4") { 697326941Sdim setXOPLevel(Features, FMA4, Enabled); 698326941Sdim } else if (Name == "xop") { 699326941Sdim setXOPLevel(Features, XOP, Enabled); 700326941Sdim } else if (Name == "sse4a") { 701326941Sdim setXOPLevel(Features, SSE4A, Enabled); 702326941Sdim } else if (Name == "f16c") { 703326941Sdim if (Enabled) 704326941Sdim setSSELevel(Features, AVX, Enabled); 705328513Sdim else 706328513Sdim setSSELevel(Features, AVX512F, Enabled); 707326941Sdim } else if (Name == "sha") { 708326941Sdim if (Enabled) 709326941Sdim setSSELevel(Features, SSE2, Enabled); 710326941Sdim } else if (Name == "sse4") { 711326941Sdim // We can get here via the __target__ attribute since that's not controlled 712326941Sdim // via the -msse4/-mno-sse4 command line alias. Handle this the same way 713326941Sdim // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if 714326941Sdim // disabled. 715326941Sdim if (Enabled) 716326941Sdim setSSELevel(Features, SSE42, Enabled); 717326941Sdim else 718326941Sdim setSSELevel(Features, SSE41, Enabled); 719326941Sdim } else if (Name == "xsave") { 720326941Sdim if (!Enabled) 721326941Sdim Features["xsaveopt"] = false; 722326941Sdim } else if (Name == "xsaveopt" || Name == "xsavec" || Name == "xsaves") { 723326941Sdim if (Enabled) 724326941Sdim Features["xsave"] = true; 725326941Sdim } 726326941Sdim} 727326941Sdim 728326941Sdim/// handleTargetFeatures - Perform initialization based on the user 729326941Sdim/// configured set of features. 730326941Sdimbool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 731326941Sdim DiagnosticsEngine &Diags) { 732326941Sdim for (const auto &Feature : Features) { 733326941Sdim if (Feature[0] != '+') 734326941Sdim continue; 735326941Sdim 736326941Sdim if (Feature == "+aes") { 737326941Sdim HasAES = true; 738327330Sdim } else if (Feature == "+vaes") { 739327330Sdim HasVAES = true; 740326941Sdim } else if (Feature == "+pclmul") { 741326941Sdim HasPCLMUL = true; 742327330Sdim } else if (Feature == "+vpclmulqdq") { 743327330Sdim HasVPCLMULQDQ = true; 744326941Sdim } else if (Feature == "+lzcnt") { 745326941Sdim HasLZCNT = true; 746326941Sdim } else if (Feature == "+rdrnd") { 747326941Sdim HasRDRND = true; 748326941Sdim } else if (Feature == "+fsgsbase") { 749326941Sdim HasFSGSBASE = true; 750326941Sdim } else if (Feature == "+bmi") { 751326941Sdim HasBMI = true; 752326941Sdim } else if (Feature == "+bmi2") { 753326941Sdim HasBMI2 = true; 754326941Sdim } else if (Feature == "+popcnt") { 755326941Sdim HasPOPCNT = true; 756326941Sdim } else if (Feature == "+rtm") { 757326941Sdim HasRTM = true; 758326941Sdim } else if (Feature == "+prfchw") { 759326941Sdim HasPRFCHW = true; 760326941Sdim } else if (Feature == "+rdseed") { 761326941Sdim HasRDSEED = true; 762326941Sdim } else if (Feature == "+adx") { 763326941Sdim HasADX = true; 764326941Sdim } else if (Feature == "+tbm") { 765326941Sdim HasTBM = true; 766326941Sdim } else if (Feature == "+lwp") { 767326941Sdim HasLWP = true; 768326941Sdim } else if (Feature == "+fma") { 769326941Sdim HasFMA = true; 770326941Sdim } else if (Feature == "+f16c") { 771326941Sdim HasF16C = true; 772327330Sdim } else if (Feature == "+gfni") { 773327330Sdim HasGFNI = true; 774326941Sdim } else if (Feature == "+avx512cd") { 775326941Sdim HasAVX512CD = true; 776326941Sdim } else if (Feature == "+avx512vpopcntdq") { 777326941Sdim HasAVX512VPOPCNTDQ = true; 778327330Sdim } else if (Feature == "+avx512vnni") { 779327330Sdim HasAVX512VNNI = true; 780353358Sdim } else if (Feature == "+avx512bf16") { 781353358Sdim HasAVX512BF16 = true; 782326941Sdim } else if (Feature == "+avx512er") { 783326941Sdim HasAVX512ER = true; 784326941Sdim } else if (Feature == "+avx512pf") { 785326941Sdim HasAVX512PF = true; 786326941Sdim } else if (Feature == "+avx512dq") { 787326941Sdim HasAVX512DQ = true; 788327330Sdim } else if (Feature == "+avx512bitalg") { 789327330Sdim HasAVX512BITALG = true; 790326941Sdim } else if (Feature == "+avx512bw") { 791326941Sdim HasAVX512BW = true; 792326941Sdim } else if (Feature == "+avx512vl") { 793326941Sdim HasAVX512VL = true; 794326941Sdim } else if (Feature == "+avx512vbmi") { 795326941Sdim HasAVX512VBMI = true; 796327330Sdim } else if (Feature == "+avx512vbmi2") { 797327330Sdim HasAVX512VBMI2 = true; 798326941Sdim } else if (Feature == "+avx512ifma") { 799326941Sdim HasAVX512IFMA = true; 800353358Sdim } else if (Feature == "+avx512vp2intersect") { 801353358Sdim HasAVX512VP2INTERSECT = true; 802326941Sdim } else if (Feature == "+sha") { 803326941Sdim HasSHA = true; 804326941Sdim } else if (Feature == "+shstk") { 805326941Sdim HasSHSTK = true; 806326941Sdim } else if (Feature == "+movbe") { 807326941Sdim HasMOVBE = true; 808326941Sdim } else if (Feature == "+sgx") { 809326941Sdim HasSGX = true; 810353358Sdim } else if (Feature == "+cx8") { 811353358Sdim HasCX8 = true; 812326941Sdim } else if (Feature == "+cx16") { 813326941Sdim HasCX16 = true; 814326941Sdim } else if (Feature == "+fxsr") { 815326941Sdim HasFXSR = true; 816326941Sdim } else if (Feature == "+xsave") { 817326941Sdim HasXSAVE = true; 818326941Sdim } else if (Feature == "+xsaveopt") { 819326941Sdim HasXSAVEOPT = true; 820326941Sdim } else if (Feature == "+xsavec") { 821326941Sdim HasXSAVEC = true; 822326941Sdim } else if (Feature == "+xsaves") { 823326941Sdim HasXSAVES = true; 824326941Sdim } else if (Feature == "+mwaitx") { 825326941Sdim HasMWAITX = true; 826326941Sdim } else if (Feature == "+pku") { 827326941Sdim HasPKU = true; 828326941Sdim } else if (Feature == "+clflushopt") { 829326941Sdim HasCLFLUSHOPT = true; 830326941Sdim } else if (Feature == "+clwb") { 831326941Sdim HasCLWB = true; 832341825Sdim } else if (Feature == "+wbnoinvd") { 833341825Sdim HasWBNOINVD = true; 834326941Sdim } else if (Feature == "+prefetchwt1") { 835326941Sdim HasPREFETCHWT1 = true; 836326941Sdim } else if (Feature == "+clzero") { 837326941Sdim HasCLZERO = true; 838341825Sdim } else if (Feature == "+cldemote") { 839341825Sdim HasCLDEMOTE = true; 840341825Sdim } else if (Feature == "+rdpid") { 841341825Sdim HasRDPID = true; 842328817Sdim } else if (Feature == "+retpoline-external-thunk") { 843328817Sdim HasRetpolineExternalThunk = true; 844332833Sdim } else if (Feature == "+sahf") { 845332833Sdim HasLAHFSAHF = true; 846341825Sdim } else if (Feature == "+waitpkg") { 847341825Sdim HasWAITPKG = true; 848341825Sdim } else if (Feature == "+movdiri") { 849341825Sdim HasMOVDIRI = true; 850341825Sdim } else if (Feature == "+movdir64b") { 851341825Sdim HasMOVDIR64B = true; 852341825Sdim } else if (Feature == "+pconfig") { 853341825Sdim HasPCONFIG = true; 854341825Sdim } else if (Feature == "+ptwrite") { 855341825Sdim HasPTWRITE = true; 856341825Sdim } else if (Feature == "+invpcid") { 857341825Sdim HasINVPCID = true; 858353358Sdim } else if (Feature == "+enqcmd") { 859353358Sdim HasENQCMD = true; 860326941Sdim } 861326941Sdim 862326941Sdim X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) 863326941Sdim .Case("+avx512f", AVX512F) 864326941Sdim .Case("+avx2", AVX2) 865326941Sdim .Case("+avx", AVX) 866326941Sdim .Case("+sse4.2", SSE42) 867326941Sdim .Case("+sse4.1", SSE41) 868326941Sdim .Case("+ssse3", SSSE3) 869326941Sdim .Case("+sse3", SSE3) 870326941Sdim .Case("+sse2", SSE2) 871326941Sdim .Case("+sse", SSE1) 872326941Sdim .Default(NoSSE); 873326941Sdim SSELevel = std::max(SSELevel, Level); 874326941Sdim 875326941Sdim MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature) 876326941Sdim .Case("+3dnowa", AMD3DNowAthlon) 877326941Sdim .Case("+3dnow", AMD3DNow) 878326941Sdim .Case("+mmx", MMX) 879326941Sdim .Default(NoMMX3DNow); 880326941Sdim MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel); 881326941Sdim 882326941Sdim XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature) 883326941Sdim .Case("+xop", XOP) 884326941Sdim .Case("+fma4", FMA4) 885326941Sdim .Case("+sse4a", SSE4A) 886326941Sdim .Default(NoXOP); 887326941Sdim XOPLevel = std::max(XOPLevel, XLevel); 888326941Sdim } 889326941Sdim 890326941Sdim // LLVM doesn't have a separate switch for fpmath, so only accept it if it 891326941Sdim // matches the selected sse level. 892326941Sdim if ((FPMath == FP_SSE && SSELevel < SSE1) || 893326941Sdim (FPMath == FP_387 && SSELevel >= SSE1)) { 894326941Sdim Diags.Report(diag::err_target_unsupported_fpmath) 895326941Sdim << (FPMath == FP_SSE ? "sse" : "387"); 896326941Sdim return false; 897326941Sdim } 898326941Sdim 899326941Sdim SimdDefaultAlign = 900326941Sdim hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; 901326941Sdim return true; 902326941Sdim} 903326941Sdim 904326941Sdim/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro 905326941Sdim/// definitions for this particular subtarget. 906326941Sdimvoid X86TargetInfo::getTargetDefines(const LangOptions &Opts, 907326941Sdim MacroBuilder &Builder) const { 908360784Sdim // Inline assembly supports X86 flag outputs. 909353358Sdim Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__"); 910353358Sdim 911344779Sdim std::string CodeModel = getTargetOpts().CodeModel; 912344779Sdim if (CodeModel == "default") 913344779Sdim CodeModel = "small"; 914344779Sdim Builder.defineMacro("__code_model_" + CodeModel + "_"); 915344779Sdim 916326941Sdim // Target identification. 917326941Sdim if (getTriple().getArch() == llvm::Triple::x86_64) { 918326941Sdim Builder.defineMacro("__amd64__"); 919326941Sdim Builder.defineMacro("__amd64"); 920326941Sdim Builder.defineMacro("__x86_64"); 921326941Sdim Builder.defineMacro("__x86_64__"); 922326941Sdim if (getTriple().getArchName() == "x86_64h") { 923326941Sdim Builder.defineMacro("__x86_64h"); 924326941Sdim Builder.defineMacro("__x86_64h__"); 925326941Sdim } 926326941Sdim } else { 927326941Sdim DefineStd(Builder, "i386", Opts); 928326941Sdim } 929326941Sdim 930353358Sdim Builder.defineMacro("__SEG_GS"); 931353358Sdim Builder.defineMacro("__SEG_FS"); 932353358Sdim Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))"); 933353358Sdim Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))"); 934353358Sdim 935326941Sdim // Subtarget options. 936326941Sdim // FIXME: We are hard-coding the tune parameters based on the CPU, but they 937326941Sdim // truly should be based on -mtune options. 938326941Sdim switch (CPU) { 939326941Sdim case CK_Generic: 940326941Sdim break; 941326941Sdim case CK_i386: 942326941Sdim // The rest are coming from the i386 define above. 943326941Sdim Builder.defineMacro("__tune_i386__"); 944326941Sdim break; 945326941Sdim case CK_i486: 946326941Sdim case CK_WinChipC6: 947326941Sdim case CK_WinChip2: 948326941Sdim case CK_C3: 949326941Sdim defineCPUMacros(Builder, "i486"); 950326941Sdim break; 951326941Sdim case CK_PentiumMMX: 952326941Sdim Builder.defineMacro("__pentium_mmx__"); 953326941Sdim Builder.defineMacro("__tune_pentium_mmx__"); 954326941Sdim LLVM_FALLTHROUGH; 955326941Sdim case CK_i586: 956326941Sdim case CK_Pentium: 957326941Sdim defineCPUMacros(Builder, "i586"); 958326941Sdim defineCPUMacros(Builder, "pentium"); 959326941Sdim break; 960326941Sdim case CK_Pentium3: 961326941Sdim case CK_PentiumM: 962326941Sdim Builder.defineMacro("__tune_pentium3__"); 963326941Sdim LLVM_FALLTHROUGH; 964326941Sdim case CK_Pentium2: 965326941Sdim case CK_C3_2: 966326941Sdim Builder.defineMacro("__tune_pentium2__"); 967326941Sdim LLVM_FALLTHROUGH; 968326941Sdim case CK_PentiumPro: 969353358Sdim case CK_i686: 970326941Sdim defineCPUMacros(Builder, "i686"); 971326941Sdim defineCPUMacros(Builder, "pentiumpro"); 972326941Sdim break; 973326941Sdim case CK_Pentium4: 974326941Sdim defineCPUMacros(Builder, "pentium4"); 975326941Sdim break; 976326941Sdim case CK_Yonah: 977326941Sdim case CK_Prescott: 978326941Sdim case CK_Nocona: 979326941Sdim defineCPUMacros(Builder, "nocona"); 980326941Sdim break; 981326941Sdim case CK_Core2: 982326941Sdim case CK_Penryn: 983326941Sdim defineCPUMacros(Builder, "core2"); 984326941Sdim break; 985326941Sdim case CK_Bonnell: 986326941Sdim defineCPUMacros(Builder, "atom"); 987326941Sdim break; 988326941Sdim case CK_Silvermont: 989326941Sdim defineCPUMacros(Builder, "slm"); 990326941Sdim break; 991326941Sdim case CK_Goldmont: 992326941Sdim defineCPUMacros(Builder, "goldmont"); 993326941Sdim break; 994341825Sdim case CK_GoldmontPlus: 995341825Sdim defineCPUMacros(Builder, "goldmont_plus"); 996341825Sdim break; 997341825Sdim case CK_Tremont: 998341825Sdim defineCPUMacros(Builder, "tremont"); 999341825Sdim break; 1000326941Sdim case CK_Nehalem: 1001326941Sdim case CK_Westmere: 1002326941Sdim case CK_SandyBridge: 1003326941Sdim case CK_IvyBridge: 1004326941Sdim case CK_Haswell: 1005326941Sdim case CK_Broadwell: 1006326941Sdim case CK_SkylakeClient: 1007326941Sdim case CK_SkylakeServer: 1008344779Sdim case CK_Cascadelake: 1009353358Sdim case CK_Cooperlake: 1010326941Sdim case CK_Cannonlake: 1011341825Sdim case CK_IcelakeClient: 1012341825Sdim case CK_IcelakeServer: 1013360784Sdim case CK_Tigerlake: 1014326941Sdim // FIXME: Historically, we defined this legacy name, it would be nice to 1015326941Sdim // remove it at some point. We've never exposed fine-grained names for 1016326941Sdim // recent primary x86 CPUs, and we should keep it that way. 1017326941Sdim defineCPUMacros(Builder, "corei7"); 1018326941Sdim break; 1019326941Sdim case CK_KNL: 1020326941Sdim defineCPUMacros(Builder, "knl"); 1021326941Sdim break; 1022326941Sdim case CK_KNM: 1023326941Sdim break; 1024326941Sdim case CK_Lakemont: 1025326941Sdim defineCPUMacros(Builder, "i586", /*Tuning*/false); 1026326941Sdim defineCPUMacros(Builder, "pentium", /*Tuning*/false); 1027326941Sdim Builder.defineMacro("__tune_lakemont__"); 1028326941Sdim break; 1029326941Sdim case CK_K6_2: 1030326941Sdim Builder.defineMacro("__k6_2__"); 1031326941Sdim Builder.defineMacro("__tune_k6_2__"); 1032326941Sdim LLVM_FALLTHROUGH; 1033326941Sdim case CK_K6_3: 1034326941Sdim if (CPU != CK_K6_2) { // In case of fallthrough 1035326941Sdim // FIXME: GCC may be enabling these in cases where some other k6 1036326941Sdim // architecture is specified but -m3dnow is explicitly provided. The 1037326941Sdim // exact semantics need to be determined and emulated here. 1038326941Sdim Builder.defineMacro("__k6_3__"); 1039326941Sdim Builder.defineMacro("__tune_k6_3__"); 1040326941Sdim } 1041326941Sdim LLVM_FALLTHROUGH; 1042326941Sdim case CK_K6: 1043326941Sdim defineCPUMacros(Builder, "k6"); 1044326941Sdim break; 1045326941Sdim case CK_Athlon: 1046326941Sdim case CK_AthlonXP: 1047326941Sdim defineCPUMacros(Builder, "athlon"); 1048326941Sdim if (SSELevel != NoSSE) { 1049326941Sdim Builder.defineMacro("__athlon_sse__"); 1050326941Sdim Builder.defineMacro("__tune_athlon_sse__"); 1051326941Sdim } 1052326941Sdim break; 1053326941Sdim case CK_K8: 1054326941Sdim case CK_K8SSE3: 1055326941Sdim case CK_x86_64: 1056326941Sdim defineCPUMacros(Builder, "k8"); 1057326941Sdim break; 1058326941Sdim case CK_AMDFAM10: 1059326941Sdim defineCPUMacros(Builder, "amdfam10"); 1060326941Sdim break; 1061326941Sdim case CK_BTVER1: 1062326941Sdim defineCPUMacros(Builder, "btver1"); 1063326941Sdim break; 1064326941Sdim case CK_BTVER2: 1065326941Sdim defineCPUMacros(Builder, "btver2"); 1066326941Sdim break; 1067326941Sdim case CK_BDVER1: 1068326941Sdim defineCPUMacros(Builder, "bdver1"); 1069326941Sdim break; 1070326941Sdim case CK_BDVER2: 1071326941Sdim defineCPUMacros(Builder, "bdver2"); 1072326941Sdim break; 1073326941Sdim case CK_BDVER3: 1074326941Sdim defineCPUMacros(Builder, "bdver3"); 1075326941Sdim break; 1076326941Sdim case CK_BDVER4: 1077326941Sdim defineCPUMacros(Builder, "bdver4"); 1078326941Sdim break; 1079326941Sdim case CK_ZNVER1: 1080326941Sdim defineCPUMacros(Builder, "znver1"); 1081326941Sdim break; 1082353358Sdim case CK_ZNVER2: 1083353358Sdim defineCPUMacros(Builder, "znver2"); 1084353358Sdim break; 1085326941Sdim case CK_Geode: 1086326941Sdim defineCPUMacros(Builder, "geode"); 1087326941Sdim break; 1088326941Sdim } 1089326941Sdim 1090326941Sdim // Target properties. 1091326941Sdim Builder.defineMacro("__REGISTER_PREFIX__", ""); 1092326941Sdim 1093326941Sdim // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline 1094326941Sdim // functions in glibc header files that use FP Stack inline asm which the 1095326941Sdim // backend can't deal with (PR879). 1096326941Sdim Builder.defineMacro("__NO_MATH_INLINES"); 1097326941Sdim 1098326941Sdim if (HasAES) 1099326941Sdim Builder.defineMacro("__AES__"); 1100326941Sdim 1101327330Sdim if (HasVAES) 1102327330Sdim Builder.defineMacro("__VAES__"); 1103327330Sdim 1104326941Sdim if (HasPCLMUL) 1105326941Sdim Builder.defineMacro("__PCLMUL__"); 1106326941Sdim 1107327330Sdim if (HasVPCLMULQDQ) 1108327330Sdim Builder.defineMacro("__VPCLMULQDQ__"); 1109327330Sdim 1110326941Sdim if (HasLZCNT) 1111326941Sdim Builder.defineMacro("__LZCNT__"); 1112326941Sdim 1113326941Sdim if (HasRDRND) 1114326941Sdim Builder.defineMacro("__RDRND__"); 1115326941Sdim 1116326941Sdim if (HasFSGSBASE) 1117326941Sdim Builder.defineMacro("__FSGSBASE__"); 1118326941Sdim 1119326941Sdim if (HasBMI) 1120326941Sdim Builder.defineMacro("__BMI__"); 1121326941Sdim 1122326941Sdim if (HasBMI2) 1123326941Sdim Builder.defineMacro("__BMI2__"); 1124326941Sdim 1125326941Sdim if (HasPOPCNT) 1126326941Sdim Builder.defineMacro("__POPCNT__"); 1127326941Sdim 1128326941Sdim if (HasRTM) 1129326941Sdim Builder.defineMacro("__RTM__"); 1130326941Sdim 1131326941Sdim if (HasPRFCHW) 1132326941Sdim Builder.defineMacro("__PRFCHW__"); 1133326941Sdim 1134326941Sdim if (HasRDSEED) 1135326941Sdim Builder.defineMacro("__RDSEED__"); 1136326941Sdim 1137326941Sdim if (HasADX) 1138326941Sdim Builder.defineMacro("__ADX__"); 1139326941Sdim 1140326941Sdim if (HasTBM) 1141326941Sdim Builder.defineMacro("__TBM__"); 1142326941Sdim 1143326941Sdim if (HasLWP) 1144326941Sdim Builder.defineMacro("__LWP__"); 1145326941Sdim 1146326941Sdim if (HasMWAITX) 1147326941Sdim Builder.defineMacro("__MWAITX__"); 1148326941Sdim 1149344779Sdim if (HasMOVBE) 1150344779Sdim Builder.defineMacro("__MOVBE__"); 1151344779Sdim 1152326941Sdim switch (XOPLevel) { 1153326941Sdim case XOP: 1154326941Sdim Builder.defineMacro("__XOP__"); 1155326941Sdim LLVM_FALLTHROUGH; 1156326941Sdim case FMA4: 1157326941Sdim Builder.defineMacro("__FMA4__"); 1158326941Sdim LLVM_FALLTHROUGH; 1159326941Sdim case SSE4A: 1160326941Sdim Builder.defineMacro("__SSE4A__"); 1161326941Sdim LLVM_FALLTHROUGH; 1162326941Sdim case NoXOP: 1163326941Sdim break; 1164326941Sdim } 1165326941Sdim 1166326941Sdim if (HasFMA) 1167326941Sdim Builder.defineMacro("__FMA__"); 1168326941Sdim 1169326941Sdim if (HasF16C) 1170326941Sdim Builder.defineMacro("__F16C__"); 1171326941Sdim 1172327330Sdim if (HasGFNI) 1173327330Sdim Builder.defineMacro("__GFNI__"); 1174327330Sdim 1175326941Sdim if (HasAVX512CD) 1176326941Sdim Builder.defineMacro("__AVX512CD__"); 1177326941Sdim if (HasAVX512VPOPCNTDQ) 1178326941Sdim Builder.defineMacro("__AVX512VPOPCNTDQ__"); 1179327330Sdim if (HasAVX512VNNI) 1180327330Sdim Builder.defineMacro("__AVX512VNNI__"); 1181353358Sdim if (HasAVX512BF16) 1182353358Sdim Builder.defineMacro("__AVX512BF16__"); 1183326941Sdim if (HasAVX512ER) 1184326941Sdim Builder.defineMacro("__AVX512ER__"); 1185326941Sdim if (HasAVX512PF) 1186326941Sdim Builder.defineMacro("__AVX512PF__"); 1187326941Sdim if (HasAVX512DQ) 1188326941Sdim Builder.defineMacro("__AVX512DQ__"); 1189327330Sdim if (HasAVX512BITALG) 1190327330Sdim Builder.defineMacro("__AVX512BITALG__"); 1191326941Sdim if (HasAVX512BW) 1192326941Sdim Builder.defineMacro("__AVX512BW__"); 1193326941Sdim if (HasAVX512VL) 1194326941Sdim Builder.defineMacro("__AVX512VL__"); 1195326941Sdim if (HasAVX512VBMI) 1196326941Sdim Builder.defineMacro("__AVX512VBMI__"); 1197327330Sdim if (HasAVX512VBMI2) 1198327330Sdim Builder.defineMacro("__AVX512VBMI2__"); 1199326941Sdim if (HasAVX512IFMA) 1200326941Sdim Builder.defineMacro("__AVX512IFMA__"); 1201353358Sdim if (HasAVX512VP2INTERSECT) 1202353358Sdim Builder.defineMacro("__AVX512VP2INTERSECT__"); 1203326941Sdim if (HasSHA) 1204326941Sdim Builder.defineMacro("__SHA__"); 1205326941Sdim 1206326941Sdim if (HasFXSR) 1207326941Sdim Builder.defineMacro("__FXSR__"); 1208326941Sdim if (HasXSAVE) 1209326941Sdim Builder.defineMacro("__XSAVE__"); 1210326941Sdim if (HasXSAVEOPT) 1211326941Sdim Builder.defineMacro("__XSAVEOPT__"); 1212326941Sdim if (HasXSAVEC) 1213326941Sdim Builder.defineMacro("__XSAVEC__"); 1214326941Sdim if (HasXSAVES) 1215326941Sdim Builder.defineMacro("__XSAVES__"); 1216326941Sdim if (HasPKU) 1217326941Sdim Builder.defineMacro("__PKU__"); 1218326941Sdim if (HasCLFLUSHOPT) 1219326941Sdim Builder.defineMacro("__CLFLUSHOPT__"); 1220326941Sdim if (HasCLWB) 1221326941Sdim Builder.defineMacro("__CLWB__"); 1222341825Sdim if (HasWBNOINVD) 1223341825Sdim Builder.defineMacro("__WBNOINVD__"); 1224326941Sdim if (HasSHSTK) 1225326941Sdim Builder.defineMacro("__SHSTK__"); 1226326941Sdim if (HasSGX) 1227326941Sdim Builder.defineMacro("__SGX__"); 1228326941Sdim if (HasPREFETCHWT1) 1229326941Sdim Builder.defineMacro("__PREFETCHWT1__"); 1230326941Sdim if (HasCLZERO) 1231326941Sdim Builder.defineMacro("__CLZERO__"); 1232341825Sdim if (HasRDPID) 1233341825Sdim Builder.defineMacro("__RDPID__"); 1234341825Sdim if (HasCLDEMOTE) 1235341825Sdim Builder.defineMacro("__CLDEMOTE__"); 1236341825Sdim if (HasWAITPKG) 1237341825Sdim Builder.defineMacro("__WAITPKG__"); 1238341825Sdim if (HasMOVDIRI) 1239341825Sdim Builder.defineMacro("__MOVDIRI__"); 1240341825Sdim if (HasMOVDIR64B) 1241341825Sdim Builder.defineMacro("__MOVDIR64B__"); 1242341825Sdim if (HasPCONFIG) 1243341825Sdim Builder.defineMacro("__PCONFIG__"); 1244341825Sdim if (HasPTWRITE) 1245341825Sdim Builder.defineMacro("__PTWRITE__"); 1246341825Sdim if (HasINVPCID) 1247341825Sdim Builder.defineMacro("__INVPCID__"); 1248353358Sdim if (HasENQCMD) 1249353358Sdim Builder.defineMacro("__ENQCMD__"); 1250326941Sdim 1251326941Sdim // Each case falls through to the previous one here. 1252326941Sdim switch (SSELevel) { 1253326941Sdim case AVX512F: 1254326941Sdim Builder.defineMacro("__AVX512F__"); 1255326941Sdim LLVM_FALLTHROUGH; 1256326941Sdim case AVX2: 1257326941Sdim Builder.defineMacro("__AVX2__"); 1258326941Sdim LLVM_FALLTHROUGH; 1259326941Sdim case AVX: 1260326941Sdim Builder.defineMacro("__AVX__"); 1261326941Sdim LLVM_FALLTHROUGH; 1262326941Sdim case SSE42: 1263326941Sdim Builder.defineMacro("__SSE4_2__"); 1264326941Sdim LLVM_FALLTHROUGH; 1265326941Sdim case SSE41: 1266326941Sdim Builder.defineMacro("__SSE4_1__"); 1267326941Sdim LLVM_FALLTHROUGH; 1268326941Sdim case SSSE3: 1269326941Sdim Builder.defineMacro("__SSSE3__"); 1270326941Sdim LLVM_FALLTHROUGH; 1271326941Sdim case SSE3: 1272326941Sdim Builder.defineMacro("__SSE3__"); 1273326941Sdim LLVM_FALLTHROUGH; 1274326941Sdim case SSE2: 1275326941Sdim Builder.defineMacro("__SSE2__"); 1276326941Sdim Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied. 1277326941Sdim LLVM_FALLTHROUGH; 1278326941Sdim case SSE1: 1279326941Sdim Builder.defineMacro("__SSE__"); 1280326941Sdim Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied. 1281326941Sdim LLVM_FALLTHROUGH; 1282326941Sdim case NoSSE: 1283326941Sdim break; 1284326941Sdim } 1285326941Sdim 1286326941Sdim if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) { 1287326941Sdim switch (SSELevel) { 1288326941Sdim case AVX512F: 1289326941Sdim case AVX2: 1290326941Sdim case AVX: 1291326941Sdim case SSE42: 1292326941Sdim case SSE41: 1293326941Sdim case SSSE3: 1294326941Sdim case SSE3: 1295326941Sdim case SSE2: 1296326941Sdim Builder.defineMacro("_M_IX86_FP", Twine(2)); 1297326941Sdim break; 1298326941Sdim case SSE1: 1299326941Sdim Builder.defineMacro("_M_IX86_FP", Twine(1)); 1300326941Sdim break; 1301326941Sdim default: 1302326941Sdim Builder.defineMacro("_M_IX86_FP", Twine(0)); 1303326941Sdim break; 1304326941Sdim } 1305326941Sdim } 1306326941Sdim 1307326941Sdim // Each case falls through to the previous one here. 1308326941Sdim switch (MMX3DNowLevel) { 1309326941Sdim case AMD3DNowAthlon: 1310326941Sdim Builder.defineMacro("__3dNOW_A__"); 1311326941Sdim LLVM_FALLTHROUGH; 1312326941Sdim case AMD3DNow: 1313326941Sdim Builder.defineMacro("__3dNOW__"); 1314326941Sdim LLVM_FALLTHROUGH; 1315326941Sdim case MMX: 1316326941Sdim Builder.defineMacro("__MMX__"); 1317326941Sdim LLVM_FALLTHROUGH; 1318326941Sdim case NoMMX3DNow: 1319326941Sdim break; 1320326941Sdim } 1321326941Sdim 1322353358Sdim if (CPU >= CK_i486 || CPU == CK_Generic) { 1323326941Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 1324326941Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 1325326941Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 1326326941Sdim } 1327353358Sdim if (HasCX8) 1328326941Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 1329353358Sdim if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64) 1330341825Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16"); 1331326941Sdim 1332326941Sdim if (HasFloat128) 1333326941Sdim Builder.defineMacro("__SIZEOF_FLOAT128__", "16"); 1334326941Sdim} 1335326941Sdim 1336326941Sdimbool X86TargetInfo::isValidFeatureName(StringRef Name) const { 1337326941Sdim return llvm::StringSwitch<bool>(Name) 1338326941Sdim .Case("3dnow", true) 1339326941Sdim .Case("3dnowa", true) 1340327135Sdim .Case("adx", true) 1341326941Sdim .Case("aes", true) 1342326941Sdim .Case("avx", true) 1343326941Sdim .Case("avx2", true) 1344326941Sdim .Case("avx512f", true) 1345326941Sdim .Case("avx512cd", true) 1346326941Sdim .Case("avx512vpopcntdq", true) 1347327330Sdim .Case("avx512vnni", true) 1348353358Sdim .Case("avx512bf16", true) 1349326941Sdim .Case("avx512er", true) 1350326941Sdim .Case("avx512pf", true) 1351326941Sdim .Case("avx512dq", true) 1352327330Sdim .Case("avx512bitalg", true) 1353326941Sdim .Case("avx512bw", true) 1354326941Sdim .Case("avx512vl", true) 1355326941Sdim .Case("avx512vbmi", true) 1356327330Sdim .Case("avx512vbmi2", true) 1357326941Sdim .Case("avx512ifma", true) 1358353358Sdim .Case("avx512vp2intersect", true) 1359326941Sdim .Case("bmi", true) 1360326941Sdim .Case("bmi2", true) 1361341825Sdim .Case("cldemote", true) 1362326941Sdim .Case("clflushopt", true) 1363326941Sdim .Case("clwb", true) 1364326941Sdim .Case("clzero", true) 1365326941Sdim .Case("cx16", true) 1366353358Sdim .Case("enqcmd", true) 1367326941Sdim .Case("f16c", true) 1368326941Sdim .Case("fma", true) 1369326941Sdim .Case("fma4", true) 1370326941Sdim .Case("fsgsbase", true) 1371326941Sdim .Case("fxsr", true) 1372327330Sdim .Case("gfni", true) 1373341825Sdim .Case("invpcid", true) 1374326941Sdim .Case("lwp", true) 1375326941Sdim .Case("lzcnt", true) 1376326941Sdim .Case("mmx", true) 1377326941Sdim .Case("movbe", true) 1378341825Sdim .Case("movdiri", true) 1379341825Sdim .Case("movdir64b", true) 1380327135Sdim .Case("mwaitx", true) 1381326941Sdim .Case("pclmul", true) 1382341825Sdim .Case("pconfig", true) 1383326941Sdim .Case("pku", true) 1384326941Sdim .Case("popcnt", true) 1385326941Sdim .Case("prefetchwt1", true) 1386326941Sdim .Case("prfchw", true) 1387341825Sdim .Case("ptwrite", true) 1388341825Sdim .Case("rdpid", true) 1389326941Sdim .Case("rdrnd", true) 1390326941Sdim .Case("rdseed", true) 1391326941Sdim .Case("rtm", true) 1392332833Sdim .Case("sahf", true) 1393326941Sdim .Case("sgx", true) 1394326941Sdim .Case("sha", true) 1395327135Sdim .Case("shstk", true) 1396326941Sdim .Case("sse", true) 1397326941Sdim .Case("sse2", true) 1398326941Sdim .Case("sse3", true) 1399326941Sdim .Case("ssse3", true) 1400326941Sdim .Case("sse4", true) 1401326941Sdim .Case("sse4.1", true) 1402326941Sdim .Case("sse4.2", true) 1403326941Sdim .Case("sse4a", true) 1404326941Sdim .Case("tbm", true) 1405327330Sdim .Case("vaes", true) 1406327330Sdim .Case("vpclmulqdq", true) 1407341825Sdim .Case("wbnoinvd", true) 1408341825Sdim .Case("waitpkg", true) 1409326941Sdim .Case("x87", true) 1410326941Sdim .Case("xop", true) 1411326941Sdim .Case("xsave", true) 1412326941Sdim .Case("xsavec", true) 1413326941Sdim .Case("xsaves", true) 1414326941Sdim .Case("xsaveopt", true) 1415326941Sdim .Default(false); 1416326941Sdim} 1417326941Sdim 1418326941Sdimbool X86TargetInfo::hasFeature(StringRef Feature) const { 1419326941Sdim return llvm::StringSwitch<bool>(Feature) 1420327135Sdim .Case("adx", HasADX) 1421326941Sdim .Case("aes", HasAES) 1422326941Sdim .Case("avx", SSELevel >= AVX) 1423326941Sdim .Case("avx2", SSELevel >= AVX2) 1424326941Sdim .Case("avx512f", SSELevel >= AVX512F) 1425326941Sdim .Case("avx512cd", HasAVX512CD) 1426326941Sdim .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ) 1427327330Sdim .Case("avx512vnni", HasAVX512VNNI) 1428353358Sdim .Case("avx512bf16", HasAVX512BF16) 1429326941Sdim .Case("avx512er", HasAVX512ER) 1430326941Sdim .Case("avx512pf", HasAVX512PF) 1431326941Sdim .Case("avx512dq", HasAVX512DQ) 1432327330Sdim .Case("avx512bitalg", HasAVX512BITALG) 1433326941Sdim .Case("avx512bw", HasAVX512BW) 1434326941Sdim .Case("avx512vl", HasAVX512VL) 1435326941Sdim .Case("avx512vbmi", HasAVX512VBMI) 1436327330Sdim .Case("avx512vbmi2", HasAVX512VBMI2) 1437326941Sdim .Case("avx512ifma", HasAVX512IFMA) 1438353358Sdim .Case("avx512vp2intersect", HasAVX512VP2INTERSECT) 1439326941Sdim .Case("bmi", HasBMI) 1440326941Sdim .Case("bmi2", HasBMI2) 1441341825Sdim .Case("cldemote", HasCLDEMOTE) 1442326941Sdim .Case("clflushopt", HasCLFLUSHOPT) 1443326941Sdim .Case("clwb", HasCLWB) 1444326941Sdim .Case("clzero", HasCLZERO) 1445353358Sdim .Case("cx8", HasCX8) 1446326941Sdim .Case("cx16", HasCX16) 1447353358Sdim .Case("enqcmd", HasENQCMD) 1448326941Sdim .Case("f16c", HasF16C) 1449326941Sdim .Case("fma", HasFMA) 1450326941Sdim .Case("fma4", XOPLevel >= FMA4) 1451326941Sdim .Case("fsgsbase", HasFSGSBASE) 1452326941Sdim .Case("fxsr", HasFXSR) 1453327330Sdim .Case("gfni", HasGFNI) 1454341825Sdim .Case("invpcid", HasINVPCID) 1455326941Sdim .Case("lwp", HasLWP) 1456326941Sdim .Case("lzcnt", HasLZCNT) 1457326941Sdim .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) 1458326941Sdim .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon) 1459326941Sdim .Case("mmx", MMX3DNowLevel >= MMX) 1460326941Sdim .Case("movbe", HasMOVBE) 1461341825Sdim .Case("movdiri", HasMOVDIRI) 1462341825Sdim .Case("movdir64b", HasMOVDIR64B) 1463327135Sdim .Case("mwaitx", HasMWAITX) 1464326941Sdim .Case("pclmul", HasPCLMUL) 1465341825Sdim .Case("pconfig", HasPCONFIG) 1466326941Sdim .Case("pku", HasPKU) 1467326941Sdim .Case("popcnt", HasPOPCNT) 1468326941Sdim .Case("prefetchwt1", HasPREFETCHWT1) 1469326941Sdim .Case("prfchw", HasPRFCHW) 1470341825Sdim .Case("ptwrite", HasPTWRITE) 1471341825Sdim .Case("rdpid", HasRDPID) 1472326941Sdim .Case("rdrnd", HasRDRND) 1473326941Sdim .Case("rdseed", HasRDSEED) 1474328817Sdim .Case("retpoline-external-thunk", HasRetpolineExternalThunk) 1475326941Sdim .Case("rtm", HasRTM) 1476332833Sdim .Case("sahf", HasLAHFSAHF) 1477326941Sdim .Case("sgx", HasSGX) 1478326941Sdim .Case("sha", HasSHA) 1479327135Sdim .Case("shstk", HasSHSTK) 1480326941Sdim .Case("sse", SSELevel >= SSE1) 1481326941Sdim .Case("sse2", SSELevel >= SSE2) 1482326941Sdim .Case("sse3", SSELevel >= SSE3) 1483326941Sdim .Case("ssse3", SSELevel >= SSSE3) 1484326941Sdim .Case("sse4.1", SSELevel >= SSE41) 1485326941Sdim .Case("sse4.2", SSELevel >= SSE42) 1486326941Sdim .Case("sse4a", XOPLevel >= SSE4A) 1487326941Sdim .Case("tbm", HasTBM) 1488327330Sdim .Case("vaes", HasVAES) 1489327330Sdim .Case("vpclmulqdq", HasVPCLMULQDQ) 1490341825Sdim .Case("wbnoinvd", HasWBNOINVD) 1491341825Sdim .Case("waitpkg", HasWAITPKG) 1492326941Sdim .Case("x86", true) 1493326941Sdim .Case("x86_32", getTriple().getArch() == llvm::Triple::x86) 1494326941Sdim .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) 1495326941Sdim .Case("xop", XOPLevel >= XOP) 1496326941Sdim .Case("xsave", HasXSAVE) 1497326941Sdim .Case("xsavec", HasXSAVEC) 1498326941Sdim .Case("xsaves", HasXSAVES) 1499326941Sdim .Case("xsaveopt", HasXSAVEOPT) 1500326941Sdim .Default(false); 1501326941Sdim} 1502326941Sdim 1503326941Sdim// We can't use a generic validation scheme for the features accepted here 1504326941Sdim// versus subtarget features accepted in the target attribute because the 1505326941Sdim// bitfield structure that's initialized in the runtime only supports the 1506326941Sdim// below currently rather than the full range of subtarget features. (See 1507326941Sdim// X86TargetInfo::hasFeature for a somewhat comprehensive list). 1508326941Sdimbool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { 1509326941Sdim return llvm::StringSwitch<bool>(FeatureStr) 1510326941Sdim#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, true) 1511326941Sdim#include "llvm/Support/X86TargetParser.def" 1512326941Sdim .Default(false); 1513326941Sdim} 1514326941Sdim 1515341825Sdimstatic llvm::X86::ProcessorFeatures getFeature(StringRef Name) { 1516341825Sdim return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name) 1517341825Sdim#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, llvm::X86::ENUM) 1518341825Sdim#include "llvm/Support/X86TargetParser.def" 1519341825Sdim ; 1520341825Sdim // Note, this function should only be used after ensuring the value is 1521341825Sdim // correct, so it asserts if the value is out of range. 1522341825Sdim} 1523341825Sdim 1524341825Sdimstatic unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) { 1525341825Sdim enum class FeatPriority { 1526341825Sdim#define FEATURE(FEAT) FEAT, 1527341825Sdim#include "clang/Basic/X86Target.def" 1528341825Sdim }; 1529341825Sdim switch (Feat) { 1530341825Sdim#define FEATURE(FEAT) \ 1531341825Sdim case llvm::X86::FEAT: \ 1532341825Sdim return static_cast<unsigned>(FeatPriority::FEAT); 1533341825Sdim#include "clang/Basic/X86Target.def" 1534341825Sdim default: 1535341825Sdim llvm_unreachable("No Feature Priority for non-CPUSupports Features"); 1536341825Sdim } 1537341825Sdim} 1538341825Sdim 1539341825Sdimunsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const { 1540341825Sdim // Valid CPUs have a 'key feature' that compares just better than its key 1541341825Sdim // feature. 1542341825Sdim CPUKind Kind = getCPUKind(Name); 1543341825Sdim if (Kind != CK_Generic) { 1544341825Sdim switch (Kind) { 1545341825Sdim default: 1546341825Sdim llvm_unreachable( 1547341825Sdim "CPU Type without a key feature used in 'target' attribute"); 1548341825Sdim#define PROC_WITH_FEAT(ENUM, STR, IS64, KEY_FEAT) \ 1549341825Sdim case CK_##ENUM: \ 1550341825Sdim return (getFeaturePriority(llvm::X86::KEY_FEAT) << 1) + 1; 1551341825Sdim#include "clang/Basic/X86Target.def" 1552341825Sdim } 1553341825Sdim } 1554341825Sdim 1555341825Sdim // Now we know we have a feature, so get its priority and shift it a few so 1556341825Sdim // that we have sufficient room for the CPUs (above). 1557341825Sdim return getFeaturePriority(getFeature(Name)) << 1; 1558341825Sdim} 1559341825Sdim 1560341825Sdimbool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const { 1561341825Sdim return llvm::StringSwitch<bool>(Name) 1562341825Sdim#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true) 1563341825Sdim#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true) 1564341825Sdim#include "clang/Basic/X86Target.def" 1565341825Sdim .Default(false); 1566341825Sdim} 1567341825Sdim 1568341825Sdimstatic StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) { 1569341825Sdim return llvm::StringSwitch<StringRef>(Name) 1570341825Sdim#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME) 1571341825Sdim#include "clang/Basic/X86Target.def" 1572341825Sdim .Default(Name); 1573341825Sdim} 1574341825Sdim 1575341825Sdimchar X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const { 1576341825Sdim return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name)) 1577341825Sdim#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING) 1578341825Sdim#include "clang/Basic/X86Target.def" 1579341825Sdim .Default(0); 1580341825Sdim} 1581341825Sdim 1582341825Sdimvoid X86TargetInfo::getCPUSpecificCPUDispatchFeatures( 1583341825Sdim StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const { 1584341825Sdim StringRef WholeList = 1585341825Sdim llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name)) 1586341825Sdim#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES) 1587341825Sdim#include "clang/Basic/X86Target.def" 1588341825Sdim .Default(""); 1589341825Sdim WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); 1590341825Sdim} 1591341825Sdim 1592326941Sdim// We can't use a generic validation scheme for the cpus accepted here 1593326941Sdim// versus subtarget cpus accepted in the target attribute because the 1594326941Sdim// variables intitialized by the runtime only support the below currently 1595326941Sdim// rather than the full range of cpus. 1596326941Sdimbool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const { 1597326941Sdim return llvm::StringSwitch<bool>(FeatureStr) 1598326941Sdim#define X86_VENDOR(ENUM, STRING) .Case(STRING, true) 1599326941Sdim#define X86_CPU_TYPE_COMPAT_WITH_ALIAS(ARCHNAME, ENUM, STR, ALIAS) \ 1600326941Sdim .Cases(STR, ALIAS, true) 1601326941Sdim#define X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true) 1602326941Sdim#define X86_CPU_SUBTYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true) 1603326941Sdim#include "llvm/Support/X86TargetParser.def" 1604326941Sdim .Default(false); 1605326941Sdim} 1606326941Sdim 1607353358Sdimstatic unsigned matchAsmCCConstraint(const char *&Name) { 1608353358Sdim auto RV = llvm::StringSwitch<unsigned>(Name) 1609353358Sdim .Case("@cca", 4) 1610353358Sdim .Case("@ccae", 5) 1611353358Sdim .Case("@ccb", 4) 1612353358Sdim .Case("@ccbe", 5) 1613353358Sdim .Case("@ccc", 4) 1614353358Sdim .Case("@cce", 4) 1615353358Sdim .Case("@ccz", 4) 1616353358Sdim .Case("@ccg", 4) 1617353358Sdim .Case("@ccge", 5) 1618353358Sdim .Case("@ccl", 4) 1619353358Sdim .Case("@ccle", 5) 1620353358Sdim .Case("@ccna", 5) 1621353358Sdim .Case("@ccnae", 6) 1622353358Sdim .Case("@ccnb", 5) 1623353358Sdim .Case("@ccnbe", 6) 1624353358Sdim .Case("@ccnc", 5) 1625353358Sdim .Case("@ccne", 5) 1626353358Sdim .Case("@ccnz", 5) 1627353358Sdim .Case("@ccng", 5) 1628353358Sdim .Case("@ccnge", 6) 1629353358Sdim .Case("@ccnl", 5) 1630353358Sdim .Case("@ccnle", 6) 1631353358Sdim .Case("@ccno", 5) 1632353358Sdim .Case("@ccnp", 5) 1633353358Sdim .Case("@ccns", 5) 1634353358Sdim .Case("@cco", 4) 1635353358Sdim .Case("@ccp", 4) 1636353358Sdim .Case("@ccs", 4) 1637353358Sdim .Default(0); 1638353358Sdim return RV; 1639353358Sdim} 1640353358Sdim 1641326941Sdimbool X86TargetInfo::validateAsmConstraint( 1642326941Sdim const char *&Name, TargetInfo::ConstraintInfo &Info) const { 1643326941Sdim switch (*Name) { 1644326941Sdim default: 1645326941Sdim return false; 1646326941Sdim // Constant constraints. 1647326941Sdim case 'e': // 32-bit signed integer constant for use with sign-extending x86_64 1648326941Sdim // instructions. 1649326941Sdim case 'Z': // 32-bit unsigned integer constant for use with zero-extending 1650326941Sdim // x86_64 instructions. 1651326941Sdim case 's': 1652326941Sdim Info.setRequiresImmediate(); 1653326941Sdim return true; 1654326941Sdim case 'I': 1655326941Sdim Info.setRequiresImmediate(0, 31); 1656326941Sdim return true; 1657326941Sdim case 'J': 1658326941Sdim Info.setRequiresImmediate(0, 63); 1659326941Sdim return true; 1660326941Sdim case 'K': 1661326941Sdim Info.setRequiresImmediate(-128, 127); 1662326941Sdim return true; 1663326941Sdim case 'L': 1664326941Sdim Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)}); 1665326941Sdim return true; 1666326941Sdim case 'M': 1667326941Sdim Info.setRequiresImmediate(0, 3); 1668326941Sdim return true; 1669326941Sdim case 'N': 1670326941Sdim Info.setRequiresImmediate(0, 255); 1671326941Sdim return true; 1672326941Sdim case 'O': 1673326941Sdim Info.setRequiresImmediate(0, 127); 1674326941Sdim return true; 1675326941Sdim // Register constraints. 1676326941Sdim case 'Y': // 'Y' is the first character for several 2-character constraints. 1677326941Sdim // Shift the pointer to the second character of the constraint. 1678326941Sdim Name++; 1679326941Sdim switch (*Name) { 1680326941Sdim default: 1681326941Sdim return false; 1682326941Sdim case 'z': 1683326941Sdim case '0': // First SSE register. 1684326941Sdim case '2': 1685326941Sdim case 't': // Any SSE register, when SSE2 is enabled. 1686326941Sdim case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled. 1687326941Sdim case 'm': // Any MMX register, when inter-unit moves enabled. 1688326941Sdim case 'k': // AVX512 arch mask registers: k1-k7. 1689326941Sdim Info.setAllowsRegister(); 1690326941Sdim return true; 1691326941Sdim } 1692326941Sdim case 'f': // Any x87 floating point stack register. 1693326941Sdim // Constraint 'f' cannot be used for output operands. 1694326941Sdim if (Info.ConstraintStr[0] == '=') 1695326941Sdim return false; 1696326941Sdim Info.setAllowsRegister(); 1697326941Sdim return true; 1698326941Sdim case 'a': // eax. 1699326941Sdim case 'b': // ebx. 1700326941Sdim case 'c': // ecx. 1701326941Sdim case 'd': // edx. 1702326941Sdim case 'S': // esi. 1703326941Sdim case 'D': // edi. 1704326941Sdim case 'A': // edx:eax. 1705326941Sdim case 't': // Top of floating point stack. 1706326941Sdim case 'u': // Second from top of floating point stack. 1707326941Sdim case 'q': // Any register accessible as [r]l: a, b, c, and d. 1708326941Sdim case 'y': // Any MMX register. 1709326941Sdim case 'v': // Any {X,Y,Z}MM register (Arch & context dependent) 1710326941Sdim case 'x': // Any SSE register. 1711341825Sdim case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0 1712326941Sdim // for intermideate k reg operations). 1713326941Sdim case 'Q': // Any register accessible as [r]h: a, b, c, and d. 1714326941Sdim case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp. 1715326941Sdim case 'l': // "Index" registers: any general register that can be used as an 1716326941Sdim // index in a base+index memory access. 1717326941Sdim Info.setAllowsRegister(); 1718326941Sdim return true; 1719326941Sdim // Floating point constant constraints. 1720326941Sdim case 'C': // SSE floating point constant. 1721326941Sdim case 'G': // x87 floating point constant. 1722326941Sdim return true; 1723353358Sdim case '@': 1724353358Sdim // CC condition changes. 1725353358Sdim if (auto Len = matchAsmCCConstraint(Name)) { 1726353358Sdim Name += Len - 1; 1727353358Sdim Info.setAllowsRegister(); 1728353358Sdim return true; 1729353358Sdim } 1730353358Sdim return false; 1731326941Sdim } 1732326941Sdim} 1733326941Sdim 1734360784Sdimbool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap, 1735360784Sdim StringRef Constraint, 1736326941Sdim unsigned Size) const { 1737326941Sdim // Strip off constraint modifiers. 1738326941Sdim while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 1739326941Sdim Constraint = Constraint.substr(1); 1740326941Sdim 1741360784Sdim return validateOperandSize(FeatureMap, Constraint, Size); 1742326941Sdim} 1743326941Sdim 1744360784Sdimbool X86TargetInfo::validateInputSize(const llvm::StringMap<bool> &FeatureMap, 1745360784Sdim StringRef Constraint, 1746326941Sdim unsigned Size) const { 1747360784Sdim return validateOperandSize(FeatureMap, Constraint, Size); 1748326941Sdim} 1749326941Sdim 1750360784Sdimbool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap, 1751360784Sdim StringRef Constraint, 1752326941Sdim unsigned Size) const { 1753326941Sdim switch (Constraint[0]) { 1754326941Sdim default: 1755326941Sdim break; 1756326941Sdim case 'k': 1757326941Sdim // Registers k0-k7 (AVX512) size limit is 64 bit. 1758326941Sdim case 'y': 1759326941Sdim return Size <= 64; 1760326941Sdim case 'f': 1761326941Sdim case 't': 1762326941Sdim case 'u': 1763326941Sdim return Size <= 128; 1764326941Sdim case 'Y': 1765326941Sdim // 'Y' is the first character for several 2-character constraints. 1766326941Sdim switch (Constraint[1]) { 1767326941Sdim default: 1768326941Sdim return false; 1769326941Sdim case 'm': 1770326941Sdim // 'Ym' is synonymous with 'y'. 1771326941Sdim case 'k': 1772326941Sdim return Size <= 64; 1773326941Sdim case 'z': 1774326941Sdim case '0': 1775366452Sdim // XMM0/YMM/ZMM0 1776366452Sdim if (FeatureMap.lookup("avx512f")) 1777366452Sdim // ZMM0 can be used if target supports AVX512F. 1778366452Sdim return Size <= 512U; 1779366452Sdim else if (FeatureMap.lookup("avx")) 1780366452Sdim // YMM0 can be used if target supports AVX. 1781366452Sdim return Size <= 256U; 1782366452Sdim else if (FeatureMap.lookup("sse")) 1783326941Sdim return Size <= 128U; 1784326941Sdim return false; 1785326941Sdim case 'i': 1786326941Sdim case 't': 1787326941Sdim case '2': 1788326941Sdim // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled. 1789326941Sdim if (SSELevel < SSE2) 1790326941Sdim return false; 1791326941Sdim break; 1792326941Sdim } 1793344779Sdim LLVM_FALLTHROUGH; 1794326941Sdim case 'v': 1795326941Sdim case 'x': 1796360784Sdim if (FeatureMap.lookup("avx512f")) 1797326941Sdim // 512-bit zmm registers can be used if target supports AVX512F. 1798326941Sdim return Size <= 512U; 1799360784Sdim else if (FeatureMap.lookup("avx")) 1800326941Sdim // 256-bit ymm registers can be used if target supports AVX. 1801326941Sdim return Size <= 256U; 1802326941Sdim return Size <= 128U; 1803326941Sdim 1804326941Sdim } 1805326941Sdim 1806326941Sdim return true; 1807326941Sdim} 1808326941Sdim 1809326941Sdimstd::string X86TargetInfo::convertConstraint(const char *&Constraint) const { 1810326941Sdim switch (*Constraint) { 1811353358Sdim case '@': 1812353358Sdim if (auto Len = matchAsmCCConstraint(Constraint)) { 1813353358Sdim std::string Converted = "{" + std::string(Constraint, Len) + "}"; 1814353358Sdim Constraint += Len - 1; 1815353358Sdim return Converted; 1816353358Sdim } 1817353358Sdim return std::string(1, *Constraint); 1818326941Sdim case 'a': 1819326941Sdim return std::string("{ax}"); 1820326941Sdim case 'b': 1821326941Sdim return std::string("{bx}"); 1822326941Sdim case 'c': 1823326941Sdim return std::string("{cx}"); 1824326941Sdim case 'd': 1825326941Sdim return std::string("{dx}"); 1826326941Sdim case 'S': 1827326941Sdim return std::string("{si}"); 1828326941Sdim case 'D': 1829326941Sdim return std::string("{di}"); 1830326941Sdim case 'p': // address 1831326941Sdim return std::string("im"); 1832326941Sdim case 't': // top of floating point stack. 1833326941Sdim return std::string("{st}"); 1834326941Sdim case 'u': // second from top of floating point stack. 1835326941Sdim return std::string("{st(1)}"); // second from top of floating point stack. 1836326941Sdim case 'Y': 1837326941Sdim switch (Constraint[1]) { 1838326941Sdim default: 1839326941Sdim // Break from inner switch and fall through (copy single char), 1840326941Sdim // continue parsing after copying the current constraint into 1841326941Sdim // the return string. 1842326941Sdim break; 1843326941Sdim case 'k': 1844326941Sdim case 'm': 1845326941Sdim case 'i': 1846326941Sdim case 't': 1847326941Sdim case 'z': 1848326941Sdim case '0': 1849326941Sdim case '2': 1850326941Sdim // "^" hints llvm that this is a 2 letter constraint. 1851326941Sdim // "Constraint++" is used to promote the string iterator 1852326941Sdim // to the next constraint. 1853326941Sdim return std::string("^") + std::string(Constraint++, 2); 1854326941Sdim } 1855326941Sdim LLVM_FALLTHROUGH; 1856326941Sdim default: 1857326941Sdim return std::string(1, *Constraint); 1858326941Sdim } 1859326941Sdim} 1860326941Sdim 1861326941Sdimbool X86TargetInfo::checkCPUKind(CPUKind Kind) const { 1862326941Sdim // Perform any per-CPU checks necessary to determine if this CPU is 1863326941Sdim // acceptable. 1864326941Sdim switch (Kind) { 1865326941Sdim case CK_Generic: 1866326941Sdim // No processor selected! 1867326941Sdim return false; 1868326941Sdim#define PROC(ENUM, STRING, IS64BIT) \ 1869326941Sdim case CK_##ENUM: \ 1870326941Sdim return IS64BIT || getTriple().getArch() == llvm::Triple::x86; 1871326941Sdim#include "clang/Basic/X86Target.def" 1872326941Sdim } 1873326941Sdim llvm_unreachable("Unhandled CPU kind"); 1874326941Sdim} 1875326941Sdim 1876341825Sdimvoid X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { 1877341825Sdim#define PROC(ENUM, STRING, IS64BIT) \ 1878341825Sdim if (IS64BIT || getTriple().getArch() == llvm::Triple::x86) \ 1879341825Sdim Values.emplace_back(STRING); 1880353358Sdim // For aliases we need to lookup the CPUKind to check get the 64-bit ness. 1881341825Sdim#define PROC_ALIAS(ENUM, ALIAS) \ 1882353358Sdim if (checkCPUKind(CK_##ENUM)) \ 1883341825Sdim Values.emplace_back(ALIAS); 1884341825Sdim#include "clang/Basic/X86Target.def" 1885341825Sdim} 1886341825Sdim 1887326941SdimX86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const { 1888326941Sdim return llvm::StringSwitch<CPUKind>(CPU) 1889326941Sdim#define PROC(ENUM, STRING, IS64BIT) .Case(STRING, CK_##ENUM) 1890326941Sdim#define PROC_ALIAS(ENUM, ALIAS) .Case(ALIAS, CK_##ENUM) 1891326941Sdim#include "clang/Basic/X86Target.def" 1892326941Sdim .Default(CK_Generic); 1893326941Sdim} 1894326941Sdim 1895326941SdimArrayRef<const char *> X86TargetInfo::getGCCRegNames() const { 1896326941Sdim return llvm::makeArrayRef(GCCRegNames); 1897326941Sdim} 1898326941Sdim 1899326941SdimArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const { 1900326941Sdim return llvm::makeArrayRef(AddlRegNames); 1901326941Sdim} 1902326941Sdim 1903326941SdimArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const { 1904326941Sdim return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - 1905326941Sdim Builtin::FirstTSBuiltin + 1); 1906326941Sdim} 1907326941Sdim 1908326941SdimArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const { 1909326941Sdim return llvm::makeArrayRef(BuiltinInfoX86, 1910326941Sdim X86::LastTSBuiltin - Builtin::FirstTSBuiltin); 1911326941Sdim} 1912