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