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