1e5dd7070Spatrick //===--- X86.cpp - Implement X86 target feature support -------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements X86 TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "X86.h"
14e5dd7070Spatrick #include "clang/Basic/Builtins.h"
15e5dd7070Spatrick #include "clang/Basic/Diagnostic.h"
16e5dd7070Spatrick #include "clang/Basic/TargetBuiltins.h"
17e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
18e5dd7070Spatrick #include "llvm/ADT/StringRef.h"
19e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
20ec727ea7Spatrick #include "llvm/Support/X86TargetParser.h"
21*7a9b00ceSrobert #include <optional>
22e5dd7070Spatrick
23e5dd7070Spatrick namespace clang {
24e5dd7070Spatrick namespace targets {
25e5dd7070Spatrick
26*7a9b00ceSrobert static constexpr Builtin::Info BuiltinInfoX86[] = {
27e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS) \
28*7a9b00ceSrobert {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
29e5dd7070Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
30*7a9b00ceSrobert {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
31e5dd7070Spatrick #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
32*7a9b00ceSrobert {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
33e5dd7070Spatrick #include "clang/Basic/BuiltinsX86.def"
34e5dd7070Spatrick
35e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS) \
36*7a9b00ceSrobert {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
37e5dd7070Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
38*7a9b00ceSrobert {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
39e5dd7070Spatrick #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
40*7a9b00ceSrobert {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
41e5dd7070Spatrick #include "clang/Basic/BuiltinsX86_64.def"
42e5dd7070Spatrick };
43e5dd7070Spatrick
44e5dd7070Spatrick static const char *const GCCRegNames[] = {
45e5dd7070Spatrick "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
46e5dd7070Spatrick "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
47e5dd7070Spatrick "argp", "flags", "fpcr", "fpsr", "dirflag", "frame", "xmm0", "xmm1",
48e5dd7070Spatrick "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "mm0", "mm1",
49e5dd7070Spatrick "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "r8", "r9",
50e5dd7070Spatrick "r10", "r11", "r12", "r13", "r14", "r15", "xmm8", "xmm9",
51e5dd7070Spatrick "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", "ymm0", "ymm1",
52e5dd7070Spatrick "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9",
53e5dd7070Spatrick "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", "xmm16", "xmm17",
54e5dd7070Spatrick "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", "xmm24", "xmm25",
55e5dd7070Spatrick "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31", "ymm16", "ymm17",
56e5dd7070Spatrick "ymm18", "ymm19", "ymm20", "ymm21", "ymm22", "ymm23", "ymm24", "ymm25",
57e5dd7070Spatrick "ymm26", "ymm27", "ymm28", "ymm29", "ymm30", "ymm31", "zmm0", "zmm1",
58e5dd7070Spatrick "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9",
59e5dd7070Spatrick "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17",
60e5dd7070Spatrick "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25",
61e5dd7070Spatrick "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", "k0", "k1",
62e5dd7070Spatrick "k2", "k3", "k4", "k5", "k6", "k7",
63e5dd7070Spatrick "cr0", "cr2", "cr3", "cr4", "cr8",
64e5dd7070Spatrick "dr0", "dr1", "dr2", "dr3", "dr6", "dr7",
65e5dd7070Spatrick "bnd0", "bnd1", "bnd2", "bnd3",
66ec727ea7Spatrick "tmm0", "tmm1", "tmm2", "tmm3", "tmm4", "tmm5", "tmm6", "tmm7",
67e5dd7070Spatrick };
68e5dd7070Spatrick
69e5dd7070Spatrick const TargetInfo::AddlRegName AddlRegNames[] = {
70e5dd7070Spatrick {{"al", "ah", "eax", "rax"}, 0},
71e5dd7070Spatrick {{"bl", "bh", "ebx", "rbx"}, 3},
72e5dd7070Spatrick {{"cl", "ch", "ecx", "rcx"}, 2},
73e5dd7070Spatrick {{"dl", "dh", "edx", "rdx"}, 1},
74e5dd7070Spatrick {{"esi", "rsi"}, 4},
75e5dd7070Spatrick {{"edi", "rdi"}, 5},
76e5dd7070Spatrick {{"esp", "rsp"}, 7},
77e5dd7070Spatrick {{"ebp", "rbp"}, 6},
78e5dd7070Spatrick {{"r8d", "r8w", "r8b"}, 38},
79e5dd7070Spatrick {{"r9d", "r9w", "r9b"}, 39},
80e5dd7070Spatrick {{"r10d", "r10w", "r10b"}, 40},
81e5dd7070Spatrick {{"r11d", "r11w", "r11b"}, 41},
82e5dd7070Spatrick {{"r12d", "r12w", "r12b"}, 42},
83e5dd7070Spatrick {{"r13d", "r13w", "r13b"}, 43},
84e5dd7070Spatrick {{"r14d", "r14w", "r14b"}, 44},
85e5dd7070Spatrick {{"r15d", "r15w", "r15b"}, 45},
86e5dd7070Spatrick };
87e5dd7070Spatrick
88e5dd7070Spatrick } // namespace targets
89e5dd7070Spatrick } // namespace clang
90e5dd7070Spatrick
91e5dd7070Spatrick using namespace clang;
92e5dd7070Spatrick using namespace clang::targets;
93e5dd7070Spatrick
setFPMath(StringRef Name)94e5dd7070Spatrick bool X86TargetInfo::setFPMath(StringRef Name) {
95e5dd7070Spatrick if (Name == "387") {
96e5dd7070Spatrick FPMath = FP_387;
97e5dd7070Spatrick return true;
98e5dd7070Spatrick }
99e5dd7070Spatrick if (Name == "sse") {
100e5dd7070Spatrick FPMath = FP_SSE;
101e5dd7070Spatrick return true;
102e5dd7070Spatrick }
103e5dd7070Spatrick return false;
104e5dd7070Spatrick }
105e5dd7070Spatrick
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const106e5dd7070Spatrick bool X86TargetInfo::initFeatureMap(
107e5dd7070Spatrick llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
108e5dd7070Spatrick const std::vector<std::string> &FeaturesVec) const {
109e5dd7070Spatrick // FIXME: This *really* should not be here.
110e5dd7070Spatrick // X86_64 always has SSE2.
111e5dd7070Spatrick if (getTriple().getArch() == llvm::Triple::x86_64)
112ec727ea7Spatrick setFeatureEnabled(Features, "sse2", true);
113e5dd7070Spatrick
114ec727ea7Spatrick using namespace llvm::X86;
115e5dd7070Spatrick
116ec727ea7Spatrick SmallVector<StringRef, 16> CPUFeatures;
117ec727ea7Spatrick getFeaturesForCPU(CPU, CPUFeatures);
118ec727ea7Spatrick for (auto &F : CPUFeatures)
119ec727ea7Spatrick setFeatureEnabled(Features, F, true);
120e5dd7070Spatrick
121a0747c9fSpatrick std::vector<std::string> UpdatedFeaturesVec;
122a0747c9fSpatrick for (const auto &Feature : FeaturesVec) {
123a0747c9fSpatrick // Expand general-regs-only to -x86, -mmx and -sse
124a0747c9fSpatrick if (Feature == "+general-regs-only") {
125a0747c9fSpatrick UpdatedFeaturesVec.push_back("-x87");
126a0747c9fSpatrick UpdatedFeaturesVec.push_back("-mmx");
127a0747c9fSpatrick UpdatedFeaturesVec.push_back("-sse");
128a0747c9fSpatrick continue;
129a0747c9fSpatrick }
130a0747c9fSpatrick
131a0747c9fSpatrick UpdatedFeaturesVec.push_back(Feature);
132a0747c9fSpatrick }
133a0747c9fSpatrick
134a0747c9fSpatrick if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec))
135e5dd7070Spatrick return false;
136e5dd7070Spatrick
137e5dd7070Spatrick // Can't do this earlier because we need to be able to explicitly enable
138e5dd7070Spatrick // or disable these features and the things that they depend upon.
139e5dd7070Spatrick
140e5dd7070Spatrick // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
141e5dd7070Spatrick auto I = Features.find("sse4.2");
142e5dd7070Spatrick if (I != Features.end() && I->getValue() &&
143*7a9b00ceSrobert !llvm::is_contained(UpdatedFeaturesVec, "-popcnt"))
144e5dd7070Spatrick Features["popcnt"] = true;
145e5dd7070Spatrick
146e5dd7070Spatrick // Additionally, if SSE is enabled and mmx is not explicitly disabled,
147e5dd7070Spatrick // then enable MMX.
148e5dd7070Spatrick I = Features.find("sse");
149e5dd7070Spatrick if (I != Features.end() && I->getValue() &&
150*7a9b00ceSrobert !llvm::is_contained(UpdatedFeaturesVec, "-mmx"))
151e5dd7070Spatrick Features["mmx"] = true;
152e5dd7070Spatrick
153ec727ea7Spatrick // Enable xsave if avx is enabled and xsave is not explicitly disabled.
154ec727ea7Spatrick I = Features.find("avx");
155ec727ea7Spatrick if (I != Features.end() && I->getValue() &&
156*7a9b00ceSrobert !llvm::is_contained(UpdatedFeaturesVec, "-xsave"))
157ec727ea7Spatrick Features["xsave"] = true;
158ec727ea7Spatrick
159*7a9b00ceSrobert // Enable CRC32 if SSE4.2 is enabled and CRC32 is not explicitly disabled.
160*7a9b00ceSrobert I = Features.find("sse4.2");
161*7a9b00ceSrobert if (I != Features.end() && I->getValue() &&
162*7a9b00ceSrobert !llvm::is_contained(UpdatedFeaturesVec, "-crc32"))
163*7a9b00ceSrobert Features["crc32"] = true;
164*7a9b00ceSrobert
165e5dd7070Spatrick return true;
166e5dd7070Spatrick }
167e5dd7070Spatrick
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const168ec727ea7Spatrick void X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
169ec727ea7Spatrick StringRef Name, bool Enabled) const {
170ec727ea7Spatrick if (Name == "sse4") {
171e5dd7070Spatrick // We can get here via the __target__ attribute since that's not controlled
172e5dd7070Spatrick // via the -msse4/-mno-sse4 command line alias. Handle this the same way
173e5dd7070Spatrick // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if
174e5dd7070Spatrick // disabled.
175e5dd7070Spatrick if (Enabled)
176ec727ea7Spatrick Name = "sse4.2";
177e5dd7070Spatrick else
178ec727ea7Spatrick Name = "sse4.1";
179e5dd7070Spatrick }
180ec727ea7Spatrick
181ec727ea7Spatrick Features[Name] = Enabled;
182a0747c9fSpatrick llvm::X86::updateImpliedFeatures(Name, Enabled, Features);
183e5dd7070Spatrick }
184e5dd7070Spatrick
185e5dd7070Spatrick /// handleTargetFeatures - Perform initialization based on the user
186e5dd7070Spatrick /// configured set of features.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)187e5dd7070Spatrick bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
188e5dd7070Spatrick DiagnosticsEngine &Diags) {
189e5dd7070Spatrick for (const auto &Feature : Features) {
190e5dd7070Spatrick if (Feature[0] != '+')
191e5dd7070Spatrick continue;
192e5dd7070Spatrick
193e5dd7070Spatrick if (Feature == "+aes") {
194e5dd7070Spatrick HasAES = true;
195e5dd7070Spatrick } else if (Feature == "+vaes") {
196e5dd7070Spatrick HasVAES = true;
197e5dd7070Spatrick } else if (Feature == "+pclmul") {
198e5dd7070Spatrick HasPCLMUL = true;
199e5dd7070Spatrick } else if (Feature == "+vpclmulqdq") {
200e5dd7070Spatrick HasVPCLMULQDQ = true;
201e5dd7070Spatrick } else if (Feature == "+lzcnt") {
202e5dd7070Spatrick HasLZCNT = true;
203e5dd7070Spatrick } else if (Feature == "+rdrnd") {
204e5dd7070Spatrick HasRDRND = true;
205e5dd7070Spatrick } else if (Feature == "+fsgsbase") {
206e5dd7070Spatrick HasFSGSBASE = true;
207e5dd7070Spatrick } else if (Feature == "+bmi") {
208e5dd7070Spatrick HasBMI = true;
209e5dd7070Spatrick } else if (Feature == "+bmi2") {
210e5dd7070Spatrick HasBMI2 = true;
211e5dd7070Spatrick } else if (Feature == "+popcnt") {
212e5dd7070Spatrick HasPOPCNT = true;
213e5dd7070Spatrick } else if (Feature == "+rtm") {
214e5dd7070Spatrick HasRTM = true;
215e5dd7070Spatrick } else if (Feature == "+prfchw") {
216e5dd7070Spatrick HasPRFCHW = true;
217e5dd7070Spatrick } else if (Feature == "+rdseed") {
218e5dd7070Spatrick HasRDSEED = true;
219e5dd7070Spatrick } else if (Feature == "+adx") {
220e5dd7070Spatrick HasADX = true;
221e5dd7070Spatrick } else if (Feature == "+tbm") {
222e5dd7070Spatrick HasTBM = true;
223e5dd7070Spatrick } else if (Feature == "+lwp") {
224e5dd7070Spatrick HasLWP = true;
225e5dd7070Spatrick } else if (Feature == "+fma") {
226e5dd7070Spatrick HasFMA = true;
227e5dd7070Spatrick } else if (Feature == "+f16c") {
228e5dd7070Spatrick HasF16C = true;
229e5dd7070Spatrick } else if (Feature == "+gfni") {
230e5dd7070Spatrick HasGFNI = true;
231e5dd7070Spatrick } else if (Feature == "+avx512cd") {
232e5dd7070Spatrick HasAVX512CD = true;
233e5dd7070Spatrick } else if (Feature == "+avx512vpopcntdq") {
234e5dd7070Spatrick HasAVX512VPOPCNTDQ = true;
235e5dd7070Spatrick } else if (Feature == "+avx512vnni") {
236e5dd7070Spatrick HasAVX512VNNI = true;
237e5dd7070Spatrick } else if (Feature == "+avx512bf16") {
238e5dd7070Spatrick HasAVX512BF16 = true;
239e5dd7070Spatrick } else if (Feature == "+avx512er") {
240e5dd7070Spatrick HasAVX512ER = true;
241*7a9b00ceSrobert } else if (Feature == "+avx512fp16") {
242*7a9b00ceSrobert HasAVX512FP16 = true;
243*7a9b00ceSrobert HasLegalHalfType = true;
244e5dd7070Spatrick } else if (Feature == "+avx512pf") {
245e5dd7070Spatrick HasAVX512PF = true;
246e5dd7070Spatrick } else if (Feature == "+avx512dq") {
247e5dd7070Spatrick HasAVX512DQ = true;
248e5dd7070Spatrick } else if (Feature == "+avx512bitalg") {
249e5dd7070Spatrick HasAVX512BITALG = true;
250e5dd7070Spatrick } else if (Feature == "+avx512bw") {
251e5dd7070Spatrick HasAVX512BW = true;
252e5dd7070Spatrick } else if (Feature == "+avx512vl") {
253e5dd7070Spatrick HasAVX512VL = true;
254e5dd7070Spatrick } else if (Feature == "+avx512vbmi") {
255e5dd7070Spatrick HasAVX512VBMI = true;
256e5dd7070Spatrick } else if (Feature == "+avx512vbmi2") {
257e5dd7070Spatrick HasAVX512VBMI2 = true;
258e5dd7070Spatrick } else if (Feature == "+avx512ifma") {
259e5dd7070Spatrick HasAVX512IFMA = true;
260e5dd7070Spatrick } else if (Feature == "+avx512vp2intersect") {
261e5dd7070Spatrick HasAVX512VP2INTERSECT = true;
262e5dd7070Spatrick } else if (Feature == "+sha") {
263e5dd7070Spatrick HasSHA = true;
264e5dd7070Spatrick } else if (Feature == "+shstk") {
265e5dd7070Spatrick HasSHSTK = true;
266e5dd7070Spatrick } else if (Feature == "+movbe") {
267e5dd7070Spatrick HasMOVBE = true;
268e5dd7070Spatrick } else if (Feature == "+sgx") {
269e5dd7070Spatrick HasSGX = true;
270e5dd7070Spatrick } else if (Feature == "+cx8") {
271e5dd7070Spatrick HasCX8 = true;
272e5dd7070Spatrick } else if (Feature == "+cx16") {
273e5dd7070Spatrick HasCX16 = true;
274e5dd7070Spatrick } else if (Feature == "+fxsr") {
275e5dd7070Spatrick HasFXSR = true;
276e5dd7070Spatrick } else if (Feature == "+xsave") {
277e5dd7070Spatrick HasXSAVE = true;
278e5dd7070Spatrick } else if (Feature == "+xsaveopt") {
279e5dd7070Spatrick HasXSAVEOPT = true;
280e5dd7070Spatrick } else if (Feature == "+xsavec") {
281e5dd7070Spatrick HasXSAVEC = true;
282e5dd7070Spatrick } else if (Feature == "+xsaves") {
283e5dd7070Spatrick HasXSAVES = true;
284e5dd7070Spatrick } else if (Feature == "+mwaitx") {
285e5dd7070Spatrick HasMWAITX = true;
286e5dd7070Spatrick } else if (Feature == "+pku") {
287e5dd7070Spatrick HasPKU = true;
288e5dd7070Spatrick } else if (Feature == "+clflushopt") {
289e5dd7070Spatrick HasCLFLUSHOPT = true;
290e5dd7070Spatrick } else if (Feature == "+clwb") {
291e5dd7070Spatrick HasCLWB = true;
292e5dd7070Spatrick } else if (Feature == "+wbnoinvd") {
293e5dd7070Spatrick HasWBNOINVD = true;
294*7a9b00ceSrobert } else if (Feature == "+prefetchi") {
295*7a9b00ceSrobert HasPREFETCHI = true;
296e5dd7070Spatrick } else if (Feature == "+prefetchwt1") {
297e5dd7070Spatrick HasPREFETCHWT1 = true;
298e5dd7070Spatrick } else if (Feature == "+clzero") {
299e5dd7070Spatrick HasCLZERO = true;
300e5dd7070Spatrick } else if (Feature == "+cldemote") {
301e5dd7070Spatrick HasCLDEMOTE = true;
302e5dd7070Spatrick } else if (Feature == "+rdpid") {
303e5dd7070Spatrick HasRDPID = true;
304*7a9b00ceSrobert } else if (Feature == "+rdpru") {
305*7a9b00ceSrobert HasRDPRU = true;
306a0747c9fSpatrick } else if (Feature == "+kl") {
307a0747c9fSpatrick HasKL = true;
308a0747c9fSpatrick } else if (Feature == "+widekl") {
309a0747c9fSpatrick HasWIDEKL = true;
310e5dd7070Spatrick } else if (Feature == "+retpoline-external-thunk") {
311e5dd7070Spatrick HasRetpolineExternalThunk = true;
312e5dd7070Spatrick } else if (Feature == "+sahf") {
313e5dd7070Spatrick HasLAHFSAHF = true;
314e5dd7070Spatrick } else if (Feature == "+waitpkg") {
315e5dd7070Spatrick HasWAITPKG = true;
316e5dd7070Spatrick } else if (Feature == "+movdiri") {
317e5dd7070Spatrick HasMOVDIRI = true;
318e5dd7070Spatrick } else if (Feature == "+movdir64b") {
319e5dd7070Spatrick HasMOVDIR64B = true;
320e5dd7070Spatrick } else if (Feature == "+pconfig") {
321e5dd7070Spatrick HasPCONFIG = true;
322e5dd7070Spatrick } else if (Feature == "+ptwrite") {
323e5dd7070Spatrick HasPTWRITE = true;
324e5dd7070Spatrick } else if (Feature == "+invpcid") {
325e5dd7070Spatrick HasINVPCID = true;
326adae0cfdSpatrick } else if (Feature == "+save-args") {
327adae0cfdSpatrick HasSaveArgs = true;
328e5dd7070Spatrick } else if (Feature == "+enqcmd") {
329e5dd7070Spatrick HasENQCMD = true;
330a0747c9fSpatrick } else if (Feature == "+hreset") {
331a0747c9fSpatrick HasHRESET = true;
332ec727ea7Spatrick } else if (Feature == "+amx-bf16") {
333ec727ea7Spatrick HasAMXBF16 = true;
334*7a9b00ceSrobert } else if (Feature == "+amx-fp16") {
335*7a9b00ceSrobert HasAMXFP16 = true;
336ec727ea7Spatrick } else if (Feature == "+amx-int8") {
337ec727ea7Spatrick HasAMXINT8 = true;
338ec727ea7Spatrick } else if (Feature == "+amx-tile") {
339ec727ea7Spatrick HasAMXTILE = true;
340*7a9b00ceSrobert } else if (Feature == "+cmpccxadd") {
341*7a9b00ceSrobert HasCMPCCXADD = true;
342*7a9b00ceSrobert } else if (Feature == "+raoint") {
343*7a9b00ceSrobert HasRAOINT = true;
344*7a9b00ceSrobert } else if (Feature == "+avxifma") {
345*7a9b00ceSrobert HasAVXIFMA = true;
346*7a9b00ceSrobert } else if (Feature == "+avxneconvert") {
347*7a9b00ceSrobert HasAVXNECONVERT= true;
348a0747c9fSpatrick } else if (Feature == "+avxvnni") {
349a0747c9fSpatrick HasAVXVNNI = true;
350*7a9b00ceSrobert } else if (Feature == "+avxvnniint8") {
351*7a9b00ceSrobert HasAVXVNNIINT8 = true;
352ec727ea7Spatrick } else if (Feature == "+serialize") {
353ec727ea7Spatrick HasSERIALIZE = true;
354ec727ea7Spatrick } else if (Feature == "+tsxldtrk") {
355ec727ea7Spatrick HasTSXLDTRK = true;
356a0747c9fSpatrick } else if (Feature == "+uintr") {
357a0747c9fSpatrick HasUINTR = true;
358*7a9b00ceSrobert } else if (Feature == "+crc32") {
359*7a9b00ceSrobert HasCRC32 = true;
360*7a9b00ceSrobert } else if (Feature == "+x87") {
361*7a9b00ceSrobert HasX87 = true;
362e5dd7070Spatrick }
363e5dd7070Spatrick
364e5dd7070Spatrick X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
365e5dd7070Spatrick .Case("+avx512f", AVX512F)
366e5dd7070Spatrick .Case("+avx2", AVX2)
367e5dd7070Spatrick .Case("+avx", AVX)
368e5dd7070Spatrick .Case("+sse4.2", SSE42)
369e5dd7070Spatrick .Case("+sse4.1", SSE41)
370e5dd7070Spatrick .Case("+ssse3", SSSE3)
371e5dd7070Spatrick .Case("+sse3", SSE3)
372e5dd7070Spatrick .Case("+sse2", SSE2)
373e5dd7070Spatrick .Case("+sse", SSE1)
374e5dd7070Spatrick .Default(NoSSE);
375e5dd7070Spatrick SSELevel = std::max(SSELevel, Level);
376e5dd7070Spatrick
377*7a9b00ceSrobert HasFloat16 = SSELevel >= SSE2;
378*7a9b00ceSrobert
379*7a9b00ceSrobert HasBFloat16 = SSELevel >= SSE2;
380*7a9b00ceSrobert
381e5dd7070Spatrick MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature)
382e5dd7070Spatrick .Case("+3dnowa", AMD3DNowAthlon)
383e5dd7070Spatrick .Case("+3dnow", AMD3DNow)
384e5dd7070Spatrick .Case("+mmx", MMX)
385e5dd7070Spatrick .Default(NoMMX3DNow);
386e5dd7070Spatrick MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
387e5dd7070Spatrick
388e5dd7070Spatrick XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
389e5dd7070Spatrick .Case("+xop", XOP)
390e5dd7070Spatrick .Case("+fma4", FMA4)
391e5dd7070Spatrick .Case("+sse4a", SSE4A)
392e5dd7070Spatrick .Default(NoXOP);
393e5dd7070Spatrick XOPLevel = std::max(XOPLevel, XLevel);
394e5dd7070Spatrick }
395e5dd7070Spatrick
396e5dd7070Spatrick // LLVM doesn't have a separate switch for fpmath, so only accept it if it
397e5dd7070Spatrick // matches the selected sse level.
398e5dd7070Spatrick if ((FPMath == FP_SSE && SSELevel < SSE1) ||
399e5dd7070Spatrick (FPMath == FP_387 && SSELevel >= SSE1)) {
400e5dd7070Spatrick Diags.Report(diag::err_target_unsupported_fpmath)
401e5dd7070Spatrick << (FPMath == FP_SSE ? "sse" : "387");
402e5dd7070Spatrick return false;
403e5dd7070Spatrick }
404e5dd7070Spatrick
405e5dd7070Spatrick SimdDefaultAlign =
406e5dd7070Spatrick hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
407*7a9b00ceSrobert
408*7a9b00ceSrobert // FIXME: We should allow long double type on 32-bits to match with GCC.
409*7a9b00ceSrobert // This requires backend to be able to lower f80 without x87 first.
410*7a9b00ceSrobert if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended())
411*7a9b00ceSrobert HasLongDouble = false;
412*7a9b00ceSrobert
413e5dd7070Spatrick return true;
414e5dd7070Spatrick }
415e5dd7070Spatrick
416e5dd7070Spatrick /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
417e5dd7070Spatrick /// definitions for this particular subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const418e5dd7070Spatrick void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
419e5dd7070Spatrick MacroBuilder &Builder) const {
420e5dd7070Spatrick // Inline assembly supports X86 flag outputs.
421e5dd7070Spatrick Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
422e5dd7070Spatrick
423e5dd7070Spatrick std::string CodeModel = getTargetOpts().CodeModel;
424e5dd7070Spatrick if (CodeModel == "default")
425e5dd7070Spatrick CodeModel = "small";
426ec727ea7Spatrick Builder.defineMacro("__code_model_" + CodeModel + "__");
427e5dd7070Spatrick
428e5dd7070Spatrick // Target identification.
429e5dd7070Spatrick if (getTriple().getArch() == llvm::Triple::x86_64) {
430e5dd7070Spatrick Builder.defineMacro("__amd64__");
431e5dd7070Spatrick Builder.defineMacro("__amd64");
432e5dd7070Spatrick Builder.defineMacro("__x86_64");
433e5dd7070Spatrick Builder.defineMacro("__x86_64__");
434e5dd7070Spatrick if (getTriple().getArchName() == "x86_64h") {
435e5dd7070Spatrick Builder.defineMacro("__x86_64h");
436e5dd7070Spatrick Builder.defineMacro("__x86_64h__");
437e5dd7070Spatrick }
438e5dd7070Spatrick } else {
439e5dd7070Spatrick DefineStd(Builder, "i386", Opts);
440e5dd7070Spatrick }
441e5dd7070Spatrick
442e5dd7070Spatrick Builder.defineMacro("__SEG_GS");
443e5dd7070Spatrick Builder.defineMacro("__SEG_FS");
444e5dd7070Spatrick Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))");
445e5dd7070Spatrick Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))");
446e5dd7070Spatrick
447e5dd7070Spatrick // Subtarget options.
448e5dd7070Spatrick // FIXME: We are hard-coding the tune parameters based on the CPU, but they
449e5dd7070Spatrick // truly should be based on -mtune options.
450ec727ea7Spatrick using namespace llvm::X86;
451e5dd7070Spatrick switch (CPU) {
452ec727ea7Spatrick case CK_None:
453e5dd7070Spatrick break;
454e5dd7070Spatrick case CK_i386:
455e5dd7070Spatrick // The rest are coming from the i386 define above.
456e5dd7070Spatrick Builder.defineMacro("__tune_i386__");
457e5dd7070Spatrick break;
458e5dd7070Spatrick case CK_i486:
459e5dd7070Spatrick case CK_WinChipC6:
460e5dd7070Spatrick case CK_WinChip2:
461e5dd7070Spatrick case CK_C3:
462e5dd7070Spatrick defineCPUMacros(Builder, "i486");
463e5dd7070Spatrick break;
464e5dd7070Spatrick case CK_PentiumMMX:
465e5dd7070Spatrick Builder.defineMacro("__pentium_mmx__");
466e5dd7070Spatrick Builder.defineMacro("__tune_pentium_mmx__");
467*7a9b00ceSrobert [[fallthrough]];
468e5dd7070Spatrick case CK_i586:
469e5dd7070Spatrick case CK_Pentium:
470e5dd7070Spatrick defineCPUMacros(Builder, "i586");
471e5dd7070Spatrick defineCPUMacros(Builder, "pentium");
472e5dd7070Spatrick break;
473e5dd7070Spatrick case CK_Pentium3:
474e5dd7070Spatrick case CK_PentiumM:
475e5dd7070Spatrick Builder.defineMacro("__tune_pentium3__");
476*7a9b00ceSrobert [[fallthrough]];
477e5dd7070Spatrick case CK_Pentium2:
478e5dd7070Spatrick case CK_C3_2:
479e5dd7070Spatrick Builder.defineMacro("__tune_pentium2__");
480*7a9b00ceSrobert [[fallthrough]];
481e5dd7070Spatrick case CK_PentiumPro:
482e5dd7070Spatrick case CK_i686:
483e5dd7070Spatrick defineCPUMacros(Builder, "i686");
484e5dd7070Spatrick defineCPUMacros(Builder, "pentiumpro");
485e5dd7070Spatrick break;
486e5dd7070Spatrick case CK_Pentium4:
487e5dd7070Spatrick defineCPUMacros(Builder, "pentium4");
488e5dd7070Spatrick break;
489e5dd7070Spatrick case CK_Yonah:
490e5dd7070Spatrick case CK_Prescott:
491e5dd7070Spatrick case CK_Nocona:
492e5dd7070Spatrick defineCPUMacros(Builder, "nocona");
493e5dd7070Spatrick break;
494e5dd7070Spatrick case CK_Core2:
495e5dd7070Spatrick case CK_Penryn:
496e5dd7070Spatrick defineCPUMacros(Builder, "core2");
497e5dd7070Spatrick break;
498e5dd7070Spatrick case CK_Bonnell:
499e5dd7070Spatrick defineCPUMacros(Builder, "atom");
500e5dd7070Spatrick break;
501e5dd7070Spatrick case CK_Silvermont:
502e5dd7070Spatrick defineCPUMacros(Builder, "slm");
503e5dd7070Spatrick break;
504e5dd7070Spatrick case CK_Goldmont:
505e5dd7070Spatrick defineCPUMacros(Builder, "goldmont");
506e5dd7070Spatrick break;
507e5dd7070Spatrick case CK_GoldmontPlus:
508e5dd7070Spatrick defineCPUMacros(Builder, "goldmont_plus");
509e5dd7070Spatrick break;
510e5dd7070Spatrick case CK_Tremont:
511e5dd7070Spatrick defineCPUMacros(Builder, "tremont");
512e5dd7070Spatrick break;
513e5dd7070Spatrick case CK_Nehalem:
514e5dd7070Spatrick case CK_Westmere:
515e5dd7070Spatrick case CK_SandyBridge:
516e5dd7070Spatrick case CK_IvyBridge:
517e5dd7070Spatrick case CK_Haswell:
518e5dd7070Spatrick case CK_Broadwell:
519e5dd7070Spatrick case CK_SkylakeClient:
520e5dd7070Spatrick case CK_SkylakeServer:
521e5dd7070Spatrick case CK_Cascadelake:
522e5dd7070Spatrick case CK_Cooperlake:
523e5dd7070Spatrick case CK_Cannonlake:
524e5dd7070Spatrick case CK_IcelakeClient:
525a0747c9fSpatrick case CK_Rocketlake:
526e5dd7070Spatrick case CK_IcelakeServer:
527e5dd7070Spatrick case CK_Tigerlake:
528a0747c9fSpatrick case CK_SapphireRapids:
529a0747c9fSpatrick case CK_Alderlake:
530*7a9b00ceSrobert case CK_Raptorlake:
531*7a9b00ceSrobert case CK_Meteorlake:
532*7a9b00ceSrobert case CK_Sierraforest:
533*7a9b00ceSrobert case CK_Grandridge:
534*7a9b00ceSrobert case CK_Graniterapids:
535*7a9b00ceSrobert case CK_Emeraldrapids:
536e5dd7070Spatrick // FIXME: Historically, we defined this legacy name, it would be nice to
537e5dd7070Spatrick // remove it at some point. We've never exposed fine-grained names for
538e5dd7070Spatrick // recent primary x86 CPUs, and we should keep it that way.
539e5dd7070Spatrick defineCPUMacros(Builder, "corei7");
540e5dd7070Spatrick break;
541e5dd7070Spatrick case CK_KNL:
542e5dd7070Spatrick defineCPUMacros(Builder, "knl");
543e5dd7070Spatrick break;
544e5dd7070Spatrick case CK_KNM:
545e5dd7070Spatrick break;
546e5dd7070Spatrick case CK_Lakemont:
547e5dd7070Spatrick defineCPUMacros(Builder, "i586", /*Tuning*/false);
548e5dd7070Spatrick defineCPUMacros(Builder, "pentium", /*Tuning*/false);
549e5dd7070Spatrick Builder.defineMacro("__tune_lakemont__");
550e5dd7070Spatrick break;
551e5dd7070Spatrick case CK_K6_2:
552e5dd7070Spatrick Builder.defineMacro("__k6_2__");
553e5dd7070Spatrick Builder.defineMacro("__tune_k6_2__");
554*7a9b00ceSrobert [[fallthrough]];
555e5dd7070Spatrick case CK_K6_3:
556e5dd7070Spatrick if (CPU != CK_K6_2) { // In case of fallthrough
557e5dd7070Spatrick // FIXME: GCC may be enabling these in cases where some other k6
558e5dd7070Spatrick // architecture is specified but -m3dnow is explicitly provided. The
559e5dd7070Spatrick // exact semantics need to be determined and emulated here.
560e5dd7070Spatrick Builder.defineMacro("__k6_3__");
561e5dd7070Spatrick Builder.defineMacro("__tune_k6_3__");
562e5dd7070Spatrick }
563*7a9b00ceSrobert [[fallthrough]];
564e5dd7070Spatrick case CK_K6:
565e5dd7070Spatrick defineCPUMacros(Builder, "k6");
566e5dd7070Spatrick break;
567e5dd7070Spatrick case CK_Athlon:
568e5dd7070Spatrick case CK_AthlonXP:
569e5dd7070Spatrick defineCPUMacros(Builder, "athlon");
570e5dd7070Spatrick if (SSELevel != NoSSE) {
571e5dd7070Spatrick Builder.defineMacro("__athlon_sse__");
572e5dd7070Spatrick Builder.defineMacro("__tune_athlon_sse__");
573e5dd7070Spatrick }
574e5dd7070Spatrick break;
575e5dd7070Spatrick case CK_K8:
576e5dd7070Spatrick case CK_K8SSE3:
577e5dd7070Spatrick case CK_x86_64:
578e5dd7070Spatrick defineCPUMacros(Builder, "k8");
579e5dd7070Spatrick break;
580a0747c9fSpatrick case CK_x86_64_v2:
581a0747c9fSpatrick case CK_x86_64_v3:
582a0747c9fSpatrick case CK_x86_64_v4:
583a0747c9fSpatrick break;
584e5dd7070Spatrick case CK_AMDFAM10:
585e5dd7070Spatrick defineCPUMacros(Builder, "amdfam10");
586e5dd7070Spatrick break;
587e5dd7070Spatrick case CK_BTVER1:
588e5dd7070Spatrick defineCPUMacros(Builder, "btver1");
589e5dd7070Spatrick break;
590e5dd7070Spatrick case CK_BTVER2:
591e5dd7070Spatrick defineCPUMacros(Builder, "btver2");
592e5dd7070Spatrick break;
593e5dd7070Spatrick case CK_BDVER1:
594e5dd7070Spatrick defineCPUMacros(Builder, "bdver1");
595e5dd7070Spatrick break;
596e5dd7070Spatrick case CK_BDVER2:
597e5dd7070Spatrick defineCPUMacros(Builder, "bdver2");
598e5dd7070Spatrick break;
599e5dd7070Spatrick case CK_BDVER3:
600e5dd7070Spatrick defineCPUMacros(Builder, "bdver3");
601e5dd7070Spatrick break;
602e5dd7070Spatrick case CK_BDVER4:
603e5dd7070Spatrick defineCPUMacros(Builder, "bdver4");
604e5dd7070Spatrick break;
605e5dd7070Spatrick case CK_ZNVER1:
606e5dd7070Spatrick defineCPUMacros(Builder, "znver1");
607e5dd7070Spatrick break;
608e5dd7070Spatrick case CK_ZNVER2:
609e5dd7070Spatrick defineCPUMacros(Builder, "znver2");
610e5dd7070Spatrick break;
611a0747c9fSpatrick case CK_ZNVER3:
612a0747c9fSpatrick defineCPUMacros(Builder, "znver3");
613a0747c9fSpatrick break;
614*7a9b00ceSrobert case CK_ZNVER4:
615*7a9b00ceSrobert defineCPUMacros(Builder, "znver4");
616*7a9b00ceSrobert break;
617e5dd7070Spatrick case CK_Geode:
618e5dd7070Spatrick defineCPUMacros(Builder, "geode");
619e5dd7070Spatrick break;
620e5dd7070Spatrick }
621e5dd7070Spatrick
622e5dd7070Spatrick // Target properties.
623e5dd7070Spatrick Builder.defineMacro("__REGISTER_PREFIX__", "");
624e5dd7070Spatrick
625e5dd7070Spatrick // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
626e5dd7070Spatrick // functions in glibc header files that use FP Stack inline asm which the
627e5dd7070Spatrick // backend can't deal with (PR879).
628e5dd7070Spatrick Builder.defineMacro("__NO_MATH_INLINES");
629e5dd7070Spatrick
630e5dd7070Spatrick if (HasAES)
631e5dd7070Spatrick Builder.defineMacro("__AES__");
632e5dd7070Spatrick
633e5dd7070Spatrick if (HasVAES)
634e5dd7070Spatrick Builder.defineMacro("__VAES__");
635e5dd7070Spatrick
636e5dd7070Spatrick if (HasPCLMUL)
637e5dd7070Spatrick Builder.defineMacro("__PCLMUL__");
638e5dd7070Spatrick
639e5dd7070Spatrick if (HasVPCLMULQDQ)
640e5dd7070Spatrick Builder.defineMacro("__VPCLMULQDQ__");
641e5dd7070Spatrick
642a0747c9fSpatrick // Note, in 32-bit mode, GCC does not define the macro if -mno-sahf. In LLVM,
643a0747c9fSpatrick // the feature flag only applies to 64-bit mode.
644a0747c9fSpatrick if (HasLAHFSAHF || getTriple().getArch() == llvm::Triple::x86)
645a0747c9fSpatrick Builder.defineMacro("__LAHF_SAHF__");
646a0747c9fSpatrick
647e5dd7070Spatrick if (HasLZCNT)
648e5dd7070Spatrick Builder.defineMacro("__LZCNT__");
649e5dd7070Spatrick
650e5dd7070Spatrick if (HasRDRND)
651e5dd7070Spatrick Builder.defineMacro("__RDRND__");
652e5dd7070Spatrick
653e5dd7070Spatrick if (HasFSGSBASE)
654e5dd7070Spatrick Builder.defineMacro("__FSGSBASE__");
655e5dd7070Spatrick
656e5dd7070Spatrick if (HasBMI)
657e5dd7070Spatrick Builder.defineMacro("__BMI__");
658e5dd7070Spatrick
659e5dd7070Spatrick if (HasBMI2)
660e5dd7070Spatrick Builder.defineMacro("__BMI2__");
661e5dd7070Spatrick
662e5dd7070Spatrick if (HasPOPCNT)
663e5dd7070Spatrick Builder.defineMacro("__POPCNT__");
664e5dd7070Spatrick
665e5dd7070Spatrick if (HasRTM)
666e5dd7070Spatrick Builder.defineMacro("__RTM__");
667e5dd7070Spatrick
668e5dd7070Spatrick if (HasPRFCHW)
669e5dd7070Spatrick Builder.defineMacro("__PRFCHW__");
670e5dd7070Spatrick
671e5dd7070Spatrick if (HasRDSEED)
672e5dd7070Spatrick Builder.defineMacro("__RDSEED__");
673e5dd7070Spatrick
674e5dd7070Spatrick if (HasADX)
675e5dd7070Spatrick Builder.defineMacro("__ADX__");
676e5dd7070Spatrick
677e5dd7070Spatrick if (HasTBM)
678e5dd7070Spatrick Builder.defineMacro("__TBM__");
679e5dd7070Spatrick
680e5dd7070Spatrick if (HasLWP)
681e5dd7070Spatrick Builder.defineMacro("__LWP__");
682e5dd7070Spatrick
683e5dd7070Spatrick if (HasMWAITX)
684e5dd7070Spatrick Builder.defineMacro("__MWAITX__");
685e5dd7070Spatrick
686e5dd7070Spatrick if (HasMOVBE)
687e5dd7070Spatrick Builder.defineMacro("__MOVBE__");
688e5dd7070Spatrick
689e5dd7070Spatrick switch (XOPLevel) {
690e5dd7070Spatrick case XOP:
691e5dd7070Spatrick Builder.defineMacro("__XOP__");
692*7a9b00ceSrobert [[fallthrough]];
693e5dd7070Spatrick case FMA4:
694e5dd7070Spatrick Builder.defineMacro("__FMA4__");
695*7a9b00ceSrobert [[fallthrough]];
696e5dd7070Spatrick case SSE4A:
697e5dd7070Spatrick Builder.defineMacro("__SSE4A__");
698*7a9b00ceSrobert [[fallthrough]];
699e5dd7070Spatrick case NoXOP:
700e5dd7070Spatrick break;
701e5dd7070Spatrick }
702e5dd7070Spatrick
703e5dd7070Spatrick if (HasFMA)
704e5dd7070Spatrick Builder.defineMacro("__FMA__");
705e5dd7070Spatrick
706e5dd7070Spatrick if (HasF16C)
707e5dd7070Spatrick Builder.defineMacro("__F16C__");
708e5dd7070Spatrick
709e5dd7070Spatrick if (HasGFNI)
710e5dd7070Spatrick Builder.defineMacro("__GFNI__");
711e5dd7070Spatrick
712e5dd7070Spatrick if (HasAVX512CD)
713e5dd7070Spatrick Builder.defineMacro("__AVX512CD__");
714e5dd7070Spatrick if (HasAVX512VPOPCNTDQ)
715e5dd7070Spatrick Builder.defineMacro("__AVX512VPOPCNTDQ__");
716e5dd7070Spatrick if (HasAVX512VNNI)
717e5dd7070Spatrick Builder.defineMacro("__AVX512VNNI__");
718e5dd7070Spatrick if (HasAVX512BF16)
719e5dd7070Spatrick Builder.defineMacro("__AVX512BF16__");
720e5dd7070Spatrick if (HasAVX512ER)
721e5dd7070Spatrick Builder.defineMacro("__AVX512ER__");
722*7a9b00ceSrobert if (HasAVX512FP16)
723*7a9b00ceSrobert Builder.defineMacro("__AVX512FP16__");
724e5dd7070Spatrick if (HasAVX512PF)
725e5dd7070Spatrick Builder.defineMacro("__AVX512PF__");
726e5dd7070Spatrick if (HasAVX512DQ)
727e5dd7070Spatrick Builder.defineMacro("__AVX512DQ__");
728e5dd7070Spatrick if (HasAVX512BITALG)
729e5dd7070Spatrick Builder.defineMacro("__AVX512BITALG__");
730e5dd7070Spatrick if (HasAVX512BW)
731e5dd7070Spatrick Builder.defineMacro("__AVX512BW__");
732e5dd7070Spatrick if (HasAVX512VL)
733e5dd7070Spatrick Builder.defineMacro("__AVX512VL__");
734e5dd7070Spatrick if (HasAVX512VBMI)
735e5dd7070Spatrick Builder.defineMacro("__AVX512VBMI__");
736e5dd7070Spatrick if (HasAVX512VBMI2)
737e5dd7070Spatrick Builder.defineMacro("__AVX512VBMI2__");
738e5dd7070Spatrick if (HasAVX512IFMA)
739e5dd7070Spatrick Builder.defineMacro("__AVX512IFMA__");
740e5dd7070Spatrick if (HasAVX512VP2INTERSECT)
741e5dd7070Spatrick Builder.defineMacro("__AVX512VP2INTERSECT__");
742e5dd7070Spatrick if (HasSHA)
743e5dd7070Spatrick Builder.defineMacro("__SHA__");
744e5dd7070Spatrick
745e5dd7070Spatrick if (HasFXSR)
746e5dd7070Spatrick Builder.defineMacro("__FXSR__");
747e5dd7070Spatrick if (HasXSAVE)
748e5dd7070Spatrick Builder.defineMacro("__XSAVE__");
749e5dd7070Spatrick if (HasXSAVEOPT)
750e5dd7070Spatrick Builder.defineMacro("__XSAVEOPT__");
751e5dd7070Spatrick if (HasXSAVEC)
752e5dd7070Spatrick Builder.defineMacro("__XSAVEC__");
753e5dd7070Spatrick if (HasXSAVES)
754e5dd7070Spatrick Builder.defineMacro("__XSAVES__");
755e5dd7070Spatrick if (HasPKU)
756e5dd7070Spatrick Builder.defineMacro("__PKU__");
757e5dd7070Spatrick if (HasCLFLUSHOPT)
758e5dd7070Spatrick Builder.defineMacro("__CLFLUSHOPT__");
759e5dd7070Spatrick if (HasCLWB)
760e5dd7070Spatrick Builder.defineMacro("__CLWB__");
761e5dd7070Spatrick if (HasWBNOINVD)
762e5dd7070Spatrick Builder.defineMacro("__WBNOINVD__");
763e5dd7070Spatrick if (HasSHSTK)
764e5dd7070Spatrick Builder.defineMacro("__SHSTK__");
765e5dd7070Spatrick if (HasSGX)
766e5dd7070Spatrick Builder.defineMacro("__SGX__");
767*7a9b00ceSrobert if (HasPREFETCHI)
768*7a9b00ceSrobert Builder.defineMacro("__PREFETCHI__");
769e5dd7070Spatrick if (HasPREFETCHWT1)
770e5dd7070Spatrick Builder.defineMacro("__PREFETCHWT1__");
771e5dd7070Spatrick if (HasCLZERO)
772e5dd7070Spatrick Builder.defineMacro("__CLZERO__");
773a0747c9fSpatrick if (HasKL)
774a0747c9fSpatrick Builder.defineMacro("__KL__");
775a0747c9fSpatrick if (HasWIDEKL)
776a0747c9fSpatrick Builder.defineMacro("__WIDEKL__");
777e5dd7070Spatrick if (HasRDPID)
778e5dd7070Spatrick Builder.defineMacro("__RDPID__");
779*7a9b00ceSrobert if (HasRDPRU)
780*7a9b00ceSrobert Builder.defineMacro("__RDPRU__");
781e5dd7070Spatrick if (HasCLDEMOTE)
782e5dd7070Spatrick Builder.defineMacro("__CLDEMOTE__");
783e5dd7070Spatrick if (HasWAITPKG)
784e5dd7070Spatrick Builder.defineMacro("__WAITPKG__");
785e5dd7070Spatrick if (HasMOVDIRI)
786e5dd7070Spatrick Builder.defineMacro("__MOVDIRI__");
787e5dd7070Spatrick if (HasMOVDIR64B)
788e5dd7070Spatrick Builder.defineMacro("__MOVDIR64B__");
789e5dd7070Spatrick if (HasPCONFIG)
790e5dd7070Spatrick Builder.defineMacro("__PCONFIG__");
791e5dd7070Spatrick if (HasPTWRITE)
792e5dd7070Spatrick Builder.defineMacro("__PTWRITE__");
793e5dd7070Spatrick if (HasINVPCID)
794e5dd7070Spatrick Builder.defineMacro("__INVPCID__");
795e5dd7070Spatrick if (HasENQCMD)
796e5dd7070Spatrick Builder.defineMacro("__ENQCMD__");
797a0747c9fSpatrick if (HasHRESET)
798a0747c9fSpatrick Builder.defineMacro("__HRESET__");
799ec727ea7Spatrick if (HasAMXTILE)
800*7a9b00ceSrobert Builder.defineMacro("__AMX_TILE__");
801ec727ea7Spatrick if (HasAMXINT8)
802*7a9b00ceSrobert Builder.defineMacro("__AMX_INT8__");
803ec727ea7Spatrick if (HasAMXBF16)
804*7a9b00ceSrobert Builder.defineMacro("__AMX_BF16__");
805*7a9b00ceSrobert if (HasAMXFP16)
806*7a9b00ceSrobert Builder.defineMacro("__AMX_FP16__");
807*7a9b00ceSrobert if (HasCMPCCXADD)
808*7a9b00ceSrobert Builder.defineMacro("__CMPCCXADD__");
809*7a9b00ceSrobert if (HasRAOINT)
810*7a9b00ceSrobert Builder.defineMacro("__RAOINT__");
811*7a9b00ceSrobert if (HasAVXIFMA)
812*7a9b00ceSrobert Builder.defineMacro("__AVXIFMA__");
813*7a9b00ceSrobert if (HasAVXNECONVERT)
814*7a9b00ceSrobert Builder.defineMacro("__AVXNECONVERT__");
815a0747c9fSpatrick if (HasAVXVNNI)
816a0747c9fSpatrick Builder.defineMacro("__AVXVNNI__");
817*7a9b00ceSrobert if (HasAVXVNNIINT8)
818*7a9b00ceSrobert Builder.defineMacro("__AVXVNNIINT8__");
819ec727ea7Spatrick if (HasSERIALIZE)
820ec727ea7Spatrick Builder.defineMacro("__SERIALIZE__");
821ec727ea7Spatrick if (HasTSXLDTRK)
822ec727ea7Spatrick Builder.defineMacro("__TSXLDTRK__");
823a0747c9fSpatrick if (HasUINTR)
824a0747c9fSpatrick Builder.defineMacro("__UINTR__");
825*7a9b00ceSrobert if (HasCRC32)
826*7a9b00ceSrobert Builder.defineMacro("__CRC32__");
827e5dd7070Spatrick
828e5dd7070Spatrick // Each case falls through to the previous one here.
829e5dd7070Spatrick switch (SSELevel) {
830e5dd7070Spatrick case AVX512F:
831e5dd7070Spatrick Builder.defineMacro("__AVX512F__");
832*7a9b00ceSrobert [[fallthrough]];
833e5dd7070Spatrick case AVX2:
834e5dd7070Spatrick Builder.defineMacro("__AVX2__");
835*7a9b00ceSrobert [[fallthrough]];
836e5dd7070Spatrick case AVX:
837e5dd7070Spatrick Builder.defineMacro("__AVX__");
838*7a9b00ceSrobert [[fallthrough]];
839e5dd7070Spatrick case SSE42:
840e5dd7070Spatrick Builder.defineMacro("__SSE4_2__");
841*7a9b00ceSrobert [[fallthrough]];
842e5dd7070Spatrick case SSE41:
843e5dd7070Spatrick Builder.defineMacro("__SSE4_1__");
844*7a9b00ceSrobert [[fallthrough]];
845e5dd7070Spatrick case SSSE3:
846e5dd7070Spatrick Builder.defineMacro("__SSSE3__");
847*7a9b00ceSrobert [[fallthrough]];
848e5dd7070Spatrick case SSE3:
849e5dd7070Spatrick Builder.defineMacro("__SSE3__");
850*7a9b00ceSrobert [[fallthrough]];
851e5dd7070Spatrick case SSE2:
852e5dd7070Spatrick Builder.defineMacro("__SSE2__");
853e5dd7070Spatrick Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
854*7a9b00ceSrobert [[fallthrough]];
855e5dd7070Spatrick case SSE1:
856e5dd7070Spatrick Builder.defineMacro("__SSE__");
857e5dd7070Spatrick Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
858*7a9b00ceSrobert [[fallthrough]];
859e5dd7070Spatrick case NoSSE:
860e5dd7070Spatrick break;
861e5dd7070Spatrick }
862e5dd7070Spatrick
863e5dd7070Spatrick if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
864e5dd7070Spatrick switch (SSELevel) {
865e5dd7070Spatrick case AVX512F:
866e5dd7070Spatrick case AVX2:
867e5dd7070Spatrick case AVX:
868e5dd7070Spatrick case SSE42:
869e5dd7070Spatrick case SSE41:
870e5dd7070Spatrick case SSSE3:
871e5dd7070Spatrick case SSE3:
872e5dd7070Spatrick case SSE2:
873e5dd7070Spatrick Builder.defineMacro("_M_IX86_FP", Twine(2));
874e5dd7070Spatrick break;
875e5dd7070Spatrick case SSE1:
876e5dd7070Spatrick Builder.defineMacro("_M_IX86_FP", Twine(1));
877e5dd7070Spatrick break;
878e5dd7070Spatrick default:
879e5dd7070Spatrick Builder.defineMacro("_M_IX86_FP", Twine(0));
880e5dd7070Spatrick break;
881e5dd7070Spatrick }
882e5dd7070Spatrick }
883e5dd7070Spatrick
884e5dd7070Spatrick // Each case falls through to the previous one here.
885e5dd7070Spatrick switch (MMX3DNowLevel) {
886e5dd7070Spatrick case AMD3DNowAthlon:
887e5dd7070Spatrick Builder.defineMacro("__3dNOW_A__");
888*7a9b00ceSrobert [[fallthrough]];
889e5dd7070Spatrick case AMD3DNow:
890e5dd7070Spatrick Builder.defineMacro("__3dNOW__");
891*7a9b00ceSrobert [[fallthrough]];
892e5dd7070Spatrick case MMX:
893e5dd7070Spatrick Builder.defineMacro("__MMX__");
894*7a9b00ceSrobert [[fallthrough]];
895e5dd7070Spatrick case NoMMX3DNow:
896e5dd7070Spatrick break;
897e5dd7070Spatrick }
898e5dd7070Spatrick
899ec727ea7Spatrick if (CPU >= CK_i486 || CPU == CK_None) {
900e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
901e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
902e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
903e5dd7070Spatrick }
904e5dd7070Spatrick if (HasCX8)
905e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
906e5dd7070Spatrick if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)
907e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
908e5dd7070Spatrick
909e5dd7070Spatrick if (HasFloat128)
910e5dd7070Spatrick Builder.defineMacro("__SIZEOF_FLOAT128__", "16");
911e5dd7070Spatrick }
912e5dd7070Spatrick
isValidFeatureName(StringRef Name) const913e5dd7070Spatrick bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
914e5dd7070Spatrick return llvm::StringSwitch<bool>(Name)
915e5dd7070Spatrick .Case("3dnow", true)
916e5dd7070Spatrick .Case("3dnowa", true)
917e5dd7070Spatrick .Case("adx", true)
918e5dd7070Spatrick .Case("aes", true)
919ec727ea7Spatrick .Case("amx-bf16", true)
920*7a9b00ceSrobert .Case("amx-fp16", true)
921ec727ea7Spatrick .Case("amx-int8", true)
922ec727ea7Spatrick .Case("amx-tile", true)
923e5dd7070Spatrick .Case("avx", true)
924e5dd7070Spatrick .Case("avx2", true)
925e5dd7070Spatrick .Case("avx512f", true)
926e5dd7070Spatrick .Case("avx512cd", true)
927e5dd7070Spatrick .Case("avx512vpopcntdq", true)
928e5dd7070Spatrick .Case("avx512vnni", true)
929e5dd7070Spatrick .Case("avx512bf16", true)
930e5dd7070Spatrick .Case("avx512er", true)
931*7a9b00ceSrobert .Case("avx512fp16", true)
932e5dd7070Spatrick .Case("avx512pf", true)
933e5dd7070Spatrick .Case("avx512dq", true)
934e5dd7070Spatrick .Case("avx512bitalg", true)
935e5dd7070Spatrick .Case("avx512bw", true)
936e5dd7070Spatrick .Case("avx512vl", true)
937e5dd7070Spatrick .Case("avx512vbmi", true)
938e5dd7070Spatrick .Case("avx512vbmi2", true)
939e5dd7070Spatrick .Case("avx512ifma", true)
940e5dd7070Spatrick .Case("avx512vp2intersect", true)
941*7a9b00ceSrobert .Case("avxifma", true)
942*7a9b00ceSrobert .Case("avxneconvert", true)
943a0747c9fSpatrick .Case("avxvnni", true)
944*7a9b00ceSrobert .Case("avxvnniint8", true)
945e5dd7070Spatrick .Case("bmi", true)
946e5dd7070Spatrick .Case("bmi2", true)
947e5dd7070Spatrick .Case("cldemote", true)
948e5dd7070Spatrick .Case("clflushopt", true)
949e5dd7070Spatrick .Case("clwb", true)
950e5dd7070Spatrick .Case("clzero", true)
951*7a9b00ceSrobert .Case("cmpccxadd", true)
952*7a9b00ceSrobert .Case("crc32", true)
953e5dd7070Spatrick .Case("cx16", true)
954e5dd7070Spatrick .Case("enqcmd", true)
955e5dd7070Spatrick .Case("f16c", true)
956e5dd7070Spatrick .Case("fma", true)
957e5dd7070Spatrick .Case("fma4", true)
958e5dd7070Spatrick .Case("fsgsbase", true)
959e5dd7070Spatrick .Case("fxsr", true)
960a0747c9fSpatrick .Case("general-regs-only", true)
961e5dd7070Spatrick .Case("gfni", true)
962a0747c9fSpatrick .Case("hreset", true)
963e5dd7070Spatrick .Case("invpcid", true)
964a0747c9fSpatrick .Case("kl", true)
965a0747c9fSpatrick .Case("widekl", true)
966e5dd7070Spatrick .Case("lwp", true)
967e5dd7070Spatrick .Case("lzcnt", true)
968e5dd7070Spatrick .Case("mmx", true)
969e5dd7070Spatrick .Case("movbe", true)
970e5dd7070Spatrick .Case("movdiri", true)
971e5dd7070Spatrick .Case("movdir64b", true)
972e5dd7070Spatrick .Case("mwaitx", true)
973e5dd7070Spatrick .Case("pclmul", true)
974e5dd7070Spatrick .Case("pconfig", true)
975e5dd7070Spatrick .Case("pku", true)
976e5dd7070Spatrick .Case("popcnt", true)
977*7a9b00ceSrobert .Case("prefetchi", true)
978e5dd7070Spatrick .Case("prefetchwt1", true)
979e5dd7070Spatrick .Case("prfchw", true)
980e5dd7070Spatrick .Case("ptwrite", true)
981*7a9b00ceSrobert .Case("raoint", true)
982e5dd7070Spatrick .Case("rdpid", true)
983*7a9b00ceSrobert .Case("rdpru", true)
984e5dd7070Spatrick .Case("rdrnd", true)
985e5dd7070Spatrick .Case("rdseed", true)
986e5dd7070Spatrick .Case("rtm", true)
987e5dd7070Spatrick .Case("sahf", true)
988ec727ea7Spatrick .Case("serialize", true)
989e5dd7070Spatrick .Case("sgx", true)
990e5dd7070Spatrick .Case("sha", true)
991e5dd7070Spatrick .Case("shstk", true)
992e5dd7070Spatrick .Case("sse", true)
993e5dd7070Spatrick .Case("sse2", true)
994e5dd7070Spatrick .Case("sse3", true)
995e5dd7070Spatrick .Case("ssse3", true)
996e5dd7070Spatrick .Case("sse4", true)
997e5dd7070Spatrick .Case("sse4.1", true)
998e5dd7070Spatrick .Case("sse4.2", true)
999e5dd7070Spatrick .Case("sse4a", true)
1000e5dd7070Spatrick .Case("tbm", true)
1001ec727ea7Spatrick .Case("tsxldtrk", true)
1002a0747c9fSpatrick .Case("uintr", true)
1003e5dd7070Spatrick .Case("vaes", true)
1004e5dd7070Spatrick .Case("vpclmulqdq", true)
1005e5dd7070Spatrick .Case("wbnoinvd", true)
1006e5dd7070Spatrick .Case("waitpkg", true)
1007e5dd7070Spatrick .Case("x87", true)
1008e5dd7070Spatrick .Case("xop", true)
1009e5dd7070Spatrick .Case("xsave", true)
1010e5dd7070Spatrick .Case("xsavec", true)
1011e5dd7070Spatrick .Case("xsaves", true)
1012e5dd7070Spatrick .Case("xsaveopt", true)
1013e5dd7070Spatrick .Default(false);
1014e5dd7070Spatrick }
1015e5dd7070Spatrick
hasFeature(StringRef Feature) const1016e5dd7070Spatrick bool X86TargetInfo::hasFeature(StringRef Feature) const {
1017e5dd7070Spatrick return llvm::StringSwitch<bool>(Feature)
1018e5dd7070Spatrick .Case("adx", HasADX)
1019e5dd7070Spatrick .Case("aes", HasAES)
1020ec727ea7Spatrick .Case("amx-bf16", HasAMXBF16)
1021*7a9b00ceSrobert .Case("amx-fp16", HasAMXFP16)
1022ec727ea7Spatrick .Case("amx-int8", HasAMXINT8)
1023ec727ea7Spatrick .Case("amx-tile", HasAMXTILE)
1024e5dd7070Spatrick .Case("avx", SSELevel >= AVX)
1025e5dd7070Spatrick .Case("avx2", SSELevel >= AVX2)
1026e5dd7070Spatrick .Case("avx512f", SSELevel >= AVX512F)
1027e5dd7070Spatrick .Case("avx512cd", HasAVX512CD)
1028e5dd7070Spatrick .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ)
1029e5dd7070Spatrick .Case("avx512vnni", HasAVX512VNNI)
1030e5dd7070Spatrick .Case("avx512bf16", HasAVX512BF16)
1031e5dd7070Spatrick .Case("avx512er", HasAVX512ER)
1032*7a9b00ceSrobert .Case("avx512fp16", HasAVX512FP16)
1033e5dd7070Spatrick .Case("avx512pf", HasAVX512PF)
1034e5dd7070Spatrick .Case("avx512dq", HasAVX512DQ)
1035e5dd7070Spatrick .Case("avx512bitalg", HasAVX512BITALG)
1036e5dd7070Spatrick .Case("avx512bw", HasAVX512BW)
1037e5dd7070Spatrick .Case("avx512vl", HasAVX512VL)
1038e5dd7070Spatrick .Case("avx512vbmi", HasAVX512VBMI)
1039e5dd7070Spatrick .Case("avx512vbmi2", HasAVX512VBMI2)
1040e5dd7070Spatrick .Case("avx512ifma", HasAVX512IFMA)
1041e5dd7070Spatrick .Case("avx512vp2intersect", HasAVX512VP2INTERSECT)
1042*7a9b00ceSrobert .Case("avxifma", HasAVXIFMA)
1043*7a9b00ceSrobert .Case("avxneconvert", HasAVXNECONVERT)
1044*7a9b00ceSrobert .Case("avxvnni", HasAVXVNNI)
1045*7a9b00ceSrobert .Case("avxvnniint8", HasAVXVNNIINT8)
1046e5dd7070Spatrick .Case("bmi", HasBMI)
1047e5dd7070Spatrick .Case("bmi2", HasBMI2)
1048e5dd7070Spatrick .Case("cldemote", HasCLDEMOTE)
1049e5dd7070Spatrick .Case("clflushopt", HasCLFLUSHOPT)
1050e5dd7070Spatrick .Case("clwb", HasCLWB)
1051e5dd7070Spatrick .Case("clzero", HasCLZERO)
1052*7a9b00ceSrobert .Case("cmpccxadd", HasCMPCCXADD)
1053*7a9b00ceSrobert .Case("crc32", HasCRC32)
1054e5dd7070Spatrick .Case("cx8", HasCX8)
1055e5dd7070Spatrick .Case("cx16", HasCX16)
1056e5dd7070Spatrick .Case("enqcmd", HasENQCMD)
1057e5dd7070Spatrick .Case("f16c", HasF16C)
1058e5dd7070Spatrick .Case("fma", HasFMA)
1059e5dd7070Spatrick .Case("fma4", XOPLevel >= FMA4)
1060e5dd7070Spatrick .Case("fsgsbase", HasFSGSBASE)
1061e5dd7070Spatrick .Case("fxsr", HasFXSR)
1062e5dd7070Spatrick .Case("gfni", HasGFNI)
1063a0747c9fSpatrick .Case("hreset", HasHRESET)
1064e5dd7070Spatrick .Case("invpcid", HasINVPCID)
1065a0747c9fSpatrick .Case("kl", HasKL)
1066a0747c9fSpatrick .Case("widekl", HasWIDEKL)
1067e5dd7070Spatrick .Case("lwp", HasLWP)
1068e5dd7070Spatrick .Case("lzcnt", HasLZCNT)
1069e5dd7070Spatrick .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
1070e5dd7070Spatrick .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
1071e5dd7070Spatrick .Case("mmx", MMX3DNowLevel >= MMX)
1072e5dd7070Spatrick .Case("movbe", HasMOVBE)
1073e5dd7070Spatrick .Case("movdiri", HasMOVDIRI)
1074e5dd7070Spatrick .Case("movdir64b", HasMOVDIR64B)
1075adae0cfdSpatrick .Case("save-args", HasSaveArgs)
1076e5dd7070Spatrick .Case("mwaitx", HasMWAITX)
1077e5dd7070Spatrick .Case("pclmul", HasPCLMUL)
1078e5dd7070Spatrick .Case("pconfig", HasPCONFIG)
1079e5dd7070Spatrick .Case("pku", HasPKU)
1080e5dd7070Spatrick .Case("popcnt", HasPOPCNT)
1081*7a9b00ceSrobert .Case("prefetchi", HasPREFETCHI)
1082e5dd7070Spatrick .Case("prefetchwt1", HasPREFETCHWT1)
1083e5dd7070Spatrick .Case("prfchw", HasPRFCHW)
1084e5dd7070Spatrick .Case("ptwrite", HasPTWRITE)
1085*7a9b00ceSrobert .Case("raoint", HasRAOINT)
1086e5dd7070Spatrick .Case("rdpid", HasRDPID)
1087*7a9b00ceSrobert .Case("rdpru", HasRDPRU)
1088e5dd7070Spatrick .Case("rdrnd", HasRDRND)
1089e5dd7070Spatrick .Case("rdseed", HasRDSEED)
1090e5dd7070Spatrick .Case("retpoline-external-thunk", HasRetpolineExternalThunk)
1091e5dd7070Spatrick .Case("rtm", HasRTM)
1092e5dd7070Spatrick .Case("sahf", HasLAHFSAHF)
1093ec727ea7Spatrick .Case("serialize", HasSERIALIZE)
1094e5dd7070Spatrick .Case("sgx", HasSGX)
1095e5dd7070Spatrick .Case("sha", HasSHA)
1096e5dd7070Spatrick .Case("shstk", HasSHSTK)
1097e5dd7070Spatrick .Case("sse", SSELevel >= SSE1)
1098e5dd7070Spatrick .Case("sse2", SSELevel >= SSE2)
1099e5dd7070Spatrick .Case("sse3", SSELevel >= SSE3)
1100e5dd7070Spatrick .Case("ssse3", SSELevel >= SSSE3)
1101e5dd7070Spatrick .Case("sse4.1", SSELevel >= SSE41)
1102e5dd7070Spatrick .Case("sse4.2", SSELevel >= SSE42)
1103e5dd7070Spatrick .Case("sse4a", XOPLevel >= SSE4A)
1104e5dd7070Spatrick .Case("tbm", HasTBM)
1105ec727ea7Spatrick .Case("tsxldtrk", HasTSXLDTRK)
1106a0747c9fSpatrick .Case("uintr", HasUINTR)
1107e5dd7070Spatrick .Case("vaes", HasVAES)
1108e5dd7070Spatrick .Case("vpclmulqdq", HasVPCLMULQDQ)
1109e5dd7070Spatrick .Case("wbnoinvd", HasWBNOINVD)
1110e5dd7070Spatrick .Case("waitpkg", HasWAITPKG)
1111e5dd7070Spatrick .Case("x86", true)
1112e5dd7070Spatrick .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
1113e5dd7070Spatrick .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
1114*7a9b00ceSrobert .Case("x87", HasX87)
1115e5dd7070Spatrick .Case("xop", XOPLevel >= XOP)
1116e5dd7070Spatrick .Case("xsave", HasXSAVE)
1117e5dd7070Spatrick .Case("xsavec", HasXSAVEC)
1118e5dd7070Spatrick .Case("xsaves", HasXSAVES)
1119e5dd7070Spatrick .Case("xsaveopt", HasXSAVEOPT)
1120e5dd7070Spatrick .Default(false);
1121e5dd7070Spatrick }
1122e5dd7070Spatrick
1123e5dd7070Spatrick // We can't use a generic validation scheme for the features accepted here
1124e5dd7070Spatrick // versus subtarget features accepted in the target attribute because the
1125e5dd7070Spatrick // bitfield structure that's initialized in the runtime only supports the
1126e5dd7070Spatrick // below currently rather than the full range of subtarget features. (See
1127e5dd7070Spatrick // X86TargetInfo::hasFeature for a somewhat comprehensive list).
validateCpuSupports(StringRef FeatureStr) const1128e5dd7070Spatrick bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
1129e5dd7070Spatrick return llvm::StringSwitch<bool>(FeatureStr)
1130*7a9b00ceSrobert #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) .Case(STR, true)
1131*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1132e5dd7070Spatrick .Default(false);
1133e5dd7070Spatrick }
1134e5dd7070Spatrick
getFeature(StringRef Name)1135e5dd7070Spatrick static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {
1136e5dd7070Spatrick return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)
1137*7a9b00ceSrobert #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \
1138*7a9b00ceSrobert .Case(STR, llvm::X86::FEATURE_##ENUM)
1139*7a9b00ceSrobert
1140*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1141e5dd7070Spatrick ;
1142e5dd7070Spatrick // Note, this function should only be used after ensuring the value is
1143e5dd7070Spatrick // correct, so it asserts if the value is out of range.
1144e5dd7070Spatrick }
1145e5dd7070Spatrick
multiVersionSortPriority(StringRef Name) const1146e5dd7070Spatrick unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
1147e5dd7070Spatrick // Valid CPUs have a 'key feature' that compares just better than its key
1148e5dd7070Spatrick // feature.
1149ec727ea7Spatrick using namespace llvm::X86;
1150ec727ea7Spatrick CPUKind Kind = parseArchX86(Name);
1151ec727ea7Spatrick if (Kind != CK_None) {
1152ec727ea7Spatrick ProcessorFeatures KeyFeature = getKeyFeature(Kind);
1153ec727ea7Spatrick return (getFeaturePriority(KeyFeature) << 1) + 1;
1154e5dd7070Spatrick }
1155e5dd7070Spatrick
1156e5dd7070Spatrick // Now we know we have a feature, so get its priority and shift it a few so
1157e5dd7070Spatrick // that we have sufficient room for the CPUs (above).
1158e5dd7070Spatrick return getFeaturePriority(getFeature(Name)) << 1;
1159e5dd7070Spatrick }
1160e5dd7070Spatrick
validateCPUSpecificCPUDispatch(StringRef Name) const1161e5dd7070Spatrick bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const {
1162e5dd7070Spatrick return llvm::StringSwitch<bool>(Name)
1163*7a9b00ceSrobert #define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, true)
1164*7a9b00ceSrobert #define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, true)
1165*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1166e5dd7070Spatrick .Default(false);
1167e5dd7070Spatrick }
1168e5dd7070Spatrick
CPUSpecificCPUDispatchNameDealias(StringRef Name)1169e5dd7070Spatrick static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) {
1170e5dd7070Spatrick return llvm::StringSwitch<StringRef>(Name)
1171*7a9b00ceSrobert #define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, NAME)
1172*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1173e5dd7070Spatrick .Default(Name);
1174e5dd7070Spatrick }
1175e5dd7070Spatrick
CPUSpecificManglingCharacter(StringRef Name) const1176e5dd7070Spatrick char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const {
1177e5dd7070Spatrick return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name))
1178*7a9b00ceSrobert #define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, MANGLING)
1179*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1180e5dd7070Spatrick .Default(0);
1181e5dd7070Spatrick }
1182e5dd7070Spatrick
getCPUSpecificCPUDispatchFeatures(StringRef Name,llvm::SmallVectorImpl<StringRef> & Features) const1183e5dd7070Spatrick void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(
1184e5dd7070Spatrick StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
1185e5dd7070Spatrick StringRef WholeList =
1186e5dd7070Spatrick llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name))
1187*7a9b00ceSrobert #define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, FEATURES)
1188*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1189e5dd7070Spatrick .Default("");
1190e5dd7070Spatrick WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1191e5dd7070Spatrick }
1192e5dd7070Spatrick
getCPUSpecificTuneName(StringRef Name) const1193*7a9b00ceSrobert StringRef X86TargetInfo::getCPUSpecificTuneName(StringRef Name) const {
1194*7a9b00ceSrobert return llvm::StringSwitch<StringRef>(Name)
1195*7a9b00ceSrobert #define CPU_SPECIFIC(NAME, TUNE_NAME, MANGLING, FEATURES) .Case(NAME, TUNE_NAME)
1196*7a9b00ceSrobert #define CPU_SPECIFIC_ALIAS(NEW_NAME, TUNE_NAME, NAME) .Case(NEW_NAME, TUNE_NAME)
1197*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1198*7a9b00ceSrobert .Default("");
1199*7a9b00ceSrobert }
1200*7a9b00ceSrobert
1201e5dd7070Spatrick // We can't use a generic validation scheme for the cpus accepted here
1202e5dd7070Spatrick // versus subtarget cpus accepted in the target attribute because the
1203e5dd7070Spatrick // variables intitialized by the runtime only support the below currently
1204e5dd7070Spatrick // rather than the full range of cpus.
validateCpuIs(StringRef FeatureStr) const1205e5dd7070Spatrick bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
1206e5dd7070Spatrick return llvm::StringSwitch<bool>(FeatureStr)
1207e5dd7070Spatrick #define X86_VENDOR(ENUM, STRING) .Case(STRING, true)
1208ec727ea7Spatrick #define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
1209ec727ea7Spatrick #define X86_CPU_TYPE(ENUM, STR) .Case(STR, true)
1210*7a9b00ceSrobert #define X86_CPU_SUBTYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
1211ec727ea7Spatrick #define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true)
1212*7a9b00ceSrobert #include "llvm/TargetParser/X86TargetParser.def"
1213e5dd7070Spatrick .Default(false);
1214e5dd7070Spatrick }
1215e5dd7070Spatrick
matchAsmCCConstraint(const char * & Name)1216e5dd7070Spatrick static unsigned matchAsmCCConstraint(const char *&Name) {
1217e5dd7070Spatrick auto RV = llvm::StringSwitch<unsigned>(Name)
1218e5dd7070Spatrick .Case("@cca", 4)
1219e5dd7070Spatrick .Case("@ccae", 5)
1220e5dd7070Spatrick .Case("@ccb", 4)
1221e5dd7070Spatrick .Case("@ccbe", 5)
1222e5dd7070Spatrick .Case("@ccc", 4)
1223e5dd7070Spatrick .Case("@cce", 4)
1224e5dd7070Spatrick .Case("@ccz", 4)
1225e5dd7070Spatrick .Case("@ccg", 4)
1226e5dd7070Spatrick .Case("@ccge", 5)
1227e5dd7070Spatrick .Case("@ccl", 4)
1228e5dd7070Spatrick .Case("@ccle", 5)
1229e5dd7070Spatrick .Case("@ccna", 5)
1230e5dd7070Spatrick .Case("@ccnae", 6)
1231e5dd7070Spatrick .Case("@ccnb", 5)
1232e5dd7070Spatrick .Case("@ccnbe", 6)
1233e5dd7070Spatrick .Case("@ccnc", 5)
1234e5dd7070Spatrick .Case("@ccne", 5)
1235e5dd7070Spatrick .Case("@ccnz", 5)
1236e5dd7070Spatrick .Case("@ccng", 5)
1237e5dd7070Spatrick .Case("@ccnge", 6)
1238e5dd7070Spatrick .Case("@ccnl", 5)
1239e5dd7070Spatrick .Case("@ccnle", 6)
1240e5dd7070Spatrick .Case("@ccno", 5)
1241e5dd7070Spatrick .Case("@ccnp", 5)
1242e5dd7070Spatrick .Case("@ccns", 5)
1243e5dd7070Spatrick .Case("@cco", 4)
1244e5dd7070Spatrick .Case("@ccp", 4)
1245e5dd7070Spatrick .Case("@ccs", 4)
1246e5dd7070Spatrick .Default(0);
1247e5dd7070Spatrick return RV;
1248e5dd7070Spatrick }
1249e5dd7070Spatrick
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1250e5dd7070Spatrick bool X86TargetInfo::validateAsmConstraint(
1251e5dd7070Spatrick const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1252e5dd7070Spatrick switch (*Name) {
1253e5dd7070Spatrick default:
1254e5dd7070Spatrick return false;
1255e5dd7070Spatrick // Constant constraints.
1256e5dd7070Spatrick case 'e': // 32-bit signed integer constant for use with sign-extending x86_64
1257e5dd7070Spatrick // instructions.
1258e5dd7070Spatrick case 'Z': // 32-bit unsigned integer constant for use with zero-extending
1259e5dd7070Spatrick // x86_64 instructions.
1260e5dd7070Spatrick case 's':
1261e5dd7070Spatrick Info.setRequiresImmediate();
1262e5dd7070Spatrick return true;
1263e5dd7070Spatrick case 'I':
1264e5dd7070Spatrick Info.setRequiresImmediate(0, 31);
1265e5dd7070Spatrick return true;
1266e5dd7070Spatrick case 'J':
1267e5dd7070Spatrick Info.setRequiresImmediate(0, 63);
1268e5dd7070Spatrick return true;
1269e5dd7070Spatrick case 'K':
1270e5dd7070Spatrick Info.setRequiresImmediate(-128, 127);
1271e5dd7070Spatrick return true;
1272e5dd7070Spatrick case 'L':
1273e5dd7070Spatrick Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)});
1274e5dd7070Spatrick return true;
1275e5dd7070Spatrick case 'M':
1276e5dd7070Spatrick Info.setRequiresImmediate(0, 3);
1277e5dd7070Spatrick return true;
1278e5dd7070Spatrick case 'N':
1279e5dd7070Spatrick Info.setRequiresImmediate(0, 255);
1280e5dd7070Spatrick return true;
1281e5dd7070Spatrick case 'O':
1282e5dd7070Spatrick Info.setRequiresImmediate(0, 127);
1283e5dd7070Spatrick return true;
1284e5dd7070Spatrick // Register constraints.
1285e5dd7070Spatrick case 'Y': // 'Y' is the first character for several 2-character constraints.
1286e5dd7070Spatrick // Shift the pointer to the second character of the constraint.
1287e5dd7070Spatrick Name++;
1288e5dd7070Spatrick switch (*Name) {
1289e5dd7070Spatrick default:
1290e5dd7070Spatrick return false;
1291ec727ea7Spatrick case 'z': // First SSE register.
1292e5dd7070Spatrick case '2':
1293e5dd7070Spatrick case 't': // Any SSE register, when SSE2 is enabled.
1294e5dd7070Spatrick case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1295e5dd7070Spatrick case 'm': // Any MMX register, when inter-unit moves enabled.
1296e5dd7070Spatrick case 'k': // AVX512 arch mask registers: k1-k7.
1297e5dd7070Spatrick Info.setAllowsRegister();
1298e5dd7070Spatrick return true;
1299e5dd7070Spatrick }
1300e5dd7070Spatrick case 'f': // Any x87 floating point stack register.
1301e5dd7070Spatrick // Constraint 'f' cannot be used for output operands.
1302e5dd7070Spatrick if (Info.ConstraintStr[0] == '=')
1303e5dd7070Spatrick return false;
1304e5dd7070Spatrick Info.setAllowsRegister();
1305e5dd7070Spatrick return true;
1306e5dd7070Spatrick case 'a': // eax.
1307e5dd7070Spatrick case 'b': // ebx.
1308e5dd7070Spatrick case 'c': // ecx.
1309e5dd7070Spatrick case 'd': // edx.
1310e5dd7070Spatrick case 'S': // esi.
1311e5dd7070Spatrick case 'D': // edi.
1312e5dd7070Spatrick case 'A': // edx:eax.
1313e5dd7070Spatrick case 't': // Top of floating point stack.
1314e5dd7070Spatrick case 'u': // Second from top of floating point stack.
1315e5dd7070Spatrick case 'q': // Any register accessible as [r]l: a, b, c, and d.
1316e5dd7070Spatrick case 'y': // Any MMX register.
1317e5dd7070Spatrick case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)
1318e5dd7070Spatrick case 'x': // Any SSE register.
1319e5dd7070Spatrick case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0
1320e5dd7070Spatrick // for intermideate k reg operations).
1321e5dd7070Spatrick case 'Q': // Any register accessible as [r]h: a, b, c, and d.
1322e5dd7070Spatrick case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1323e5dd7070Spatrick case 'l': // "Index" registers: any general register that can be used as an
1324e5dd7070Spatrick // index in a base+index memory access.
1325e5dd7070Spatrick Info.setAllowsRegister();
1326e5dd7070Spatrick return true;
1327e5dd7070Spatrick // Floating point constant constraints.
1328e5dd7070Spatrick case 'C': // SSE floating point constant.
1329e5dd7070Spatrick case 'G': // x87 floating point constant.
1330e5dd7070Spatrick return true;
1331e5dd7070Spatrick case '@':
1332e5dd7070Spatrick // CC condition changes.
1333e5dd7070Spatrick if (auto Len = matchAsmCCConstraint(Name)) {
1334e5dd7070Spatrick Name += Len - 1;
1335e5dd7070Spatrick Info.setAllowsRegister();
1336e5dd7070Spatrick return true;
1337e5dd7070Spatrick }
1338e5dd7070Spatrick return false;
1339e5dd7070Spatrick }
1340e5dd7070Spatrick }
1341e5dd7070Spatrick
1342ec727ea7Spatrick // Below is based on the following information:
1343ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1344ec727ea7Spatrick // | Processor Name | Cache Line Size (Bytes) | Source |
1345ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1346ec727ea7Spatrick // | i386 | 64 | https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf |
1347ec727ea7Spatrick // | i486 | 16 | "four doublewords" (doubleword = 32 bits, 4 bits * 32 bits = 16 bytes) https://en.wikichip.org/w/images/d/d3/i486_MICROPROCESSOR_HARDWARE_REFERENCE_MANUAL_%281990%29.pdf and http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.126.4216&rep=rep1&type=pdf (page 29) |
1348ec727ea7Spatrick // | i586/Pentium MMX | 32 | https://www.7-cpu.com/cpu/P-MMX.html |
1349ec727ea7Spatrick // | i686/Pentium | 32 | https://www.7-cpu.com/cpu/P6.html |
1350ec727ea7Spatrick // | Netburst/Pentium4 | 64 | https://www.7-cpu.com/cpu/P4-180.html |
1351ec727ea7Spatrick // | Atom | 64 | https://www.7-cpu.com/cpu/Atom.html |
1352ec727ea7Spatrick // | Westmere | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/sandy_bridge_(client) "Cache Architecture" |
1353ec727ea7Spatrick // | Sandy Bridge | 64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html |
1354ec727ea7Spatrick // | Ivy Bridge | 64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html |
1355ec727ea7Spatrick // | Haswell | 64 | https://www.7-cpu.com/cpu/Haswell.html |
1356ec727ea7Spatrick // | Boadwell | 64 | https://www.7-cpu.com/cpu/Broadwell.html |
1357ec727ea7Spatrick // | Skylake (including skylake-avx512) | 64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy" |
1358ec727ea7Spatrick // | Cascade Lake | 64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy" |
1359ec727ea7Spatrick // | Skylake | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy" |
1360ec727ea7Spatrick // | Ice Lake | 64 | https://www.7-cpu.com/cpu/Ice_Lake.html |
1361ec727ea7Spatrick // | Knights Landing | 64 | https://software.intel.com/en-us/articles/intel-xeon-phi-processor-7200-family-memory-management-optimizations "The Intel® Xeon Phi™ Processor Architecture" |
1362ec727ea7Spatrick // | Knights Mill | 64 | https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf?countrylabel=Colombia "2.5.5.2 L1 DCache " |
1363ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
getCPUCacheLineSize() const1364*7a9b00ceSrobert std::optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
1365ec727ea7Spatrick using namespace llvm::X86;
1366ec727ea7Spatrick switch (CPU) {
1367ec727ea7Spatrick // i386
1368ec727ea7Spatrick case CK_i386:
1369ec727ea7Spatrick // i486
1370ec727ea7Spatrick case CK_i486:
1371ec727ea7Spatrick case CK_WinChipC6:
1372ec727ea7Spatrick case CK_WinChip2:
1373ec727ea7Spatrick case CK_C3:
1374ec727ea7Spatrick // Lakemont
1375ec727ea7Spatrick case CK_Lakemont:
1376ec727ea7Spatrick return 16;
1377ec727ea7Spatrick
1378ec727ea7Spatrick // i586
1379ec727ea7Spatrick case CK_i586:
1380ec727ea7Spatrick case CK_Pentium:
1381ec727ea7Spatrick case CK_PentiumMMX:
1382ec727ea7Spatrick // i686
1383ec727ea7Spatrick case CK_PentiumPro:
1384ec727ea7Spatrick case CK_i686:
1385ec727ea7Spatrick case CK_Pentium2:
1386ec727ea7Spatrick case CK_Pentium3:
1387ec727ea7Spatrick case CK_PentiumM:
1388ec727ea7Spatrick case CK_C3_2:
1389ec727ea7Spatrick // K6
1390ec727ea7Spatrick case CK_K6:
1391ec727ea7Spatrick case CK_K6_2:
1392ec727ea7Spatrick case CK_K6_3:
1393ec727ea7Spatrick // Geode
1394ec727ea7Spatrick case CK_Geode:
1395ec727ea7Spatrick return 32;
1396ec727ea7Spatrick
1397ec727ea7Spatrick // Netburst
1398ec727ea7Spatrick case CK_Pentium4:
1399ec727ea7Spatrick case CK_Prescott:
1400ec727ea7Spatrick case CK_Nocona:
1401ec727ea7Spatrick // Atom
1402ec727ea7Spatrick case CK_Bonnell:
1403ec727ea7Spatrick case CK_Silvermont:
1404ec727ea7Spatrick case CK_Goldmont:
1405ec727ea7Spatrick case CK_GoldmontPlus:
1406ec727ea7Spatrick case CK_Tremont:
1407ec727ea7Spatrick
1408ec727ea7Spatrick case CK_Westmere:
1409ec727ea7Spatrick case CK_SandyBridge:
1410ec727ea7Spatrick case CK_IvyBridge:
1411ec727ea7Spatrick case CK_Haswell:
1412ec727ea7Spatrick case CK_Broadwell:
1413ec727ea7Spatrick case CK_SkylakeClient:
1414ec727ea7Spatrick case CK_SkylakeServer:
1415ec727ea7Spatrick case CK_Cascadelake:
1416ec727ea7Spatrick case CK_Nehalem:
1417ec727ea7Spatrick case CK_Cooperlake:
1418ec727ea7Spatrick case CK_Cannonlake:
1419ec727ea7Spatrick case CK_Tigerlake:
1420a0747c9fSpatrick case CK_SapphireRapids:
1421ec727ea7Spatrick case CK_IcelakeClient:
1422a0747c9fSpatrick case CK_Rocketlake:
1423ec727ea7Spatrick case CK_IcelakeServer:
1424a0747c9fSpatrick case CK_Alderlake:
1425*7a9b00ceSrobert case CK_Raptorlake:
1426*7a9b00ceSrobert case CK_Meteorlake:
1427*7a9b00ceSrobert case CK_Sierraforest:
1428*7a9b00ceSrobert case CK_Grandridge:
1429*7a9b00ceSrobert case CK_Graniterapids:
1430*7a9b00ceSrobert case CK_Emeraldrapids:
1431ec727ea7Spatrick case CK_KNL:
1432ec727ea7Spatrick case CK_KNM:
1433ec727ea7Spatrick // K7
1434ec727ea7Spatrick case CK_Athlon:
1435ec727ea7Spatrick case CK_AthlonXP:
1436ec727ea7Spatrick // K8
1437ec727ea7Spatrick case CK_K8:
1438ec727ea7Spatrick case CK_K8SSE3:
1439ec727ea7Spatrick case CK_AMDFAM10:
1440ec727ea7Spatrick // Bobcat
1441ec727ea7Spatrick case CK_BTVER1:
1442ec727ea7Spatrick case CK_BTVER2:
1443ec727ea7Spatrick // Bulldozer
1444ec727ea7Spatrick case CK_BDVER1:
1445ec727ea7Spatrick case CK_BDVER2:
1446ec727ea7Spatrick case CK_BDVER3:
1447ec727ea7Spatrick case CK_BDVER4:
1448ec727ea7Spatrick // Zen
1449ec727ea7Spatrick case CK_ZNVER1:
1450ec727ea7Spatrick case CK_ZNVER2:
1451a0747c9fSpatrick case CK_ZNVER3:
1452*7a9b00ceSrobert case CK_ZNVER4:
1453ec727ea7Spatrick // Deprecated
1454ec727ea7Spatrick case CK_x86_64:
1455a0747c9fSpatrick case CK_x86_64_v2:
1456a0747c9fSpatrick case CK_x86_64_v3:
1457a0747c9fSpatrick case CK_x86_64_v4:
1458ec727ea7Spatrick case CK_Yonah:
1459ec727ea7Spatrick case CK_Penryn:
1460ec727ea7Spatrick case CK_Core2:
1461ec727ea7Spatrick return 64;
1462ec727ea7Spatrick
1463ec727ea7Spatrick // The following currently have unknown cache line sizes (but they are probably all 64):
1464ec727ea7Spatrick // Core
1465ec727ea7Spatrick case CK_None:
1466*7a9b00ceSrobert return std::nullopt;
1467ec727ea7Spatrick }
1468ec727ea7Spatrick llvm_unreachable("Unknown CPU kind");
1469ec727ea7Spatrick }
1470ec727ea7Spatrick
validateOutputSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1471e5dd7070Spatrick bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
1472e5dd7070Spatrick StringRef Constraint,
1473e5dd7070Spatrick unsigned Size) const {
1474e5dd7070Spatrick // Strip off constraint modifiers.
1475e5dd7070Spatrick while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1476e5dd7070Spatrick Constraint = Constraint.substr(1);
1477e5dd7070Spatrick
1478e5dd7070Spatrick return validateOperandSize(FeatureMap, Constraint, Size);
1479e5dd7070Spatrick }
1480e5dd7070Spatrick
validateInputSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1481e5dd7070Spatrick bool X86TargetInfo::validateInputSize(const llvm::StringMap<bool> &FeatureMap,
1482e5dd7070Spatrick StringRef Constraint,
1483e5dd7070Spatrick unsigned Size) const {
1484e5dd7070Spatrick return validateOperandSize(FeatureMap, Constraint, Size);
1485e5dd7070Spatrick }
1486e5dd7070Spatrick
validateOperandSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size) const1487e5dd7070Spatrick bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
1488e5dd7070Spatrick StringRef Constraint,
1489e5dd7070Spatrick unsigned Size) const {
1490e5dd7070Spatrick switch (Constraint[0]) {
1491e5dd7070Spatrick default:
1492e5dd7070Spatrick break;
1493e5dd7070Spatrick case 'k':
1494e5dd7070Spatrick // Registers k0-k7 (AVX512) size limit is 64 bit.
1495e5dd7070Spatrick case 'y':
1496e5dd7070Spatrick return Size <= 64;
1497e5dd7070Spatrick case 'f':
1498e5dd7070Spatrick case 't':
1499e5dd7070Spatrick case 'u':
1500e5dd7070Spatrick return Size <= 128;
1501e5dd7070Spatrick case 'Y':
1502e5dd7070Spatrick // 'Y' is the first character for several 2-character constraints.
1503e5dd7070Spatrick switch (Constraint[1]) {
1504e5dd7070Spatrick default:
1505e5dd7070Spatrick return false;
1506e5dd7070Spatrick case 'm':
1507e5dd7070Spatrick // 'Ym' is synonymous with 'y'.
1508e5dd7070Spatrick case 'k':
1509e5dd7070Spatrick return Size <= 64;
1510e5dd7070Spatrick case 'z':
1511ec727ea7Spatrick // XMM0/YMM/ZMM0
1512a0747c9fSpatrick if (hasFeatureEnabled(FeatureMap, "avx512f"))
1513ec727ea7Spatrick // ZMM0 can be used if target supports AVX512F.
1514ec727ea7Spatrick return Size <= 512U;
1515a0747c9fSpatrick else if (hasFeatureEnabled(FeatureMap, "avx"))
1516ec727ea7Spatrick // YMM0 can be used if target supports AVX.
1517ec727ea7Spatrick return Size <= 256U;
1518a0747c9fSpatrick else if (hasFeatureEnabled(FeatureMap, "sse"))
1519e5dd7070Spatrick return Size <= 128U;
1520e5dd7070Spatrick return false;
1521e5dd7070Spatrick case 'i':
1522e5dd7070Spatrick case 't':
1523e5dd7070Spatrick case '2':
1524e5dd7070Spatrick // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled.
1525e5dd7070Spatrick if (SSELevel < SSE2)
1526e5dd7070Spatrick return false;
1527e5dd7070Spatrick break;
1528e5dd7070Spatrick }
1529ec727ea7Spatrick break;
1530e5dd7070Spatrick case 'v':
1531e5dd7070Spatrick case 'x':
1532a0747c9fSpatrick if (hasFeatureEnabled(FeatureMap, "avx512f"))
1533e5dd7070Spatrick // 512-bit zmm registers can be used if target supports AVX512F.
1534e5dd7070Spatrick return Size <= 512U;
1535a0747c9fSpatrick else if (hasFeatureEnabled(FeatureMap, "avx"))
1536e5dd7070Spatrick // 256-bit ymm registers can be used if target supports AVX.
1537e5dd7070Spatrick return Size <= 256U;
1538e5dd7070Spatrick return Size <= 128U;
1539e5dd7070Spatrick
1540e5dd7070Spatrick }
1541e5dd7070Spatrick
1542e5dd7070Spatrick return true;
1543e5dd7070Spatrick }
1544e5dd7070Spatrick
convertConstraint(const char * & Constraint) const1545e5dd7070Spatrick std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
1546e5dd7070Spatrick switch (*Constraint) {
1547e5dd7070Spatrick case '@':
1548e5dd7070Spatrick if (auto Len = matchAsmCCConstraint(Constraint)) {
1549e5dd7070Spatrick std::string Converted = "{" + std::string(Constraint, Len) + "}";
1550e5dd7070Spatrick Constraint += Len - 1;
1551e5dd7070Spatrick return Converted;
1552e5dd7070Spatrick }
1553e5dd7070Spatrick return std::string(1, *Constraint);
1554e5dd7070Spatrick case 'a':
1555e5dd7070Spatrick return std::string("{ax}");
1556e5dd7070Spatrick case 'b':
1557e5dd7070Spatrick return std::string("{bx}");
1558e5dd7070Spatrick case 'c':
1559e5dd7070Spatrick return std::string("{cx}");
1560e5dd7070Spatrick case 'd':
1561e5dd7070Spatrick return std::string("{dx}");
1562e5dd7070Spatrick case 'S':
1563e5dd7070Spatrick return std::string("{si}");
1564e5dd7070Spatrick case 'D':
1565e5dd7070Spatrick return std::string("{di}");
1566*7a9b00ceSrobert case 'p': // Keep 'p' constraint (address).
1567*7a9b00ceSrobert return std::string("p");
1568e5dd7070Spatrick case 't': // top of floating point stack.
1569e5dd7070Spatrick return std::string("{st}");
1570e5dd7070Spatrick case 'u': // second from top of floating point stack.
1571e5dd7070Spatrick return std::string("{st(1)}"); // second from top of floating point stack.
1572e5dd7070Spatrick case 'Y':
1573e5dd7070Spatrick switch (Constraint[1]) {
1574e5dd7070Spatrick default:
1575e5dd7070Spatrick // Break from inner switch and fall through (copy single char),
1576e5dd7070Spatrick // continue parsing after copying the current constraint into
1577e5dd7070Spatrick // the return string.
1578e5dd7070Spatrick break;
1579e5dd7070Spatrick case 'k':
1580e5dd7070Spatrick case 'm':
1581e5dd7070Spatrick case 'i':
1582e5dd7070Spatrick case 't':
1583e5dd7070Spatrick case 'z':
1584e5dd7070Spatrick case '2':
1585e5dd7070Spatrick // "^" hints llvm that this is a 2 letter constraint.
1586e5dd7070Spatrick // "Constraint++" is used to promote the string iterator
1587e5dd7070Spatrick // to the next constraint.
1588e5dd7070Spatrick return std::string("^") + std::string(Constraint++, 2);
1589e5dd7070Spatrick }
1590*7a9b00ceSrobert [[fallthrough]];
1591e5dd7070Spatrick default:
1592e5dd7070Spatrick return std::string(1, *Constraint);
1593e5dd7070Spatrick }
1594e5dd7070Spatrick }
1595e5dd7070Spatrick
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const1596e5dd7070Spatrick void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
1597ec727ea7Spatrick bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
1598ec727ea7Spatrick llvm::X86::fillValidCPUArchList(Values, Only64Bit);
1599e5dd7070Spatrick }
1600e5dd7070Spatrick
fillValidTuneCPUList(SmallVectorImpl<StringRef> & Values) const1601a0747c9fSpatrick void X86TargetInfo::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const {
1602a0747c9fSpatrick llvm::X86::fillValidTuneCPUList(Values);
1603a0747c9fSpatrick }
1604a0747c9fSpatrick
getGCCRegNames() const1605e5dd7070Spatrick ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {
1606*7a9b00ceSrobert return llvm::ArrayRef(GCCRegNames);
1607e5dd7070Spatrick }
1608e5dd7070Spatrick
getGCCAddlRegNames() const1609e5dd7070Spatrick ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
1610*7a9b00ceSrobert return llvm::ArrayRef(AddlRegNames);
1611e5dd7070Spatrick }
1612e5dd7070Spatrick
getTargetBuiltins() const1613e5dd7070Spatrick ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
1614*7a9b00ceSrobert return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
1615e5dd7070Spatrick Builtin::FirstTSBuiltin + 1);
1616e5dd7070Spatrick }
1617e5dd7070Spatrick
getTargetBuiltins() const1618e5dd7070Spatrick ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
1619*7a9b00ceSrobert return llvm::ArrayRef(BuiltinInfoX86,
1620e5dd7070Spatrick X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
1621e5dd7070Spatrick }
1622