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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang/lib/Basic/Targets/X86.cpp