forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			1906 lines
		
	
	
		
			62 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			1906 lines
		
	
	
		
			62 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--- X86.cpp - Implement X86 target feature support -------------------===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file implements X86 TargetInfo objects.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "X86.h"
 | |
| #include "clang/Basic/Builtins.h"
 | |
| #include "clang/Basic/Diagnostic.h"
 | |
| #include "clang/Basic/TargetBuiltins.h"
 | |
| #include "llvm/ADT/StringExtras.h"
 | |
| #include "llvm/ADT/StringRef.h"
 | |
| #include "llvm/ADT/StringSwitch.h"
 | |
| #include "llvm/Support/TargetParser.h"
 | |
| 
 | |
| namespace clang {
 | |
| namespace targets {
 | |
| 
 | |
| const Builtin::Info BuiltinInfoX86[] = {
 | |
| #define BUILTIN(ID, TYPE, ATTRS)                                               \
 | |
|   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
 | |
| #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
 | |
|   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
 | |
| #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
 | |
|   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
 | |
| #include "clang/Basic/BuiltinsX86.def"
 | |
| 
 | |
| #define BUILTIN(ID, TYPE, ATTRS)                                               \
 | |
|   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
 | |
| #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
 | |
|   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
 | |
| #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
 | |
|   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
 | |
| #include "clang/Basic/BuiltinsX86_64.def"
 | |
| };
 | |
| 
 | |
| static const char *const GCCRegNames[] = {
 | |
|     "ax",    "dx",    "cx",    "bx",    "si",      "di",    "bp",    "sp",
 | |
|     "st",    "st(1)", "st(2)", "st(3)", "st(4)",   "st(5)", "st(6)", "st(7)",
 | |
|     "argp",  "flags", "fpcr",  "fpsr",  "dirflag", "frame", "xmm0",  "xmm1",
 | |
|     "xmm2",  "xmm3",  "xmm4",  "xmm5",  "xmm6",    "xmm7",  "mm0",   "mm1",
 | |
|     "mm2",   "mm3",   "mm4",   "mm5",   "mm6",     "mm7",   "r8",    "r9",
 | |
|     "r10",   "r11",   "r12",   "r13",   "r14",     "r15",   "xmm8",  "xmm9",
 | |
|     "xmm10", "xmm11", "xmm12", "xmm13", "xmm14",   "xmm15", "ymm0",  "ymm1",
 | |
|     "ymm2",  "ymm3",  "ymm4",  "ymm5",  "ymm6",    "ymm7",  "ymm8",  "ymm9",
 | |
|     "ymm10", "ymm11", "ymm12", "ymm13", "ymm14",   "ymm15", "xmm16", "xmm17",
 | |
|     "xmm18", "xmm19", "xmm20", "xmm21", "xmm22",   "xmm23", "xmm24", "xmm25",
 | |
|     "xmm26", "xmm27", "xmm28", "xmm29", "xmm30",   "xmm31", "ymm16", "ymm17",
 | |
|     "ymm18", "ymm19", "ymm20", "ymm21", "ymm22",   "ymm23", "ymm24", "ymm25",
 | |
|     "ymm26", "ymm27", "ymm28", "ymm29", "ymm30",   "ymm31", "zmm0",  "zmm1",
 | |
|     "zmm2",  "zmm3",  "zmm4",  "zmm5",  "zmm6",    "zmm7",  "zmm8",  "zmm9",
 | |
|     "zmm10", "zmm11", "zmm12", "zmm13", "zmm14",   "zmm15", "zmm16", "zmm17",
 | |
|     "zmm18", "zmm19", "zmm20", "zmm21", "zmm22",   "zmm23", "zmm24", "zmm25",
 | |
|     "zmm26", "zmm27", "zmm28", "zmm29", "zmm30",   "zmm31", "k0",    "k1",
 | |
|     "k2",    "k3",    "k4",    "k5",    "k6",      "k7",
 | |
|     "cr0",   "cr2",   "cr3",   "cr4",   "cr8",
 | |
|     "dr0",   "dr1",   "dr2",   "dr3",   "dr6",     "dr7",
 | |
|     "bnd0",  "bnd1",  "bnd2",  "bnd3",
 | |
| };
 | |
| 
 | |
| const TargetInfo::AddlRegName AddlRegNames[] = {
 | |
|     {{"al", "ah", "eax", "rax"}, 0},
 | |
|     {{"bl", "bh", "ebx", "rbx"}, 3},
 | |
|     {{"cl", "ch", "ecx", "rcx"}, 2},
 | |
|     {{"dl", "dh", "edx", "rdx"}, 1},
 | |
|     {{"esi", "rsi"}, 4},
 | |
|     {{"edi", "rdi"}, 5},
 | |
|     {{"esp", "rsp"}, 7},
 | |
|     {{"ebp", "rbp"}, 6},
 | |
|     {{"r8d", "r8w", "r8b"}, 38},
 | |
|     {{"r9d", "r9w", "r9b"}, 39},
 | |
|     {{"r10d", "r10w", "r10b"}, 40},
 | |
|     {{"r11d", "r11w", "r11b"}, 41},
 | |
|     {{"r12d", "r12w", "r12b"}, 42},
 | |
|     {{"r13d", "r13w", "r13b"}, 43},
 | |
|     {{"r14d", "r14w", "r14b"}, 44},
 | |
|     {{"r15d", "r15w", "r15b"}, 45},
 | |
| };
 | |
| 
 | |
| } // namespace targets
 | |
| } // namespace clang
 | |
| 
 | |
| using namespace clang;
 | |
| using namespace clang::targets;
 | |
| 
 | |
| bool X86TargetInfo::setFPMath(StringRef Name) {
 | |
|   if (Name == "387") {
 | |
|     FPMath = FP_387;
 | |
|     return true;
 | |
|   }
 | |
|   if (Name == "sse") {
 | |
|     FPMath = FP_SSE;
 | |
|     return true;
 | |
|   }
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::initFeatureMap(
 | |
|     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
 | |
|     const std::vector<std::string> &FeaturesVec) const {
 | |
|   // FIXME: This *really* should not be here.
 | |
|   // X86_64 always has SSE2.
 | |
|   if (getTriple().getArch() == llvm::Triple::x86_64)
 | |
|     setFeatureEnabledImpl(Features, "sse2", true);
 | |
| 
 | |
|   const CPUKind Kind = getCPUKind(CPU);
 | |
| 
 | |
|   // Enable X87 for all X86 processors but Lakemont.
 | |
|   if (Kind != CK_Lakemont)
 | |
|     setFeatureEnabledImpl(Features, "x87", true);
 | |
| 
 | |
|   // Enable cmpxchg8 for i586 and greater CPUs. Include generic for backwards
 | |
|   // compatibility.
 | |
|   if (Kind >= CK_i586 || Kind == CK_Generic)
 | |
|     setFeatureEnabledImpl(Features, "cx8", true);
 | |
| 
 | |
|   switch (Kind) {
 | |
|   case CK_Generic:
 | |
|   case CK_i386:
 | |
|   case CK_i486:
 | |
|   case CK_i586:
 | |
|   case CK_Pentium:
 | |
|   case CK_PentiumPro:
 | |
|   case CK_i686:
 | |
|   case CK_Lakemont:
 | |
|     break;
 | |
| 
 | |
|   case CK_Cooperlake:
 | |
|     // CPX inherits all CLX features plus AVX512BF16
 | |
|     setFeatureEnabledImpl(Features, "avx512bf16", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Cascadelake:
 | |
|     // CLX inherits all SKX features plus AVX512VNNI
 | |
|     setFeatureEnabledImpl(Features, "avx512vnni", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_SkylakeServer:
 | |
|     setFeatureEnabledImpl(Features, "avx512f", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512cd", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512dq", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512bw", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512vl", true);
 | |
|     setFeatureEnabledImpl(Features, "clwb", true);
 | |
|     setFeatureEnabledImpl(Features, "pku", true);
 | |
|     // SkylakeServer cores inherits all SKL features, except SGX
 | |
|     goto SkylakeCommon;
 | |
| 
 | |
|   case CK_Tigerlake:
 | |
|     setFeatureEnabledImpl(Features, "avx512vp2intersect", true);
 | |
|     setFeatureEnabledImpl(Features, "movdiri", true);
 | |
|     setFeatureEnabledImpl(Features, "movdir64b", true);
 | |
|     setFeatureEnabledImpl(Features, "shstk", true);
 | |
|     // Tigerlake cores inherits IcelakeClient, except pconfig and wbnoinvd
 | |
|     goto IcelakeCommon;
 | |
| 
 | |
|   case CK_IcelakeServer:
 | |
|     setFeatureEnabledImpl(Features, "pconfig", true);
 | |
|     setFeatureEnabledImpl(Features, "wbnoinvd", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_IcelakeClient:
 | |
| IcelakeCommon:
 | |
|     setFeatureEnabledImpl(Features, "vaes", true);
 | |
|     setFeatureEnabledImpl(Features, "gfni", true);
 | |
|     setFeatureEnabledImpl(Features, "vpclmulqdq", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512bitalg", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512vbmi2", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512vnni", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512vpopcntdq", true);
 | |
|     setFeatureEnabledImpl(Features, "rdpid", true);
 | |
|     setFeatureEnabledImpl(Features, "clwb", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Cannonlake:
 | |
|     setFeatureEnabledImpl(Features, "avx512f", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512cd", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512dq", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512bw", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512vl", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512ifma", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512vbmi", true);
 | |
|     setFeatureEnabledImpl(Features, "pku", true);
 | |
|     setFeatureEnabledImpl(Features, "sha", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_SkylakeClient:
 | |
|     setFeatureEnabledImpl(Features, "sgx", true);
 | |
|     // SkylakeServer cores inherits all SKL features, except SGX
 | |
| SkylakeCommon:
 | |
|     setFeatureEnabledImpl(Features, "xsavec", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaves", true);
 | |
|     setFeatureEnabledImpl(Features, "clflushopt", true);
 | |
|     setFeatureEnabledImpl(Features, "aes", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Broadwell:
 | |
|     setFeatureEnabledImpl(Features, "rdseed", true);
 | |
|     setFeatureEnabledImpl(Features, "adx", true);
 | |
|     setFeatureEnabledImpl(Features, "prfchw", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Haswell:
 | |
|     setFeatureEnabledImpl(Features, "avx2", true);
 | |
|     setFeatureEnabledImpl(Features, "lzcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "bmi", true);
 | |
|     setFeatureEnabledImpl(Features, "bmi2", true);
 | |
|     setFeatureEnabledImpl(Features, "fma", true);
 | |
|     setFeatureEnabledImpl(Features, "invpcid", true);
 | |
|     setFeatureEnabledImpl(Features, "movbe", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_IvyBridge:
 | |
|     setFeatureEnabledImpl(Features, "rdrnd", true);
 | |
|     setFeatureEnabledImpl(Features, "f16c", true);
 | |
|     setFeatureEnabledImpl(Features, "fsgsbase", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_SandyBridge:
 | |
|     setFeatureEnabledImpl(Features, "avx", true);
 | |
|     setFeatureEnabledImpl(Features, "xsave", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaveopt", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Westmere:
 | |
|     setFeatureEnabledImpl(Features, "pclmul", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Nehalem:
 | |
|     setFeatureEnabledImpl(Features, "sse4.2", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Penryn:
 | |
|     setFeatureEnabledImpl(Features, "sse4.1", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Core2:
 | |
|     setFeatureEnabledImpl(Features, "ssse3", true);
 | |
|     setFeatureEnabledImpl(Features, "sahf", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Nocona:
 | |
|     setFeatureEnabledImpl(Features, "cx16", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Yonah:
 | |
|   case CK_Prescott:
 | |
|     setFeatureEnabledImpl(Features, "sse3", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_PentiumM:
 | |
|   case CK_Pentium4:
 | |
|   case CK_x86_64:
 | |
|     setFeatureEnabledImpl(Features, "sse2", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Pentium3:
 | |
|   case CK_C3_2:
 | |
|     setFeatureEnabledImpl(Features, "sse", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Pentium2:
 | |
|     setFeatureEnabledImpl(Features, "fxsr", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_PentiumMMX:
 | |
|   case CK_K6:
 | |
|   case CK_WinChipC6:
 | |
|     setFeatureEnabledImpl(Features, "mmx", true);
 | |
|     break;
 | |
| 
 | |
|   case CK_Tremont:
 | |
|     setFeatureEnabledImpl(Features, "cldemote", true);
 | |
|     setFeatureEnabledImpl(Features, "movdiri", true);
 | |
|     setFeatureEnabledImpl(Features, "movdir64b", true);
 | |
|     setFeatureEnabledImpl(Features, "gfni", true);
 | |
|     setFeatureEnabledImpl(Features, "waitpkg", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_GoldmontPlus:
 | |
|     setFeatureEnabledImpl(Features, "ptwrite", true);
 | |
|     setFeatureEnabledImpl(Features, "rdpid", true);
 | |
|     setFeatureEnabledImpl(Features, "sgx", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Goldmont:
 | |
|     setFeatureEnabledImpl(Features, "sha", true);
 | |
|     setFeatureEnabledImpl(Features, "rdseed", true);
 | |
|     setFeatureEnabledImpl(Features, "xsave", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaveopt", true);
 | |
|     setFeatureEnabledImpl(Features, "xsavec", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaves", true);
 | |
|     setFeatureEnabledImpl(Features, "clflushopt", true);
 | |
|     setFeatureEnabledImpl(Features, "fsgsbase", true);
 | |
|     setFeatureEnabledImpl(Features, "aes", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Silvermont:
 | |
|     setFeatureEnabledImpl(Features, "rdrnd", true);
 | |
|     setFeatureEnabledImpl(Features, "pclmul", true);
 | |
|     setFeatureEnabledImpl(Features, "sse4.2", true);
 | |
|     setFeatureEnabledImpl(Features, "prfchw", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Bonnell:
 | |
|     setFeatureEnabledImpl(Features, "movbe", true);
 | |
|     setFeatureEnabledImpl(Features, "ssse3", true);
 | |
|     setFeatureEnabledImpl(Features, "fxsr", true);
 | |
|     setFeatureEnabledImpl(Features, "cx16", true);
 | |
|     setFeatureEnabledImpl(Features, "sahf", true);
 | |
|     setFeatureEnabledImpl(Features, "mmx", true);
 | |
|     break;
 | |
| 
 | |
|   case CK_KNM:
 | |
|     // TODO: Add avx5124fmaps/avx5124vnniw.
 | |
|     setFeatureEnabledImpl(Features, "avx512vpopcntdq", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_KNL:
 | |
|     setFeatureEnabledImpl(Features, "avx512f", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512cd", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512er", true);
 | |
|     setFeatureEnabledImpl(Features, "avx512pf", true);
 | |
|     setFeatureEnabledImpl(Features, "prfchw", true);
 | |
|     setFeatureEnabledImpl(Features, "prefetchwt1", true);
 | |
|     setFeatureEnabledImpl(Features, "fxsr", true);
 | |
|     setFeatureEnabledImpl(Features, "rdseed", true);
 | |
|     setFeatureEnabledImpl(Features, "adx", true);
 | |
|     setFeatureEnabledImpl(Features, "lzcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "bmi", true);
 | |
|     setFeatureEnabledImpl(Features, "bmi2", true);
 | |
|     setFeatureEnabledImpl(Features, "fma", true);
 | |
|     setFeatureEnabledImpl(Features, "rdrnd", true);
 | |
|     setFeatureEnabledImpl(Features, "f16c", true);
 | |
|     setFeatureEnabledImpl(Features, "fsgsbase", true);
 | |
|     setFeatureEnabledImpl(Features, "aes", true);
 | |
|     setFeatureEnabledImpl(Features, "pclmul", true);
 | |
|     setFeatureEnabledImpl(Features, "cx16", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaveopt", true);
 | |
|     setFeatureEnabledImpl(Features, "xsave", true);
 | |
|     setFeatureEnabledImpl(Features, "movbe", true);
 | |
|     setFeatureEnabledImpl(Features, "sahf", true);
 | |
|     setFeatureEnabledImpl(Features, "mmx", true);
 | |
|     break;
 | |
| 
 | |
|   case CK_K6_2:
 | |
|   case CK_K6_3:
 | |
|   case CK_WinChip2:
 | |
|   case CK_C3:
 | |
|     setFeatureEnabledImpl(Features, "3dnow", true);
 | |
|     break;
 | |
| 
 | |
|   case CK_AMDFAM10:
 | |
|     setFeatureEnabledImpl(Features, "sse4a", true);
 | |
|     setFeatureEnabledImpl(Features, "lzcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "popcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "sahf", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_K8SSE3:
 | |
|     setFeatureEnabledImpl(Features, "sse3", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_K8:
 | |
|     setFeatureEnabledImpl(Features, "sse2", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_AthlonXP:
 | |
|     setFeatureEnabledImpl(Features, "sse", true);
 | |
|     setFeatureEnabledImpl(Features, "fxsr", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Athlon:
 | |
|   case CK_Geode:
 | |
|     setFeatureEnabledImpl(Features, "3dnowa", true);
 | |
|     break;
 | |
| 
 | |
|   case CK_BTVER2:
 | |
|     setFeatureEnabledImpl(Features, "avx", true);
 | |
|     setFeatureEnabledImpl(Features, "aes", true);
 | |
|     setFeatureEnabledImpl(Features, "pclmul", true);
 | |
|     setFeatureEnabledImpl(Features, "bmi", true);
 | |
|     setFeatureEnabledImpl(Features, "f16c", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaveopt", true);
 | |
|     setFeatureEnabledImpl(Features, "movbe", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_BTVER1:
 | |
|     setFeatureEnabledImpl(Features, "ssse3", true);
 | |
|     setFeatureEnabledImpl(Features, "sse4a", true);
 | |
|     setFeatureEnabledImpl(Features, "lzcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "popcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "prfchw", true);
 | |
|     setFeatureEnabledImpl(Features, "cx16", true);
 | |
|     setFeatureEnabledImpl(Features, "fxsr", true);
 | |
|     setFeatureEnabledImpl(Features, "sahf", true);
 | |
|     setFeatureEnabledImpl(Features, "mmx", true);
 | |
|     break;
 | |
| 
 | |
|   case CK_ZNVER2:
 | |
|     setFeatureEnabledImpl(Features, "clwb", true);
 | |
|     setFeatureEnabledImpl(Features, "rdpid", true);
 | |
|     setFeatureEnabledImpl(Features, "wbnoinvd", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_ZNVER1:
 | |
|     setFeatureEnabledImpl(Features, "adx", true);
 | |
|     setFeatureEnabledImpl(Features, "aes", true);
 | |
|     setFeatureEnabledImpl(Features, "avx2", true);
 | |
|     setFeatureEnabledImpl(Features, "bmi", true);
 | |
|     setFeatureEnabledImpl(Features, "bmi2", true);
 | |
|     setFeatureEnabledImpl(Features, "clflushopt", true);
 | |
|     setFeatureEnabledImpl(Features, "clzero", true);
 | |
|     setFeatureEnabledImpl(Features, "cx16", true);
 | |
|     setFeatureEnabledImpl(Features, "f16c", true);
 | |
|     setFeatureEnabledImpl(Features, "fma", true);
 | |
|     setFeatureEnabledImpl(Features, "fsgsbase", true);
 | |
|     setFeatureEnabledImpl(Features, "fxsr", true);
 | |
|     setFeatureEnabledImpl(Features, "lzcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "mmx", true);
 | |
|     setFeatureEnabledImpl(Features, "mwaitx", true);
 | |
|     setFeatureEnabledImpl(Features, "movbe", true);
 | |
|     setFeatureEnabledImpl(Features, "pclmul", true);
 | |
|     setFeatureEnabledImpl(Features, "popcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "prfchw", true);
 | |
|     setFeatureEnabledImpl(Features, "rdrnd", true);
 | |
|     setFeatureEnabledImpl(Features, "rdseed", true);
 | |
|     setFeatureEnabledImpl(Features, "sahf", true);
 | |
|     setFeatureEnabledImpl(Features, "sha", true);
 | |
|     setFeatureEnabledImpl(Features, "sse4a", true);
 | |
|     setFeatureEnabledImpl(Features, "xsave", true);
 | |
|     setFeatureEnabledImpl(Features, "xsavec", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaveopt", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaves", true);
 | |
|     break;
 | |
| 
 | |
|   case CK_BDVER4:
 | |
|     setFeatureEnabledImpl(Features, "avx2", true);
 | |
|     setFeatureEnabledImpl(Features, "bmi2", true);
 | |
|     setFeatureEnabledImpl(Features, "mwaitx", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_BDVER3:
 | |
|     setFeatureEnabledImpl(Features, "fsgsbase", true);
 | |
|     setFeatureEnabledImpl(Features, "xsaveopt", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_BDVER2:
 | |
|     setFeatureEnabledImpl(Features, "bmi", true);
 | |
|     setFeatureEnabledImpl(Features, "fma", true);
 | |
|     setFeatureEnabledImpl(Features, "f16c", true);
 | |
|     setFeatureEnabledImpl(Features, "tbm", true);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_BDVER1:
 | |
|     // xop implies avx, sse4a and fma4.
 | |
|     setFeatureEnabledImpl(Features, "xop", true);
 | |
|     setFeatureEnabledImpl(Features, "lwp", true);
 | |
|     setFeatureEnabledImpl(Features, "lzcnt", true);
 | |
|     setFeatureEnabledImpl(Features, "aes", true);
 | |
|     setFeatureEnabledImpl(Features, "pclmul", true);
 | |
|     setFeatureEnabledImpl(Features, "prfchw", true);
 | |
|     setFeatureEnabledImpl(Features, "cx16", true);
 | |
|     setFeatureEnabledImpl(Features, "fxsr", true);
 | |
|     setFeatureEnabledImpl(Features, "xsave", true);
 | |
|     setFeatureEnabledImpl(Features, "sahf", true);
 | |
|     setFeatureEnabledImpl(Features, "mmx", true);
 | |
|     break;
 | |
|   }
 | |
|   if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec))
 | |
|     return false;
 | |
| 
 | |
|   // Can't do this earlier because we need to be able to explicitly enable
 | |
|   // or disable these features and the things that they depend upon.
 | |
| 
 | |
|   // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
 | |
|   auto I = Features.find("sse4.2");
 | |
|   if (I != Features.end() && I->getValue() &&
 | |
|       llvm::find(FeaturesVec, "-popcnt") == FeaturesVec.end())
 | |
|     Features["popcnt"] = true;
 | |
| 
 | |
|   // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled.
 | |
|   I = Features.find("3dnow");
 | |
|   if (I != Features.end() && I->getValue() &&
 | |
|       llvm::find(FeaturesVec, "-prfchw") == FeaturesVec.end())
 | |
|     Features["prfchw"] = true;
 | |
| 
 | |
|   // Additionally, if SSE is enabled and mmx is not explicitly disabled,
 | |
|   // then enable MMX.
 | |
|   I = Features.find("sse");
 | |
|   if (I != Features.end() && I->getValue() &&
 | |
|       llvm::find(FeaturesVec, "-mmx") == FeaturesVec.end())
 | |
|     Features["mmx"] = true;
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
 | |
|                                 X86SSEEnum Level, bool Enabled) {
 | |
|   if (Enabled) {
 | |
|     switch (Level) {
 | |
|     case AVX512F:
 | |
|       Features["avx512f"] = true;
 | |
|       Features["fma"] = true;
 | |
|       Features["f16c"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case AVX2:
 | |
|       Features["avx2"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case AVX:
 | |
|       Features["avx"] = true;
 | |
|       Features["xsave"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case SSE42:
 | |
|       Features["sse4.2"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case SSE41:
 | |
|       Features["sse4.1"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case SSSE3:
 | |
|       Features["ssse3"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case SSE3:
 | |
|       Features["sse3"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case SSE2:
 | |
|       Features["sse2"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case SSE1:
 | |
|       Features["sse"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case NoSSE:
 | |
|       break;
 | |
|     }
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   switch (Level) {
 | |
|   case NoSSE:
 | |
|   case SSE1:
 | |
|     Features["sse"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE2:
 | |
|     Features["sse2"] = Features["pclmul"] = Features["aes"] = false;
 | |
|     Features["sha"] = Features["gfni"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE3:
 | |
|     Features["sse3"] = false;
 | |
|     setXOPLevel(Features, NoXOP, false);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSSE3:
 | |
|     Features["ssse3"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE41:
 | |
|     Features["sse4.1"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE42:
 | |
|     Features["sse4.2"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case AVX:
 | |
|     Features["fma"] = Features["avx"] = Features["f16c"] = false;
 | |
|     Features["xsave"] = Features["xsaveopt"] = Features["vaes"] = false;
 | |
|     Features["vpclmulqdq"] = false;
 | |
|     setXOPLevel(Features, FMA4, false);
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case AVX2:
 | |
|     Features["avx2"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case AVX512F:
 | |
|     Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] = false;
 | |
|     Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] = false;
 | |
|     Features["avx512vl"] = Features["avx512vbmi"] = false;
 | |
|     Features["avx512ifma"] = Features["avx512vpopcntdq"] = false;
 | |
|     Features["avx512bitalg"] = Features["avx512vnni"] = false;
 | |
|     Features["avx512vbmi2"] = Features["avx512bf16"] = false;
 | |
|     Features["avx512vp2intersect"] = false;
 | |
|     break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features,
 | |
|                                 MMX3DNowEnum Level, bool Enabled) {
 | |
|   if (Enabled) {
 | |
|     switch (Level) {
 | |
|     case AMD3DNowAthlon:
 | |
|       Features["3dnowa"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case AMD3DNow:
 | |
|       Features["3dnow"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case MMX:
 | |
|       Features["mmx"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case NoMMX3DNow:
 | |
|       break;
 | |
|     }
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   switch (Level) {
 | |
|   case NoMMX3DNow:
 | |
|   case MMX:
 | |
|     Features["mmx"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case AMD3DNow:
 | |
|     Features["3dnow"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case AMD3DNowAthlon:
 | |
|     Features["3dnowa"] = false;
 | |
|     break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
 | |
|                                 bool Enabled) {
 | |
|   if (Enabled) {
 | |
|     switch (Level) {
 | |
|     case XOP:
 | |
|       Features["xop"] = true;
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case FMA4:
 | |
|       Features["fma4"] = true;
 | |
|       setSSELevel(Features, AVX, true);
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case SSE4A:
 | |
|       Features["sse4a"] = true;
 | |
|       setSSELevel(Features, SSE3, true);
 | |
|       LLVM_FALLTHROUGH;
 | |
|     case NoXOP:
 | |
|       break;
 | |
|     }
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   switch (Level) {
 | |
|   case NoXOP:
 | |
|   case SSE4A:
 | |
|     Features["sse4a"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case FMA4:
 | |
|     Features["fma4"] = false;
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case XOP:
 | |
|     Features["xop"] = false;
 | |
|     break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
 | |
|                                           StringRef Name, bool Enabled) {
 | |
|   // This is a bit of a hack to deal with the sse4 target feature when used
 | |
|   // as part of the target attribute. We handle sse4 correctly everywhere
 | |
|   // else. See below for more information on how we handle the sse4 options.
 | |
|   if (Name != "sse4")
 | |
|     Features[Name] = Enabled;
 | |
| 
 | |
|   if (Name == "mmx") {
 | |
|     setMMXLevel(Features, MMX, Enabled);
 | |
|   } else if (Name == "sse") {
 | |
|     setSSELevel(Features, SSE1, Enabled);
 | |
|   } else if (Name == "sse2") {
 | |
|     setSSELevel(Features, SSE2, Enabled);
 | |
|   } else if (Name == "sse3") {
 | |
|     setSSELevel(Features, SSE3, Enabled);
 | |
|   } else if (Name == "ssse3") {
 | |
|     setSSELevel(Features, SSSE3, Enabled);
 | |
|   } else if (Name == "sse4.2") {
 | |
|     setSSELevel(Features, SSE42, Enabled);
 | |
|   } else if (Name == "sse4.1") {
 | |
|     setSSELevel(Features, SSE41, Enabled);
 | |
|   } else if (Name == "3dnow") {
 | |
|     setMMXLevel(Features, AMD3DNow, Enabled);
 | |
|   } else if (Name == "3dnowa") {
 | |
|     setMMXLevel(Features, AMD3DNowAthlon, Enabled);
 | |
|   } else if (Name == "aes") {
 | |
|     if (Enabled)
 | |
|       setSSELevel(Features, SSE2, Enabled);
 | |
|     else
 | |
|       Features["vaes"] = false;
 | |
|   } else if (Name == "vaes") {
 | |
|     if (Enabled) {
 | |
|       setSSELevel(Features, AVX, Enabled);
 | |
|       Features["aes"] = true;
 | |
|     }
 | |
|   } else if (Name == "pclmul") {
 | |
|     if (Enabled)
 | |
|       setSSELevel(Features, SSE2, Enabled);
 | |
|     else
 | |
|       Features["vpclmulqdq"] = false;
 | |
|   } else if (Name == "vpclmulqdq") {
 | |
|     if (Enabled) {
 | |
|       setSSELevel(Features, AVX, Enabled);
 | |
|       Features["pclmul"] = true;
 | |
|     }
 | |
|   } else if (Name == "gfni") {
 | |
|      if (Enabled)
 | |
|       setSSELevel(Features, SSE2, Enabled);
 | |
|   } else if (Name == "avx") {
 | |
|     setSSELevel(Features, AVX, Enabled);
 | |
|   } else if (Name == "avx2") {
 | |
|     setSSELevel(Features, AVX2, Enabled);
 | |
|   } else if (Name == "avx512f") {
 | |
|     setSSELevel(Features, AVX512F, Enabled);
 | |
|   } else if (Name.startswith("avx512")) {
 | |
|     if (Enabled)
 | |
|       setSSELevel(Features, AVX512F, Enabled);
 | |
|     // Enable BWI instruction if certain features are being enabled.
 | |
|     if ((Name == "avx512vbmi" || Name == "avx512vbmi2" ||
 | |
|          Name == "avx512bitalg" || Name == "avx512bf16") && Enabled)
 | |
|       Features["avx512bw"] = true;
 | |
|     // Also disable some features if BWI is being disabled.
 | |
|     if (Name == "avx512bw" && !Enabled) {
 | |
|       Features["avx512vbmi"] = false;
 | |
|       Features["avx512vbmi2"] = false;
 | |
|       Features["avx512bitalg"] = false;
 | |
|       Features["avx512bf16"] = false;
 | |
|     }
 | |
|   } else if (Name == "fma") {
 | |
|     if (Enabled)
 | |
|       setSSELevel(Features, AVX, Enabled);
 | |
|     else
 | |
|       setSSELevel(Features, AVX512F, Enabled);
 | |
|   } else if (Name == "fma4") {
 | |
|     setXOPLevel(Features, FMA4, Enabled);
 | |
|   } else if (Name == "xop") {
 | |
|     setXOPLevel(Features, XOP, Enabled);
 | |
|   } else if (Name == "sse4a") {
 | |
|     setXOPLevel(Features, SSE4A, Enabled);
 | |
|   } else if (Name == "f16c") {
 | |
|     if (Enabled)
 | |
|       setSSELevel(Features, AVX, Enabled);
 | |
|     else
 | |
|       setSSELevel(Features, AVX512F, Enabled);
 | |
|   } else if (Name == "sha") {
 | |
|     if (Enabled)
 | |
|       setSSELevel(Features, SSE2, Enabled);
 | |
|   } else if (Name == "sse4") {
 | |
|     // We can get here via the __target__ attribute since that's not controlled
 | |
|     // via the -msse4/-mno-sse4 command line alias. Handle this the same way
 | |
|     // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if
 | |
|     // disabled.
 | |
|     if (Enabled)
 | |
|       setSSELevel(Features, SSE42, Enabled);
 | |
|     else
 | |
|       setSSELevel(Features, SSE41, Enabled);
 | |
|   } else if (Name == "xsave") {
 | |
|     if (!Enabled)
 | |
|       Features["xsaveopt"] = false;
 | |
|   } else if (Name == "xsaveopt" || Name == "xsavec" || Name == "xsaves") {
 | |
|     if (Enabled)
 | |
|       Features["xsave"] = true;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /// handleTargetFeatures - Perform initialization based on the user
 | |
| /// configured set of features.
 | |
| bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
 | |
|                                          DiagnosticsEngine &Diags) {
 | |
|   for (const auto &Feature : Features) {
 | |
|     if (Feature[0] != '+')
 | |
|       continue;
 | |
| 
 | |
|     if (Feature == "+aes") {
 | |
|       HasAES = true;
 | |
|     } else if (Feature == "+vaes") {
 | |
|       HasVAES = true;
 | |
|     } else if (Feature == "+pclmul") {
 | |
|       HasPCLMUL = true;
 | |
|     } else if (Feature == "+vpclmulqdq") {
 | |
|       HasVPCLMULQDQ = true;
 | |
|     } else if (Feature == "+lzcnt") {
 | |
|       HasLZCNT = true;
 | |
|     } else if (Feature == "+rdrnd") {
 | |
|       HasRDRND = true;
 | |
|     } else if (Feature == "+fsgsbase") {
 | |
|       HasFSGSBASE = true;
 | |
|     } else if (Feature == "+bmi") {
 | |
|       HasBMI = true;
 | |
|     } else if (Feature == "+bmi2") {
 | |
|       HasBMI2 = true;
 | |
|     } else if (Feature == "+popcnt") {
 | |
|       HasPOPCNT = true;
 | |
|     } else if (Feature == "+rtm") {
 | |
|       HasRTM = true;
 | |
|     } else if (Feature == "+prfchw") {
 | |
|       HasPRFCHW = true;
 | |
|     } else if (Feature == "+rdseed") {
 | |
|       HasRDSEED = true;
 | |
|     } else if (Feature == "+adx") {
 | |
|       HasADX = true;
 | |
|     } else if (Feature == "+tbm") {
 | |
|       HasTBM = true;
 | |
|     } else if (Feature == "+lwp") {
 | |
|       HasLWP = true;
 | |
|     } else if (Feature == "+fma") {
 | |
|       HasFMA = true;
 | |
|     } else if (Feature == "+f16c") {
 | |
|       HasF16C = true;
 | |
|     } else if (Feature == "+gfni") {
 | |
|       HasGFNI = true;
 | |
|     } else if (Feature == "+avx512cd") {
 | |
|       HasAVX512CD = true;
 | |
|     } else if (Feature == "+avx512vpopcntdq") {
 | |
|       HasAVX512VPOPCNTDQ = true;
 | |
|     } else if (Feature == "+avx512vnni") {
 | |
|       HasAVX512VNNI = true;
 | |
|     } else if (Feature == "+avx512bf16") {
 | |
|       HasAVX512BF16 = true;
 | |
|     } else if (Feature == "+avx512er") {
 | |
|       HasAVX512ER = true;
 | |
|     } else if (Feature == "+avx512pf") {
 | |
|       HasAVX512PF = true;
 | |
|     } else if (Feature == "+avx512dq") {
 | |
|       HasAVX512DQ = true;
 | |
|     } else if (Feature == "+avx512bitalg") {
 | |
|       HasAVX512BITALG = true;
 | |
|     } else if (Feature == "+avx512bw") {
 | |
|       HasAVX512BW = true;
 | |
|     } else if (Feature == "+avx512vl") {
 | |
|       HasAVX512VL = true;
 | |
|     } else if (Feature == "+avx512vbmi") {
 | |
|       HasAVX512VBMI = true;
 | |
|     } else if (Feature == "+avx512vbmi2") {
 | |
|       HasAVX512VBMI2 = true;
 | |
|     } else if (Feature == "+avx512ifma") {
 | |
|       HasAVX512IFMA = true;
 | |
|     } else if (Feature == "+avx512vp2intersect") {
 | |
|       HasAVX512VP2INTERSECT = true;
 | |
|     } else if (Feature == "+sha") {
 | |
|       HasSHA = true;
 | |
|     } else if (Feature == "+shstk") {
 | |
|       HasSHSTK = true;
 | |
|     } else if (Feature == "+movbe") {
 | |
|       HasMOVBE = true;
 | |
|     } else if (Feature == "+sgx") {
 | |
|       HasSGX = true;
 | |
|     } else if (Feature == "+cx8") {
 | |
|       HasCX8 = true;
 | |
|     } else if (Feature == "+cx16") {
 | |
|       HasCX16 = true;
 | |
|     } else if (Feature == "+fxsr") {
 | |
|       HasFXSR = true;
 | |
|     } else if (Feature == "+xsave") {
 | |
|       HasXSAVE = true;
 | |
|     } else if (Feature == "+xsaveopt") {
 | |
|       HasXSAVEOPT = true;
 | |
|     } else if (Feature == "+xsavec") {
 | |
|       HasXSAVEC = true;
 | |
|     } else if (Feature == "+xsaves") {
 | |
|       HasXSAVES = true;
 | |
|     } else if (Feature == "+mwaitx") {
 | |
|       HasMWAITX = true;
 | |
|     } else if (Feature == "+pku") {
 | |
|       HasPKU = true;
 | |
|     } else if (Feature == "+clflushopt") {
 | |
|       HasCLFLUSHOPT = true;
 | |
|     } else if (Feature == "+clwb") {
 | |
|       HasCLWB = true;
 | |
|     } else if (Feature == "+wbnoinvd") {
 | |
|       HasWBNOINVD = true;
 | |
|     } else if (Feature == "+prefetchwt1") {
 | |
|       HasPREFETCHWT1 = true;
 | |
|     } else if (Feature == "+clzero") {
 | |
|       HasCLZERO = true;
 | |
|     } else if (Feature == "+cldemote") {
 | |
|       HasCLDEMOTE = true;
 | |
|     } else if (Feature == "+rdpid") {
 | |
|       HasRDPID = true;
 | |
|     } else if (Feature == "+retpoline-external-thunk") {
 | |
|       HasRetpolineExternalThunk = true;
 | |
|     } else if (Feature == "+sahf") {
 | |
|       HasLAHFSAHF = true;
 | |
|     } else if (Feature == "+waitpkg") {
 | |
|       HasWAITPKG = true;
 | |
|     } else if (Feature == "+movdiri") {
 | |
|       HasMOVDIRI = true;
 | |
|     } else if (Feature == "+movdir64b") {
 | |
|       HasMOVDIR64B = true;
 | |
|     } else if (Feature == "+pconfig") {
 | |
|       HasPCONFIG = true;
 | |
|     } else if (Feature == "+ptwrite") {
 | |
|       HasPTWRITE = true;
 | |
|     } else if (Feature == "+invpcid") {
 | |
|       HasINVPCID = true;
 | |
|     } else if (Feature == "+enqcmd") {
 | |
|       HasENQCMD = true;
 | |
|     }
 | |
| 
 | |
|     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
 | |
|                            .Case("+avx512f", AVX512F)
 | |
|                            .Case("+avx2", AVX2)
 | |
|                            .Case("+avx", AVX)
 | |
|                            .Case("+sse4.2", SSE42)
 | |
|                            .Case("+sse4.1", SSE41)
 | |
|                            .Case("+ssse3", SSSE3)
 | |
|                            .Case("+sse3", SSE3)
 | |
|                            .Case("+sse2", SSE2)
 | |
|                            .Case("+sse", SSE1)
 | |
|                            .Default(NoSSE);
 | |
|     SSELevel = std::max(SSELevel, Level);
 | |
| 
 | |
|     MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature)
 | |
|                                       .Case("+3dnowa", AMD3DNowAthlon)
 | |
|                                       .Case("+3dnow", AMD3DNow)
 | |
|                                       .Case("+mmx", MMX)
 | |
|                                       .Default(NoMMX3DNow);
 | |
|     MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
 | |
| 
 | |
|     XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
 | |
|                          .Case("+xop", XOP)
 | |
|                          .Case("+fma4", FMA4)
 | |
|                          .Case("+sse4a", SSE4A)
 | |
|                          .Default(NoXOP);
 | |
|     XOPLevel = std::max(XOPLevel, XLevel);
 | |
|   }
 | |
| 
 | |
|   // LLVM doesn't have a separate switch for fpmath, so only accept it if it
 | |
|   // matches the selected sse level.
 | |
|   if ((FPMath == FP_SSE && SSELevel < SSE1) ||
 | |
|       (FPMath == FP_387 && SSELevel >= SSE1)) {
 | |
|     Diags.Report(diag::err_target_unsupported_fpmath)
 | |
|         << (FPMath == FP_SSE ? "sse" : "387");
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   SimdDefaultAlign =
 | |
|       hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
 | |
| /// definitions for this particular subtarget.
 | |
| void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
 | |
|                                      MacroBuilder &Builder) const {
 | |
|   // Inline assembly supports X86 flag outputs.
 | |
|   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
 | |
| 
 | |
|   std::string CodeModel = getTargetOpts().CodeModel;
 | |
|   if (CodeModel == "default")
 | |
|     CodeModel = "small";
 | |
|   Builder.defineMacro("__code_model_" + CodeModel + "__");
 | |
| 
 | |
|   // Target identification.
 | |
|   if (getTriple().getArch() == llvm::Triple::x86_64) {
 | |
|     Builder.defineMacro("__amd64__");
 | |
|     Builder.defineMacro("__amd64");
 | |
|     Builder.defineMacro("__x86_64");
 | |
|     Builder.defineMacro("__x86_64__");
 | |
|     if (getTriple().getArchName() == "x86_64h") {
 | |
|       Builder.defineMacro("__x86_64h");
 | |
|       Builder.defineMacro("__x86_64h__");
 | |
|     }
 | |
|   } else {
 | |
|     DefineStd(Builder, "i386", Opts);
 | |
|   }
 | |
| 
 | |
|   Builder.defineMacro("__SEG_GS");
 | |
|   Builder.defineMacro("__SEG_FS");
 | |
|   Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))");
 | |
|   Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))");
 | |
| 
 | |
|   // Subtarget options.
 | |
|   // FIXME: We are hard-coding the tune parameters based on the CPU, but they
 | |
|   // truly should be based on -mtune options.
 | |
|   switch (CPU) {
 | |
|   case CK_Generic:
 | |
|     break;
 | |
|   case CK_i386:
 | |
|     // The rest are coming from the i386 define above.
 | |
|     Builder.defineMacro("__tune_i386__");
 | |
|     break;
 | |
|   case CK_i486:
 | |
|   case CK_WinChipC6:
 | |
|   case CK_WinChip2:
 | |
|   case CK_C3:
 | |
|     defineCPUMacros(Builder, "i486");
 | |
|     break;
 | |
|   case CK_PentiumMMX:
 | |
|     Builder.defineMacro("__pentium_mmx__");
 | |
|     Builder.defineMacro("__tune_pentium_mmx__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_i586:
 | |
|   case CK_Pentium:
 | |
|     defineCPUMacros(Builder, "i586");
 | |
|     defineCPUMacros(Builder, "pentium");
 | |
|     break;
 | |
|   case CK_Pentium3:
 | |
|   case CK_PentiumM:
 | |
|     Builder.defineMacro("__tune_pentium3__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_Pentium2:
 | |
|   case CK_C3_2:
 | |
|     Builder.defineMacro("__tune_pentium2__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_PentiumPro:
 | |
|   case CK_i686:
 | |
|     defineCPUMacros(Builder, "i686");
 | |
|     defineCPUMacros(Builder, "pentiumpro");
 | |
|     break;
 | |
|   case CK_Pentium4:
 | |
|     defineCPUMacros(Builder, "pentium4");
 | |
|     break;
 | |
|   case CK_Yonah:
 | |
|   case CK_Prescott:
 | |
|   case CK_Nocona:
 | |
|     defineCPUMacros(Builder, "nocona");
 | |
|     break;
 | |
|   case CK_Core2:
 | |
|   case CK_Penryn:
 | |
|     defineCPUMacros(Builder, "core2");
 | |
|     break;
 | |
|   case CK_Bonnell:
 | |
|     defineCPUMacros(Builder, "atom");
 | |
|     break;
 | |
|   case CK_Silvermont:
 | |
|     defineCPUMacros(Builder, "slm");
 | |
|     break;
 | |
|   case CK_Goldmont:
 | |
|     defineCPUMacros(Builder, "goldmont");
 | |
|     break;
 | |
|   case CK_GoldmontPlus:
 | |
|     defineCPUMacros(Builder, "goldmont_plus");
 | |
|     break;
 | |
|   case CK_Tremont:
 | |
|     defineCPUMacros(Builder, "tremont");
 | |
|     break;
 | |
|   case CK_Nehalem:
 | |
|   case CK_Westmere:
 | |
|   case CK_SandyBridge:
 | |
|   case CK_IvyBridge:
 | |
|   case CK_Haswell:
 | |
|   case CK_Broadwell:
 | |
|   case CK_SkylakeClient:
 | |
|   case CK_SkylakeServer:
 | |
|   case CK_Cascadelake:
 | |
|   case CK_Cooperlake:
 | |
|   case CK_Cannonlake:
 | |
|   case CK_IcelakeClient:
 | |
|   case CK_IcelakeServer:
 | |
|   case CK_Tigerlake:
 | |
|     // FIXME: Historically, we defined this legacy name, it would be nice to
 | |
|     // remove it at some point. We've never exposed fine-grained names for
 | |
|     // recent primary x86 CPUs, and we should keep it that way.
 | |
|     defineCPUMacros(Builder, "corei7");
 | |
|     break;
 | |
|   case CK_KNL:
 | |
|     defineCPUMacros(Builder, "knl");
 | |
|     break;
 | |
|   case CK_KNM:
 | |
|     break;
 | |
|   case CK_Lakemont:
 | |
|     defineCPUMacros(Builder, "i586", /*Tuning*/false);
 | |
|     defineCPUMacros(Builder, "pentium", /*Tuning*/false);
 | |
|     Builder.defineMacro("__tune_lakemont__");
 | |
|     break;
 | |
|   case CK_K6_2:
 | |
|     Builder.defineMacro("__k6_2__");
 | |
|     Builder.defineMacro("__tune_k6_2__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_K6_3:
 | |
|     if (CPU != CK_K6_2) { // In case of fallthrough
 | |
|       // FIXME: GCC may be enabling these in cases where some other k6
 | |
|       // architecture is specified but -m3dnow is explicitly provided. The
 | |
|       // exact semantics need to be determined and emulated here.
 | |
|       Builder.defineMacro("__k6_3__");
 | |
|       Builder.defineMacro("__tune_k6_3__");
 | |
|     }
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case CK_K6:
 | |
|     defineCPUMacros(Builder, "k6");
 | |
|     break;
 | |
|   case CK_Athlon:
 | |
|   case CK_AthlonXP:
 | |
|     defineCPUMacros(Builder, "athlon");
 | |
|     if (SSELevel != NoSSE) {
 | |
|       Builder.defineMacro("__athlon_sse__");
 | |
|       Builder.defineMacro("__tune_athlon_sse__");
 | |
|     }
 | |
|     break;
 | |
|   case CK_K8:
 | |
|   case CK_K8SSE3:
 | |
|   case CK_x86_64:
 | |
|     defineCPUMacros(Builder, "k8");
 | |
|     break;
 | |
|   case CK_AMDFAM10:
 | |
|     defineCPUMacros(Builder, "amdfam10");
 | |
|     break;
 | |
|   case CK_BTVER1:
 | |
|     defineCPUMacros(Builder, "btver1");
 | |
|     break;
 | |
|   case CK_BTVER2:
 | |
|     defineCPUMacros(Builder, "btver2");
 | |
|     break;
 | |
|   case CK_BDVER1:
 | |
|     defineCPUMacros(Builder, "bdver1");
 | |
|     break;
 | |
|   case CK_BDVER2:
 | |
|     defineCPUMacros(Builder, "bdver2");
 | |
|     break;
 | |
|   case CK_BDVER3:
 | |
|     defineCPUMacros(Builder, "bdver3");
 | |
|     break;
 | |
|   case CK_BDVER4:
 | |
|     defineCPUMacros(Builder, "bdver4");
 | |
|     break;
 | |
|   case CK_ZNVER1:
 | |
|     defineCPUMacros(Builder, "znver1");
 | |
|     break;
 | |
|   case CK_ZNVER2:
 | |
|     defineCPUMacros(Builder, "znver2");
 | |
|     break;
 | |
|   case CK_Geode:
 | |
|     defineCPUMacros(Builder, "geode");
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   // Target properties.
 | |
|   Builder.defineMacro("__REGISTER_PREFIX__", "");
 | |
| 
 | |
|   // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
 | |
|   // functions in glibc header files that use FP Stack inline asm which the
 | |
|   // backend can't deal with (PR879).
 | |
|   Builder.defineMacro("__NO_MATH_INLINES");
 | |
| 
 | |
|   if (HasAES)
 | |
|     Builder.defineMacro("__AES__");
 | |
| 
 | |
|   if (HasVAES)
 | |
|     Builder.defineMacro("__VAES__");
 | |
| 
 | |
|   if (HasPCLMUL)
 | |
|     Builder.defineMacro("__PCLMUL__");
 | |
| 
 | |
|   if (HasVPCLMULQDQ)
 | |
|     Builder.defineMacro("__VPCLMULQDQ__");
 | |
| 
 | |
|   if (HasLZCNT)
 | |
|     Builder.defineMacro("__LZCNT__");
 | |
| 
 | |
|   if (HasRDRND)
 | |
|     Builder.defineMacro("__RDRND__");
 | |
| 
 | |
|   if (HasFSGSBASE)
 | |
|     Builder.defineMacro("__FSGSBASE__");
 | |
| 
 | |
|   if (HasBMI)
 | |
|     Builder.defineMacro("__BMI__");
 | |
| 
 | |
|   if (HasBMI2)
 | |
|     Builder.defineMacro("__BMI2__");
 | |
| 
 | |
|   if (HasPOPCNT)
 | |
|     Builder.defineMacro("__POPCNT__");
 | |
| 
 | |
|   if (HasRTM)
 | |
|     Builder.defineMacro("__RTM__");
 | |
| 
 | |
|   if (HasPRFCHW)
 | |
|     Builder.defineMacro("__PRFCHW__");
 | |
| 
 | |
|   if (HasRDSEED)
 | |
|     Builder.defineMacro("__RDSEED__");
 | |
| 
 | |
|   if (HasADX)
 | |
|     Builder.defineMacro("__ADX__");
 | |
| 
 | |
|   if (HasTBM)
 | |
|     Builder.defineMacro("__TBM__");
 | |
| 
 | |
|   if (HasLWP)
 | |
|     Builder.defineMacro("__LWP__");
 | |
| 
 | |
|   if (HasMWAITX)
 | |
|     Builder.defineMacro("__MWAITX__");
 | |
| 
 | |
|   if (HasMOVBE)
 | |
|     Builder.defineMacro("__MOVBE__");
 | |
| 
 | |
|   switch (XOPLevel) {
 | |
|   case XOP:
 | |
|     Builder.defineMacro("__XOP__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case FMA4:
 | |
|     Builder.defineMacro("__FMA4__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE4A:
 | |
|     Builder.defineMacro("__SSE4A__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case NoXOP:
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   if (HasFMA)
 | |
|     Builder.defineMacro("__FMA__");
 | |
| 
 | |
|   if (HasF16C)
 | |
|     Builder.defineMacro("__F16C__");
 | |
| 
 | |
|   if (HasGFNI)
 | |
|     Builder.defineMacro("__GFNI__");
 | |
| 
 | |
|   if (HasAVX512CD)
 | |
|     Builder.defineMacro("__AVX512CD__");
 | |
|   if (HasAVX512VPOPCNTDQ)
 | |
|     Builder.defineMacro("__AVX512VPOPCNTDQ__");
 | |
|   if (HasAVX512VNNI)
 | |
|     Builder.defineMacro("__AVX512VNNI__");
 | |
|   if (HasAVX512BF16)
 | |
|     Builder.defineMacro("__AVX512BF16__");
 | |
|   if (HasAVX512ER)
 | |
|     Builder.defineMacro("__AVX512ER__");
 | |
|   if (HasAVX512PF)
 | |
|     Builder.defineMacro("__AVX512PF__");
 | |
|   if (HasAVX512DQ)
 | |
|     Builder.defineMacro("__AVX512DQ__");
 | |
|   if (HasAVX512BITALG)
 | |
|     Builder.defineMacro("__AVX512BITALG__");
 | |
|   if (HasAVX512BW)
 | |
|     Builder.defineMacro("__AVX512BW__");
 | |
|   if (HasAVX512VL)
 | |
|     Builder.defineMacro("__AVX512VL__");
 | |
|   if (HasAVX512VBMI)
 | |
|     Builder.defineMacro("__AVX512VBMI__");
 | |
|   if (HasAVX512VBMI2)
 | |
|     Builder.defineMacro("__AVX512VBMI2__");
 | |
|   if (HasAVX512IFMA)
 | |
|     Builder.defineMacro("__AVX512IFMA__");
 | |
|   if (HasAVX512VP2INTERSECT)
 | |
|     Builder.defineMacro("__AVX512VP2INTERSECT__");
 | |
|   if (HasSHA)
 | |
|     Builder.defineMacro("__SHA__");
 | |
| 
 | |
|   if (HasFXSR)
 | |
|     Builder.defineMacro("__FXSR__");
 | |
|   if (HasXSAVE)
 | |
|     Builder.defineMacro("__XSAVE__");
 | |
|   if (HasXSAVEOPT)
 | |
|     Builder.defineMacro("__XSAVEOPT__");
 | |
|   if (HasXSAVEC)
 | |
|     Builder.defineMacro("__XSAVEC__");
 | |
|   if (HasXSAVES)
 | |
|     Builder.defineMacro("__XSAVES__");
 | |
|   if (HasPKU)
 | |
|     Builder.defineMacro("__PKU__");
 | |
|   if (HasCLFLUSHOPT)
 | |
|     Builder.defineMacro("__CLFLUSHOPT__");
 | |
|   if (HasCLWB)
 | |
|     Builder.defineMacro("__CLWB__");
 | |
|   if (HasWBNOINVD)
 | |
|     Builder.defineMacro("__WBNOINVD__");
 | |
|   if (HasSHSTK)
 | |
|     Builder.defineMacro("__SHSTK__");
 | |
|   if (HasSGX)
 | |
|     Builder.defineMacro("__SGX__");
 | |
|   if (HasPREFETCHWT1)
 | |
|     Builder.defineMacro("__PREFETCHWT1__");
 | |
|   if (HasCLZERO)
 | |
|     Builder.defineMacro("__CLZERO__");
 | |
|   if (HasRDPID)
 | |
|     Builder.defineMacro("__RDPID__");
 | |
|   if (HasCLDEMOTE)
 | |
|     Builder.defineMacro("__CLDEMOTE__");
 | |
|   if (HasWAITPKG)
 | |
|     Builder.defineMacro("__WAITPKG__");
 | |
|   if (HasMOVDIRI)
 | |
|     Builder.defineMacro("__MOVDIRI__");
 | |
|   if (HasMOVDIR64B)
 | |
|     Builder.defineMacro("__MOVDIR64B__");
 | |
|   if (HasPCONFIG)
 | |
|     Builder.defineMacro("__PCONFIG__");
 | |
|   if (HasPTWRITE)
 | |
|     Builder.defineMacro("__PTWRITE__");
 | |
|   if (HasINVPCID)
 | |
|     Builder.defineMacro("__INVPCID__");
 | |
|   if (HasENQCMD)
 | |
|     Builder.defineMacro("__ENQCMD__");
 | |
| 
 | |
|   // Each case falls through to the previous one here.
 | |
|   switch (SSELevel) {
 | |
|   case AVX512F:
 | |
|     Builder.defineMacro("__AVX512F__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case AVX2:
 | |
|     Builder.defineMacro("__AVX2__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case AVX:
 | |
|     Builder.defineMacro("__AVX__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE42:
 | |
|     Builder.defineMacro("__SSE4_2__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE41:
 | |
|     Builder.defineMacro("__SSE4_1__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSSE3:
 | |
|     Builder.defineMacro("__SSSE3__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE3:
 | |
|     Builder.defineMacro("__SSE3__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE2:
 | |
|     Builder.defineMacro("__SSE2__");
 | |
|     Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case SSE1:
 | |
|     Builder.defineMacro("__SSE__");
 | |
|     Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case NoSSE:
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
 | |
|     switch (SSELevel) {
 | |
|     case AVX512F:
 | |
|     case AVX2:
 | |
|     case AVX:
 | |
|     case SSE42:
 | |
|     case SSE41:
 | |
|     case SSSE3:
 | |
|     case SSE3:
 | |
|     case SSE2:
 | |
|       Builder.defineMacro("_M_IX86_FP", Twine(2));
 | |
|       break;
 | |
|     case SSE1:
 | |
|       Builder.defineMacro("_M_IX86_FP", Twine(1));
 | |
|       break;
 | |
|     default:
 | |
|       Builder.defineMacro("_M_IX86_FP", Twine(0));
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Each case falls through to the previous one here.
 | |
|   switch (MMX3DNowLevel) {
 | |
|   case AMD3DNowAthlon:
 | |
|     Builder.defineMacro("__3dNOW_A__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case AMD3DNow:
 | |
|     Builder.defineMacro("__3dNOW__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case MMX:
 | |
|     Builder.defineMacro("__MMX__");
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case NoMMX3DNow:
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   if (CPU >= CK_i486 || CPU == CK_Generic) {
 | |
|     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
 | |
|     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
 | |
|     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
 | |
|   }
 | |
|   if (HasCX8)
 | |
|     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
 | |
|   if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)
 | |
|     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
 | |
| 
 | |
|   if (HasFloat128)
 | |
|     Builder.defineMacro("__SIZEOF_FLOAT128__", "16");
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
 | |
|   return llvm::StringSwitch<bool>(Name)
 | |
|       .Case("3dnow", true)
 | |
|       .Case("3dnowa", true)
 | |
|       .Case("adx", true)
 | |
|       .Case("aes", true)
 | |
|       .Case("avx", true)
 | |
|       .Case("avx2", true)
 | |
|       .Case("avx512f", true)
 | |
|       .Case("avx512cd", true)
 | |
|       .Case("avx512vpopcntdq", true)
 | |
|       .Case("avx512vnni", true)
 | |
|       .Case("avx512bf16", true)
 | |
|       .Case("avx512er", true)
 | |
|       .Case("avx512pf", true)
 | |
|       .Case("avx512dq", true)
 | |
|       .Case("avx512bitalg", true)
 | |
|       .Case("avx512bw", true)
 | |
|       .Case("avx512vl", true)
 | |
|       .Case("avx512vbmi", true)
 | |
|       .Case("avx512vbmi2", true)
 | |
|       .Case("avx512ifma", true)
 | |
|       .Case("avx512vp2intersect", true)
 | |
|       .Case("bmi", true)
 | |
|       .Case("bmi2", true)
 | |
|       .Case("cldemote", true)
 | |
|       .Case("clflushopt", true)
 | |
|       .Case("clwb", true)
 | |
|       .Case("clzero", true)
 | |
|       .Case("cx16", true)
 | |
|       .Case("enqcmd", true)
 | |
|       .Case("f16c", true)
 | |
|       .Case("fma", true)
 | |
|       .Case("fma4", true)
 | |
|       .Case("fsgsbase", true)
 | |
|       .Case("fxsr", true)
 | |
|       .Case("gfni", true)
 | |
|       .Case("invpcid", true)
 | |
|       .Case("lwp", true)
 | |
|       .Case("lzcnt", true)
 | |
|       .Case("mmx", true)
 | |
|       .Case("movbe", true)
 | |
|       .Case("movdiri", true)
 | |
|       .Case("movdir64b", true)
 | |
|       .Case("mwaitx", true)
 | |
|       .Case("pclmul", true)
 | |
|       .Case("pconfig", true)
 | |
|       .Case("pku", true)
 | |
|       .Case("popcnt", true)
 | |
|       .Case("prefetchwt1", true)
 | |
|       .Case("prfchw", true)
 | |
|       .Case("ptwrite", true)
 | |
|       .Case("rdpid", true)
 | |
|       .Case("rdrnd", true)
 | |
|       .Case("rdseed", true)
 | |
|       .Case("rtm", true)
 | |
|       .Case("sahf", true)
 | |
|       .Case("sgx", true)
 | |
|       .Case("sha", true)
 | |
|       .Case("shstk", true)
 | |
|       .Case("sse", true)
 | |
|       .Case("sse2", true)
 | |
|       .Case("sse3", true)
 | |
|       .Case("ssse3", true)
 | |
|       .Case("sse4", true)
 | |
|       .Case("sse4.1", true)
 | |
|       .Case("sse4.2", true)
 | |
|       .Case("sse4a", true)
 | |
|       .Case("tbm", true)
 | |
|       .Case("vaes", true)
 | |
|       .Case("vpclmulqdq", true)
 | |
|       .Case("wbnoinvd", true)
 | |
|       .Case("waitpkg", true)
 | |
|       .Case("x87", true)
 | |
|       .Case("xop", true)
 | |
|       .Case("xsave", true)
 | |
|       .Case("xsavec", true)
 | |
|       .Case("xsaves", true)
 | |
|       .Case("xsaveopt", true)
 | |
|       .Default(false);
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::hasFeature(StringRef Feature) const {
 | |
|   return llvm::StringSwitch<bool>(Feature)
 | |
|       .Case("adx", HasADX)
 | |
|       .Case("aes", HasAES)
 | |
|       .Case("avx", SSELevel >= AVX)
 | |
|       .Case("avx2", SSELevel >= AVX2)
 | |
|       .Case("avx512f", SSELevel >= AVX512F)
 | |
|       .Case("avx512cd", HasAVX512CD)
 | |
|       .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ)
 | |
|       .Case("avx512vnni", HasAVX512VNNI)
 | |
|       .Case("avx512bf16", HasAVX512BF16)
 | |
|       .Case("avx512er", HasAVX512ER)
 | |
|       .Case("avx512pf", HasAVX512PF)
 | |
|       .Case("avx512dq", HasAVX512DQ)
 | |
|       .Case("avx512bitalg", HasAVX512BITALG)
 | |
|       .Case("avx512bw", HasAVX512BW)
 | |
|       .Case("avx512vl", HasAVX512VL)
 | |
|       .Case("avx512vbmi", HasAVX512VBMI)
 | |
|       .Case("avx512vbmi2", HasAVX512VBMI2)
 | |
|       .Case("avx512ifma", HasAVX512IFMA)
 | |
|       .Case("avx512vp2intersect", HasAVX512VP2INTERSECT)
 | |
|       .Case("bmi", HasBMI)
 | |
|       .Case("bmi2", HasBMI2)
 | |
|       .Case("cldemote", HasCLDEMOTE)
 | |
|       .Case("clflushopt", HasCLFLUSHOPT)
 | |
|       .Case("clwb", HasCLWB)
 | |
|       .Case("clzero", HasCLZERO)
 | |
|       .Case("cx8", HasCX8)
 | |
|       .Case("cx16", HasCX16)
 | |
|       .Case("enqcmd", HasENQCMD)
 | |
|       .Case("f16c", HasF16C)
 | |
|       .Case("fma", HasFMA)
 | |
|       .Case("fma4", XOPLevel >= FMA4)
 | |
|       .Case("fsgsbase", HasFSGSBASE)
 | |
|       .Case("fxsr", HasFXSR)
 | |
|       .Case("gfni", HasGFNI)
 | |
|       .Case("invpcid", HasINVPCID)
 | |
|       .Case("lwp", HasLWP)
 | |
|       .Case("lzcnt", HasLZCNT)
 | |
|       .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
 | |
|       .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
 | |
|       .Case("mmx", MMX3DNowLevel >= MMX)
 | |
|       .Case("movbe", HasMOVBE)
 | |
|       .Case("movdiri", HasMOVDIRI)
 | |
|       .Case("movdir64b", HasMOVDIR64B)
 | |
|       .Case("mwaitx", HasMWAITX)
 | |
|       .Case("pclmul", HasPCLMUL)
 | |
|       .Case("pconfig", HasPCONFIG)
 | |
|       .Case("pku", HasPKU)
 | |
|       .Case("popcnt", HasPOPCNT)
 | |
|       .Case("prefetchwt1", HasPREFETCHWT1)
 | |
|       .Case("prfchw", HasPRFCHW)
 | |
|       .Case("ptwrite", HasPTWRITE)
 | |
|       .Case("rdpid", HasRDPID)
 | |
|       .Case("rdrnd", HasRDRND)
 | |
|       .Case("rdseed", HasRDSEED)
 | |
|       .Case("retpoline-external-thunk", HasRetpolineExternalThunk)
 | |
|       .Case("rtm", HasRTM)
 | |
|       .Case("sahf", HasLAHFSAHF)
 | |
|       .Case("sgx", HasSGX)
 | |
|       .Case("sha", HasSHA)
 | |
|       .Case("shstk", HasSHSTK)
 | |
|       .Case("sse", SSELevel >= SSE1)
 | |
|       .Case("sse2", SSELevel >= SSE2)
 | |
|       .Case("sse3", SSELevel >= SSE3)
 | |
|       .Case("ssse3", SSELevel >= SSSE3)
 | |
|       .Case("sse4.1", SSELevel >= SSE41)
 | |
|       .Case("sse4.2", SSELevel >= SSE42)
 | |
|       .Case("sse4a", XOPLevel >= SSE4A)
 | |
|       .Case("tbm", HasTBM)
 | |
|       .Case("vaes", HasVAES)
 | |
|       .Case("vpclmulqdq", HasVPCLMULQDQ)
 | |
|       .Case("wbnoinvd", HasWBNOINVD)
 | |
|       .Case("waitpkg", HasWAITPKG)
 | |
|       .Case("x86", true)
 | |
|       .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
 | |
|       .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
 | |
|       .Case("xop", XOPLevel >= XOP)
 | |
|       .Case("xsave", HasXSAVE)
 | |
|       .Case("xsavec", HasXSAVEC)
 | |
|       .Case("xsaves", HasXSAVES)
 | |
|       .Case("xsaveopt", HasXSAVEOPT)
 | |
|       .Default(false);
 | |
| }
 | |
| 
 | |
| // We can't use a generic validation scheme for the features accepted here
 | |
| // versus subtarget features accepted in the target attribute because the
 | |
| // bitfield structure that's initialized in the runtime only supports the
 | |
| // below currently rather than the full range of subtarget features. (See
 | |
| // X86TargetInfo::hasFeature for a somewhat comprehensive list).
 | |
| bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
 | |
|   return llvm::StringSwitch<bool>(FeatureStr)
 | |
| #define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, true)
 | |
| #include "llvm/Support/X86TargetParser.def"
 | |
|       .Default(false);
 | |
| }
 | |
| 
 | |
| static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {
 | |
|   return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)
 | |
| #define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, llvm::X86::ENUM)
 | |
| #include "llvm/Support/X86TargetParser.def"
 | |
|       ;
 | |
|   // Note, this function should only be used after ensuring the value is
 | |
|   // correct, so it asserts if the value is out of range.
 | |
| }
 | |
| 
 | |
| static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) {
 | |
|   enum class FeatPriority {
 | |
| #define FEATURE(FEAT) FEAT,
 | |
| #include "clang/Basic/X86Target.def"
 | |
|   };
 | |
|   switch (Feat) {
 | |
| #define FEATURE(FEAT)                                                          \
 | |
|   case llvm::X86::FEAT:                                                        \
 | |
|     return static_cast<unsigned>(FeatPriority::FEAT);
 | |
| #include "clang/Basic/X86Target.def"
 | |
|   default:
 | |
|     llvm_unreachable("No Feature Priority for non-CPUSupports Features");
 | |
|   }
 | |
| }
 | |
| 
 | |
| unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
 | |
|   // Valid CPUs have a 'key feature' that compares just better than its key
 | |
|   // feature.
 | |
|   CPUKind Kind = getCPUKind(Name);
 | |
|   if (Kind != CK_Generic) {
 | |
|     switch (Kind) {
 | |
|     default:
 | |
|       llvm_unreachable(
 | |
|           "CPU Type without a key feature used in 'target' attribute");
 | |
| #define PROC_WITH_FEAT(ENUM, STR, IS64, KEY_FEAT)                              \
 | |
|   case CK_##ENUM:                                                              \
 | |
|     return (getFeaturePriority(llvm::X86::KEY_FEAT) << 1) + 1;
 | |
| #include "clang/Basic/X86Target.def"
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Now we know we have a feature, so get its priority and shift it a few so
 | |
|   // that we have sufficient room for the CPUs (above).
 | |
|   return getFeaturePriority(getFeature(Name)) << 1;
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const {
 | |
|   return llvm::StringSwitch<bool>(Name)
 | |
| #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true)
 | |
| #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true)
 | |
| #include "clang/Basic/X86Target.def"
 | |
|       .Default(false);
 | |
| }
 | |
| 
 | |
| static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) {
 | |
|   return llvm::StringSwitch<StringRef>(Name)
 | |
| #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME)
 | |
| #include "clang/Basic/X86Target.def"
 | |
|       .Default(Name);
 | |
| }
 | |
| 
 | |
| char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const {
 | |
|   return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name))
 | |
| #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING)
 | |
| #include "clang/Basic/X86Target.def"
 | |
|       .Default(0);
 | |
| }
 | |
| 
 | |
| void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(
 | |
|     StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
 | |
|   StringRef WholeList =
 | |
|       llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name))
 | |
| #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES)
 | |
| #include "clang/Basic/X86Target.def"
 | |
|           .Default("");
 | |
|   WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
 | |
| }
 | |
| 
 | |
| // We can't use a generic validation scheme for the cpus accepted here
 | |
| // versus subtarget cpus accepted in the target attribute because the
 | |
| // variables intitialized by the runtime only support the below currently
 | |
| // rather than the full range of cpus.
 | |
| bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
 | |
|   return llvm::StringSwitch<bool>(FeatureStr)
 | |
| #define X86_VENDOR(ENUM, STRING) .Case(STRING, true)
 | |
| #define X86_CPU_TYPE_COMPAT_WITH_ALIAS(ARCHNAME, ENUM, STR, ALIAS)             \
 | |
|   .Cases(STR, ALIAS, true)
 | |
| #define X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true)
 | |
| #define X86_CPU_SUBTYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true)
 | |
| #include "llvm/Support/X86TargetParser.def"
 | |
|       .Default(false);
 | |
| }
 | |
| 
 | |
| static unsigned matchAsmCCConstraint(const char *&Name) {
 | |
|   auto RV = llvm::StringSwitch<unsigned>(Name)
 | |
|                 .Case("@cca", 4)
 | |
|                 .Case("@ccae", 5)
 | |
|                 .Case("@ccb", 4)
 | |
|                 .Case("@ccbe", 5)
 | |
|                 .Case("@ccc", 4)
 | |
|                 .Case("@cce", 4)
 | |
|                 .Case("@ccz", 4)
 | |
|                 .Case("@ccg", 4)
 | |
|                 .Case("@ccge", 5)
 | |
|                 .Case("@ccl", 4)
 | |
|                 .Case("@ccle", 5)
 | |
|                 .Case("@ccna", 5)
 | |
|                 .Case("@ccnae", 6)
 | |
|                 .Case("@ccnb", 5)
 | |
|                 .Case("@ccnbe", 6)
 | |
|                 .Case("@ccnc", 5)
 | |
|                 .Case("@ccne", 5)
 | |
|                 .Case("@ccnz", 5)
 | |
|                 .Case("@ccng", 5)
 | |
|                 .Case("@ccnge", 6)
 | |
|                 .Case("@ccnl", 5)
 | |
|                 .Case("@ccnle", 6)
 | |
|                 .Case("@ccno", 5)
 | |
|                 .Case("@ccnp", 5)
 | |
|                 .Case("@ccns", 5)
 | |
|                 .Case("@cco", 4)
 | |
|                 .Case("@ccp", 4)
 | |
|                 .Case("@ccs", 4)
 | |
|                 .Default(0);
 | |
|   return RV;
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::validateAsmConstraint(
 | |
|     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
 | |
|   switch (*Name) {
 | |
|   default:
 | |
|     return false;
 | |
|   // Constant constraints.
 | |
|   case 'e': // 32-bit signed integer constant for use with sign-extending x86_64
 | |
|             // instructions.
 | |
|   case 'Z': // 32-bit unsigned integer constant for use with zero-extending
 | |
|             // x86_64 instructions.
 | |
|   case 's':
 | |
|     Info.setRequiresImmediate();
 | |
|     return true;
 | |
|   case 'I':
 | |
|     Info.setRequiresImmediate(0, 31);
 | |
|     return true;
 | |
|   case 'J':
 | |
|     Info.setRequiresImmediate(0, 63);
 | |
|     return true;
 | |
|   case 'K':
 | |
|     Info.setRequiresImmediate(-128, 127);
 | |
|     return true;
 | |
|   case 'L':
 | |
|     Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)});
 | |
|     return true;
 | |
|   case 'M':
 | |
|     Info.setRequiresImmediate(0, 3);
 | |
|     return true;
 | |
|   case 'N':
 | |
|     Info.setRequiresImmediate(0, 255);
 | |
|     return true;
 | |
|   case 'O':
 | |
|     Info.setRequiresImmediate(0, 127);
 | |
|     return true;
 | |
|   // Register constraints.
 | |
|   case 'Y': // 'Y' is the first character for several 2-character constraints.
 | |
|     // Shift the pointer to the second character of the constraint.
 | |
|     Name++;
 | |
|     switch (*Name) {
 | |
|     default:
 | |
|       return false;
 | |
|     case 'z':
 | |
|     case '0': // First SSE register.
 | |
|     case '2':
 | |
|     case 't': // Any SSE register, when SSE2 is enabled.
 | |
|     case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
 | |
|     case 'm': // Any MMX register, when inter-unit moves enabled.
 | |
|     case 'k': // AVX512 arch mask registers: k1-k7.
 | |
|       Info.setAllowsRegister();
 | |
|       return true;
 | |
|     }
 | |
|   case 'f': // Any x87 floating point stack register.
 | |
|     // Constraint 'f' cannot be used for output operands.
 | |
|     if (Info.ConstraintStr[0] == '=')
 | |
|       return false;
 | |
|     Info.setAllowsRegister();
 | |
|     return true;
 | |
|   case 'a': // eax.
 | |
|   case 'b': // ebx.
 | |
|   case 'c': // ecx.
 | |
|   case 'd': // edx.
 | |
|   case 'S': // esi.
 | |
|   case 'D': // edi.
 | |
|   case 'A': // edx:eax.
 | |
|   case 't': // Top of floating point stack.
 | |
|   case 'u': // Second from top of floating point stack.
 | |
|   case 'q': // Any register accessible as [r]l: a, b, c, and d.
 | |
|   case 'y': // Any MMX register.
 | |
|   case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)
 | |
|   case 'x': // Any SSE register.
 | |
|   case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0
 | |
|             // for intermideate k reg operations).
 | |
|   case 'Q': // Any register accessible as [r]h: a, b, c, and d.
 | |
|   case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
 | |
|   case 'l': // "Index" registers: any general register that can be used as an
 | |
|             // index in a base+index memory access.
 | |
|     Info.setAllowsRegister();
 | |
|     return true;
 | |
|   // Floating point constant constraints.
 | |
|   case 'C': // SSE floating point constant.
 | |
|   case 'G': // x87 floating point constant.
 | |
|     return true;
 | |
|   case '@':
 | |
|     // CC condition changes.
 | |
|     if (auto Len = matchAsmCCConstraint(Name)) {
 | |
|       Name += Len - 1;
 | |
|       Info.setAllowsRegister();
 | |
|       return true;
 | |
|     }
 | |
|     return false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
 | |
|                                        StringRef Constraint,
 | |
|                                        unsigned Size) const {
 | |
|   // Strip off constraint modifiers.
 | |
|   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
 | |
|     Constraint = Constraint.substr(1);
 | |
| 
 | |
|   return validateOperandSize(FeatureMap, Constraint, Size);
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::validateInputSize(const llvm::StringMap<bool> &FeatureMap,
 | |
|                                       StringRef Constraint,
 | |
|                                       unsigned Size) const {
 | |
|   return validateOperandSize(FeatureMap, Constraint, Size);
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
 | |
|                                         StringRef Constraint,
 | |
|                                         unsigned Size) const {
 | |
|   switch (Constraint[0]) {
 | |
|   default:
 | |
|     break;
 | |
|   case 'k':
 | |
|   // Registers k0-k7 (AVX512) size limit is 64 bit.
 | |
|   case 'y':
 | |
|     return Size <= 64;
 | |
|   case 'f':
 | |
|   case 't':
 | |
|   case 'u':
 | |
|     return Size <= 128;
 | |
|   case 'Y':
 | |
|     // 'Y' is the first character for several 2-character constraints.
 | |
|     switch (Constraint[1]) {
 | |
|     default:
 | |
|       return false;
 | |
|     case 'm':
 | |
|       // 'Ym' is synonymous with 'y'.
 | |
|     case 'k':
 | |
|       return Size <= 64;
 | |
|     case 'z':
 | |
|     case '0':
 | |
|       // XMM0
 | |
|       if (FeatureMap.lookup("sse"))
 | |
|         return Size <= 128U;
 | |
|       return false;
 | |
|     case 'i':
 | |
|     case 't':
 | |
|     case '2':
 | |
|       // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled.
 | |
|       if (SSELevel < SSE2)
 | |
|         return false;
 | |
|       break;
 | |
|     }
 | |
|     LLVM_FALLTHROUGH;
 | |
|   case 'v':
 | |
|   case 'x':
 | |
|     if (FeatureMap.lookup("avx512f"))
 | |
|       // 512-bit zmm registers can be used if target supports AVX512F.
 | |
|       return Size <= 512U;
 | |
|     else if (FeatureMap.lookup("avx"))
 | |
|       // 256-bit ymm registers can be used if target supports AVX.
 | |
|       return Size <= 256U;
 | |
|     return Size <= 128U;
 | |
| 
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
 | |
|   switch (*Constraint) {
 | |
|   case '@':
 | |
|     if (auto Len = matchAsmCCConstraint(Constraint)) {
 | |
|       std::string Converted = "{" + std::string(Constraint, Len) + "}";
 | |
|       Constraint += Len - 1;
 | |
|       return Converted;
 | |
|     }
 | |
|     return std::string(1, *Constraint);
 | |
|   case 'a':
 | |
|     return std::string("{ax}");
 | |
|   case 'b':
 | |
|     return std::string("{bx}");
 | |
|   case 'c':
 | |
|     return std::string("{cx}");
 | |
|   case 'd':
 | |
|     return std::string("{dx}");
 | |
|   case 'S':
 | |
|     return std::string("{si}");
 | |
|   case 'D':
 | |
|     return std::string("{di}");
 | |
|   case 'p': // address
 | |
|     return std::string("im");
 | |
|   case 't': // top of floating point stack.
 | |
|     return std::string("{st}");
 | |
|   case 'u':                        // second from top of floating point stack.
 | |
|     return std::string("{st(1)}"); // second from top of floating point stack.
 | |
|   case 'Y':
 | |
|     switch (Constraint[1]) {
 | |
|     default:
 | |
|       // Break from inner switch and fall through (copy single char),
 | |
|       // continue parsing after copying the current constraint into
 | |
|       // the return string.
 | |
|       break;
 | |
|     case 'k':
 | |
|     case 'm':
 | |
|     case 'i':
 | |
|     case 't':
 | |
|     case 'z':
 | |
|     case '0':
 | |
|     case '2':
 | |
|       // "^" hints llvm that this is a 2 letter constraint.
 | |
|       // "Constraint++" is used to promote the string iterator
 | |
|       // to the next constraint.
 | |
|       return std::string("^") + std::string(Constraint++, 2);
 | |
|     }
 | |
|     LLVM_FALLTHROUGH;
 | |
|   default:
 | |
|     return std::string(1, *Constraint);
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool X86TargetInfo::checkCPUKind(CPUKind Kind) const {
 | |
|   // Perform any per-CPU checks necessary to determine if this CPU is
 | |
|   // acceptable.
 | |
|   switch (Kind) {
 | |
|   case CK_Generic:
 | |
|     // No processor selected!
 | |
|     return false;
 | |
| #define PROC(ENUM, STRING, IS64BIT)                                            \
 | |
|   case CK_##ENUM:                                                              \
 | |
|     return IS64BIT || getTriple().getArch() == llvm::Triple::x86;
 | |
| #include "clang/Basic/X86Target.def"
 | |
|   }
 | |
|   llvm_unreachable("Unhandled CPU kind");
 | |
| }
 | |
| 
 | |
| void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
 | |
| #define PROC(ENUM, STRING, IS64BIT)                                            \
 | |
|   if (IS64BIT || getTriple().getArch() == llvm::Triple::x86)                   \
 | |
|     Values.emplace_back(STRING);
 | |
|   // For aliases we need to lookup the CPUKind to check get the 64-bit ness.
 | |
| #define PROC_ALIAS(ENUM, ALIAS)                                                \
 | |
|   if (checkCPUKind(CK_##ENUM))                                                      \
 | |
|     Values.emplace_back(ALIAS);
 | |
| #include "clang/Basic/X86Target.def"
 | |
| }
 | |
| 
 | |
| X86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const {
 | |
|   return llvm::StringSwitch<CPUKind>(CPU)
 | |
| #define PROC(ENUM, STRING, IS64BIT) .Case(STRING, CK_##ENUM)
 | |
| #define PROC_ALIAS(ENUM, ALIAS) .Case(ALIAS, CK_##ENUM)
 | |
| #include "clang/Basic/X86Target.def"
 | |
|       .Default(CK_Generic);
 | |
| }
 | |
| 
 | |
| ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {
 | |
|   return llvm::makeArrayRef(GCCRegNames);
 | |
| }
 | |
| 
 | |
| ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
 | |
|   return llvm::makeArrayRef(AddlRegNames);
 | |
| }
 | |
| 
 | |
| ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
 | |
|   return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
 | |
|                                                 Builtin::FirstTSBuiltin + 1);
 | |
| }
 | |
| 
 | |
| ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
 | |
|   return llvm::makeArrayRef(BuiltinInfoX86,
 | |
|                             X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
 | |
| }
 |