[lldb] Fix "exact match" debug_names type queries (#118465)
[llvm-project.git] / clang / lib / Basic / Targets / X86.h
blob3ed36c8fa724b5e6ee0fd6187c65671fae28d89c
1 //===--- X86.h - Declare X86 target feature support -------------*- C++ -*-===//
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 declares X86 TargetInfo objects.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
16 #include "OSTargets.h"
17 #include "clang/Basic/BitmaskEnum.h"
18 #include "clang/Basic/TargetInfo.h"
19 #include "clang/Basic/TargetOptions.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/TargetParser/Triple.h"
22 #include "llvm/TargetParser/X86TargetParser.h"
23 #include <optional>
25 namespace clang {
26 namespace targets {
28 static const unsigned X86AddrSpaceMap[] = {
29 0, // Default
30 0, // opencl_global
31 0, // opencl_local
32 0, // opencl_constant
33 0, // opencl_private
34 0, // opencl_generic
35 0, // opencl_global_device
36 0, // opencl_global_host
37 0, // cuda_device
38 0, // cuda_constant
39 0, // cuda_shared
40 0, // sycl_global
41 0, // sycl_global_device
42 0, // sycl_global_host
43 0, // sycl_local
44 0, // sycl_private
45 270, // ptr32_sptr
46 271, // ptr32_uptr
47 272, // ptr64
48 0, // hlsl_groupshared
49 // Wasm address space values for this target are dummy values,
50 // as it is only enabled for Wasm targets.
51 20, // wasm_funcref
54 // X86 target abstract base class; x86-32 and x86-64 are very close, so
55 // most of the implementation can be shared.
56 class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
58 enum X86SSEEnum {
59 NoSSE,
60 SSE1,
61 SSE2,
62 SSE3,
63 SSSE3,
64 SSE41,
65 SSE42,
66 AVX,
67 AVX2,
68 AVX512F
69 } SSELevel = NoSSE;
70 bool HasMMX = false;
71 enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;
72 enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
74 bool HasAES = false;
75 bool HasVAES = false;
76 bool HasPCLMUL = false;
77 bool HasVPCLMULQDQ = false;
78 bool HasGFNI = false;
79 bool HasLZCNT = false;
80 bool HasRDRND = false;
81 bool HasFSGSBASE = false;
82 bool HasBMI = false;
83 bool HasBMI2 = false;
84 bool HasPOPCNT = false;
85 bool HasRTM = false;
86 bool HasPRFCHW = false;
87 bool HasRDSEED = false;
88 bool HasADX = false;
89 bool HasTBM = false;
90 bool HasLWP = false;
91 bool HasFMA = false;
92 bool HasF16C = false;
93 bool HasAVX10_1 = false;
94 bool HasAVX10_1_512 = false;
95 bool HasAVX10_2 = false;
96 bool HasAVX10_2_512 = false;
97 bool HasEVEX512 = false;
98 bool HasAVX512CD = false;
99 bool HasAVX512VPOPCNTDQ = false;
100 bool HasAVX512VNNI = false;
101 bool HasAVX512FP16 = false;
102 bool HasAVX512BF16 = false;
103 bool HasAVX512DQ = false;
104 bool HasAVX512BITALG = false;
105 bool HasAVX512BW = false;
106 bool HasAVX512VL = false;
107 bool HasAVX512VBMI = false;
108 bool HasAVX512VBMI2 = false;
109 bool HasAVXIFMA = false;
110 bool HasAVX512IFMA = false;
111 bool HasAVX512VP2INTERSECT = false;
112 bool HasSHA = false;
113 bool HasSHA512 = false;
114 bool HasSHSTK = false;
115 bool HasSM3 = false;
116 bool HasSGX = false;
117 bool HasSM4 = false;
118 bool HasCX8 = false;
119 bool HasCX16 = false;
120 bool HasFXSR = false;
121 bool HasXSAVE = false;
122 bool HasXSAVEOPT = false;
123 bool HasXSAVEC = false;
124 bool HasXSAVES = false;
125 bool HasMWAITX = false;
126 bool HasCLZERO = false;
127 bool HasCLDEMOTE = false;
128 bool HasPCONFIG = false;
129 bool HasPKU = false;
130 bool HasCLFLUSHOPT = false;
131 bool HasCLWB = false;
132 bool HasMOVBE = false;
133 bool HasMOVRS = false;
134 bool HasPREFETCHI = false;
135 bool HasRDPID = false;
136 bool HasRDPRU = false;
137 bool HasRetpolineExternalThunk = false;
138 bool HasLAHFSAHF = false;
139 bool HasWBNOINVD = false;
140 bool HasWAITPKG = false;
141 bool HasMOVDIRI = false;
142 bool HasMOVDIR64B = false;
143 bool HasPTWRITE = false;
144 bool HasINVPCID = false;
145 bool HasENQCMD = false;
146 bool HasAVXVNNIINT16 = false;
147 bool HasAMXFP16 = false;
148 bool HasCMPCCXADD = false;
149 bool HasRAOINT = false;
150 bool HasAVXVNNIINT8 = false;
151 bool HasAVXNECONVERT = false;
152 bool HasKL = false; // For key locker
153 bool HasWIDEKL = false; // For wide key locker
154 bool HasHRESET = false;
155 bool HasAVXVNNI = false;
156 bool HasAMXTILE = false;
157 bool HasAMXINT8 = false;
158 bool HasAMXBF16 = false;
159 bool HasAMXCOMPLEX = false;
160 bool HasAMXFP8 = false;
161 bool HasAMXMOVRS = false;
162 bool HasAMXTRANSPOSE = false;
163 bool HasAMXAVX512 = false;
164 bool HasAMXTF32 = false;
165 bool HasSERIALIZE = false;
166 bool HasTSXLDTRK = false;
167 bool HasUSERMSR = false;
168 bool HasUINTR = false;
169 bool HasCRC32 = false;
170 bool HasX87 = false;
171 bool HasEGPR = false;
172 bool HasPush2Pop2 = false;
173 bool HasPPX = false;
174 bool HasNDD = false;
175 bool HasCCMP = false;
176 bool HasNF = false;
177 bool HasCF = false;
178 bool HasZU = false;
179 bool HasInlineAsmUseGPR32 = false;
180 bool HasBranchHint = false;
182 protected:
183 llvm::X86::CPUKind CPU = llvm::X86::CK_None;
185 enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
187 public:
188 X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
189 : TargetInfo(Triple) {
190 BFloat16Width = BFloat16Align = 16;
191 BFloat16Format = &llvm::APFloat::BFloat();
192 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
193 AddrSpaceMap = &X86AddrSpaceMap;
194 HasStrictFP = true;
195 HasUnalignedAccess = true;
197 bool IsWinCOFF =
198 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
199 if (IsWinCOFF)
200 MaxVectorAlign = MaxTLSAlign = 8192u * getCharWidth();
203 const char *getLongDoubleMangling() const override {
204 return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
207 LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
208 // X87 evaluates with 80 bits "long double" precision.
209 return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended
210 : LangOptions::FPEvalMethodKind::FEM_Source;
213 // EvalMethod `source` is not supported for targets with `NoSSE` feature.
214 bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; }
216 ArrayRef<const char *> getGCCRegNames() const override;
218 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
219 return {};
222 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
224 bool isSPRegName(StringRef RegName) const override {
225 return RegName == "esp" || RegName == "rsp";
228 bool supportsCpuSupports() const override { return true; }
229 bool supportsCpuIs() const override { return true; }
230 bool supportsCpuInit() const override { return true; }
232 bool validateCpuSupports(StringRef FeatureStr) const override;
234 bool validateCpuIs(StringRef FeatureStr) const override;
236 bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
238 char CPUSpecificManglingCharacter(StringRef Name) const override;
240 void getCPUSpecificCPUDispatchFeatures(
241 StringRef Name,
242 llvm::SmallVectorImpl<StringRef> &Features) const override;
244 std::optional<unsigned> getCPUCacheLineSize() const override;
246 bool validateAsmConstraint(const char *&Name,
247 TargetInfo::ConstraintInfo &info) const override;
249 bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
250 bool &HasSizeMismatch) const override {
251 // esp and ebp are the only 32-bit registers the x86 backend can currently
252 // handle.
253 if (RegName == "esp" || RegName == "ebp") {
254 // Check that the register size is 32-bit.
255 HasSizeMismatch = RegSize != 32;
256 return true;
259 return false;
262 bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
263 StringRef Constraint, unsigned Size) const override;
265 bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
266 StringRef Constraint, unsigned Size) const override;
268 bool
269 checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
270 if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
271 return true;
272 return TargetInfo::checkCFProtectionReturnSupported(Diags);
275 bool
276 checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
277 if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
278 return true;
279 return TargetInfo::checkCFProtectionBranchSupported(Diags);
282 virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
283 StringRef Constraint, unsigned Size) const;
285 std::string convertConstraint(const char *&Constraint) const override;
286 std::string_view getClobbers() const override {
287 return "~{dirflag},~{fpsr},~{flags}";
290 StringRef getConstraintRegister(StringRef Constraint,
291 StringRef Expression) const override {
292 StringRef::iterator I, E;
293 for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
294 if (isalpha(*I) || *I == '@')
295 break;
297 if (I == E)
298 return "";
299 switch (*I) {
300 // For the register constraints, return the matching register name
301 case 'a':
302 return "ax";
303 case 'b':
304 return "bx";
305 case 'c':
306 return "cx";
307 case 'd':
308 return "dx";
309 case 'S':
310 return "si";
311 case 'D':
312 return "di";
313 // In case the constraint is 'r' we need to return Expression
314 case 'r':
315 return Expression;
316 // Double letters Y<x> constraints
317 case 'Y':
318 if ((++I != E) && ((*I == '0') || (*I == 'z')))
319 return "xmm0";
320 break;
321 default:
322 break;
324 return "";
327 bool useFP16ConversionIntrinsics() const override {
328 return false;
331 void getTargetDefines(const LangOptions &Opts,
332 MacroBuilder &Builder) const override;
334 void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
335 bool Enabled) const final;
337 bool
338 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
339 StringRef CPU,
340 const std::vector<std::string> &FeaturesVec) const override;
342 bool isValidFeatureName(StringRef Name) const override;
344 bool hasFeature(StringRef Feature) const final;
346 bool handleTargetFeatures(std::vector<std::string> &Features,
347 DiagnosticsEngine &Diags) override;
349 StringRef getABI() const override {
350 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
351 return "avx512";
352 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
353 return "avx";
354 if (getTriple().getArch() == llvm::Triple::x86 && !HasMMX)
355 return "no-mmx";
356 return "";
359 bool supportsTargetAttributeTune() const override {
360 return true;
363 bool isValidCPUName(StringRef Name) const override {
364 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
365 return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None;
368 bool isValidTuneCPUName(StringRef Name) const override {
369 if (Name == "generic")
370 return true;
372 // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
373 // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
374 // since mtune was ignored by clang for so long.
375 return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None;
378 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
379 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
381 bool setCPU(const std::string &Name) override {
382 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
383 CPU = llvm::X86::parseArchX86(Name, Only64Bit);
384 return CPU != llvm::X86::CK_None;
387 unsigned getFMVPriority(ArrayRef<StringRef> Features) const override;
389 bool setFPMath(StringRef Name) override;
391 bool supportsExtendIntArgs() const override {
392 return getTriple().getArch() != llvm::Triple::x86;
395 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
396 // Most of the non-ARM calling conventions are i386 conventions.
397 switch (CC) {
398 case CC_X86ThisCall:
399 case CC_X86FastCall:
400 case CC_X86StdCall:
401 case CC_X86VectorCall:
402 case CC_X86RegCall:
403 case CC_C:
404 case CC_PreserveMost:
405 case CC_Swift:
406 case CC_X86Pascal:
407 case CC_IntelOclBicc:
408 case CC_OpenCLKernel:
409 return CCCR_OK;
410 case CC_SwiftAsync:
411 return CCCR_Error;
412 default:
413 return CCCR_Warning;
417 bool checkArithmeticFenceSupported() const override { return true; }
419 CallingConv getDefaultCallingConv() const override {
420 return CC_C;
423 bool hasSjLjLowering() const override { return true; }
425 void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
427 uint64_t getPointerWidthV(LangAS AS) const override {
428 unsigned TargetAddrSpace = getTargetAddressSpace(AS);
429 if (TargetAddrSpace == ptr32_sptr || TargetAddrSpace == ptr32_uptr)
430 return 32;
431 if (TargetAddrSpace == ptr64)
432 return 64;
433 return PointerWidth;
436 uint64_t getPointerAlignV(LangAS AddrSpace) const override {
437 return getPointerWidthV(AddrSpace);
442 // X86-32 generic target
443 class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {
444 public:
445 X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
446 : X86TargetInfo(Triple, Opts) {
447 DoubleAlign = LongLongAlign = 32;
448 LongDoubleWidth = 96;
449 LongDoubleAlign = 32;
450 SuitableAlign = 128;
451 resetDataLayout(Triple.isOSBinFormatMachO()
452 ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
453 "128-f64:32:64-f80:32-n8:16:32-S128"
454 : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
455 "128-f64:32:64-f80:32-n8:16:32-S128",
456 Triple.isOSBinFormatMachO() ? "_" : "");
457 SizeType = UnsignedInt;
458 PtrDiffType = SignedInt;
459 IntPtrType = SignedInt;
460 RegParmMax = 3;
462 // Use fpret for all types.
463 RealTypeUsesObjCFPRetMask =
464 (unsigned)(FloatModeKind::Float | FloatModeKind::Double |
465 FloatModeKind::LongDouble);
467 // x86-32 has atomics up to 8 bytes
468 MaxAtomicPromoteWidth = 64;
469 MaxAtomicInlineWidth = 32;
472 BuiltinVaListKind getBuiltinVaListKind() const override {
473 return TargetInfo::CharPtrBuiltinVaList;
476 int getEHDataRegisterNumber(unsigned RegNo) const override {
477 if (RegNo == 0)
478 return 0;
479 if (RegNo == 1)
480 return 2;
481 return -1;
484 bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
485 StringRef Constraint, unsigned Size) const override {
486 switch (Constraint[0]) {
487 default:
488 break;
489 case 'R':
490 case 'q':
491 case 'Q':
492 case 'a':
493 case 'b':
494 case 'c':
495 case 'd':
496 case 'S':
497 case 'D':
498 return Size <= 32;
499 case 'A':
500 return Size <= 64;
503 return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);
506 void setMaxAtomicWidth() override {
507 if (hasFeature("cx8"))
508 MaxAtomicInlineWidth = 64;
511 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
513 bool hasBitIntType() const override { return true; }
514 size_t getMaxBitIntWidth() const override {
515 return llvm::IntegerType::MAX_INT_BITS;
519 class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
520 : public NetBSDTargetInfo<X86_32TargetInfo> {
521 public:
522 NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
523 : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
526 class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
527 : public OpenBSDTargetInfo<X86_32TargetInfo> {
528 public:
529 OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
530 : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
531 SizeType = UnsignedLong;
532 IntPtrType = SignedLong;
533 PtrDiffType = SignedLong;
537 class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
538 : public DarwinTargetInfo<X86_32TargetInfo> {
539 public:
540 DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
541 : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
542 LongDoubleWidth = 128;
543 LongDoubleAlign = 128;
544 SuitableAlign = 128;
545 MaxVectorAlign = 256;
546 // The watchOS simulator uses the builtin bool type for Objective-C.
547 llvm::Triple T = llvm::Triple(Triple);
548 if (T.isWatchOS())
549 UseSignedCharForObjCBool = false;
550 SizeType = UnsignedLong;
551 IntPtrType = SignedLong;
552 resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-"
553 "f64:32:64-f80:128-n8:16:32-S128",
554 "_");
555 HasAlignMac68kSupport = true;
558 bool handleTargetFeatures(std::vector<std::string> &Features,
559 DiagnosticsEngine &Diags) override {
560 if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
561 Diags))
562 return false;
563 // We now know the features we have: we can decide how to align vectors.
564 MaxVectorAlign =
565 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
566 return true;
570 // x86-32 Windows target
571 class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
572 : public WindowsTargetInfo<X86_32TargetInfo> {
573 public:
574 WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
575 : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
576 DoubleAlign = LongLongAlign = 64;
577 bool IsWinCOFF =
578 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
579 bool IsMSVC = getTriple().isWindowsMSVCEnvironment();
580 std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e";
581 Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-";
582 Layout += IsMSVC ? "f80:128" : "f80:32";
583 Layout += "-n8:16:32-a:0:32-S32";
584 resetDataLayout(Layout, IsWinCOFF ? "_" : "");
588 // x86-32 Windows Visual Studio target
589 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
590 : public WindowsX86_32TargetInfo {
591 public:
592 MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
593 const TargetOptions &Opts)
594 : WindowsX86_32TargetInfo(Triple, Opts) {
595 LongDoubleWidth = LongDoubleAlign = 64;
596 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
599 void getTargetDefines(const LangOptions &Opts,
600 MacroBuilder &Builder) const override {
601 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
602 // The value of the following reflects processor type.
603 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
604 // We lost the original triple, so we use the default.
605 Builder.defineMacro("_M_IX86", "600");
609 // x86-32 MinGW target
610 class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
611 : public WindowsX86_32TargetInfo {
612 public:
613 MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
614 : WindowsX86_32TargetInfo(Triple, Opts) {
615 HasFloat128 = true;
618 void getTargetDefines(const LangOptions &Opts,
619 MacroBuilder &Builder) const override {
620 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
621 Builder.defineMacro("_X86_");
625 // x86-32 Cygwin target
626 class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {
627 public:
628 CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
629 : X86_32TargetInfo(Triple, Opts) {
630 this->WCharType = TargetInfo::UnsignedShort;
631 DoubleAlign = LongLongAlign = 64;
632 resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"
633 "i128:128-f80:32-n8:16:32-a:0:32-S32",
634 "_");
637 void getTargetDefines(const LangOptions &Opts,
638 MacroBuilder &Builder) const override {
639 X86_32TargetInfo::getTargetDefines(Opts, Builder);
640 Builder.defineMacro("_X86_");
641 Builder.defineMacro("__CYGWIN__");
642 Builder.defineMacro("__CYGWIN32__");
643 addCygMingDefines(Opts, Builder);
644 DefineStd(Builder, "unix", Opts);
645 if (Opts.CPlusPlus)
646 Builder.defineMacro("_GNU_SOURCE");
650 // x86-32 Haiku target
651 class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
652 : public HaikuTargetInfo<X86_32TargetInfo> {
653 public:
654 HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
655 : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
657 void getTargetDefines(const LangOptions &Opts,
658 MacroBuilder &Builder) const override {
659 HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
660 Builder.defineMacro("__INTEL__");
664 // X86-32 MCU target
665 class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {
666 public:
667 MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
668 : X86_32TargetInfo(Triple, Opts) {
669 LongDoubleWidth = 64;
670 DefaultAlignForAttributeAligned = 32;
671 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
672 resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-"
673 "f64:32-f128:32-n8:16:32-a:0:32-S32");
674 WIntType = UnsignedInt;
677 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
678 // On MCU we support only C calling convention.
679 return CC == CC_C ? CCCR_OK : CCCR_Warning;
682 void getTargetDefines(const LangOptions &Opts,
683 MacroBuilder &Builder) const override {
684 X86_32TargetInfo::getTargetDefines(Opts, Builder);
685 Builder.defineMacro("__iamcu");
686 Builder.defineMacro("__iamcu__");
689 bool allowsLargerPreferedTypeAlignment() const override { return false; }
692 // x86-32 RTEMS target
693 class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {
694 public:
695 RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
696 : X86_32TargetInfo(Triple, Opts) {
697 SizeType = UnsignedLong;
698 IntPtrType = SignedLong;
699 PtrDiffType = SignedLong;
702 void getTargetDefines(const LangOptions &Opts,
703 MacroBuilder &Builder) const override {
704 X86_32TargetInfo::getTargetDefines(Opts, Builder);
705 Builder.defineMacro("__INTEL__");
706 Builder.defineMacro("__rtems__");
710 // x86-64 generic target
711 class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
712 public:
713 X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
714 : X86TargetInfo(Triple, Opts) {
715 const bool IsX32 = getTriple().isX32();
716 bool IsWinCOFF =
717 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
718 LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
719 LongDoubleWidth = 128;
720 LongDoubleAlign = 128;
721 LargeArrayMinWidth = 128;
722 LargeArrayAlign = 128;
723 SuitableAlign = 128;
724 SizeType = IsX32 ? UnsignedInt : UnsignedLong;
725 PtrDiffType = IsX32 ? SignedInt : SignedLong;
726 IntPtrType = IsX32 ? SignedInt : SignedLong;
727 IntMaxType = IsX32 ? SignedLongLong : SignedLong;
728 Int64Type = IsX32 ? SignedLongLong : SignedLong;
729 RegParmMax = 6;
731 // Pointers are 32-bit in x32.
732 resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
733 "i64:64-i128:128-f80:128-n8:16:32:64-S128"
734 : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:"
735 "64-i128:128-f80:128-n8:16:32:64-S128"
736 : "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:"
737 "64-i128:128-f80:128-n8:16:32:64-S128");
739 // Use fpret only for long double.
740 RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;
742 // Use fp2ret for _Complex long double.
743 ComplexLongDoubleUsesFP2Ret = true;
745 // Make __builtin_ms_va_list available.
746 HasBuiltinMSVaList = true;
748 // x86-64 has atomics up to 16 bytes.
749 MaxAtomicPromoteWidth = 128;
750 MaxAtomicInlineWidth = 64;
753 BuiltinVaListKind getBuiltinVaListKind() const override {
754 return TargetInfo::X86_64ABIBuiltinVaList;
757 int getEHDataRegisterNumber(unsigned RegNo) const override {
758 if (RegNo == 0)
759 return 0;
760 if (RegNo == 1)
761 return 1;
762 return -1;
765 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
766 switch (CC) {
767 case CC_C:
768 case CC_Swift:
769 case CC_SwiftAsync:
770 case CC_X86VectorCall:
771 case CC_IntelOclBicc:
772 case CC_Win64:
773 case CC_PreserveMost:
774 case CC_PreserveAll:
775 case CC_PreserveNone:
776 case CC_X86RegCall:
777 case CC_OpenCLKernel:
778 return CCCR_OK;
779 default:
780 return CCCR_Warning;
784 CallingConv getDefaultCallingConv() const override {
785 return CC_C;
788 // for x32 we need it here explicitly
789 bool hasInt128Type() const override { return true; }
791 unsigned getUnwindWordWidth() const override { return 64; }
793 unsigned getRegisterWidth() const override { return 64; }
795 bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
796 bool &HasSizeMismatch) const override {
797 // rsp and rbp are the only 64-bit registers the x86 backend can currently
798 // handle.
799 if (RegName == "rsp" || RegName == "rbp") {
800 // Check that the register size is 64-bit.
801 HasSizeMismatch = RegSize != 64;
802 return true;
805 // Check if the register is a 32-bit register the backend can handle.
806 return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
807 HasSizeMismatch);
810 void setMaxAtomicWidth() override {
811 if (hasFeature("cx16"))
812 MaxAtomicInlineWidth = 128;
815 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
817 bool hasBitIntType() const override { return true; }
818 size_t getMaxBitIntWidth() const override {
819 return llvm::IntegerType::MAX_INT_BITS;
823 // x86-64 UEFI target
824 class LLVM_LIBRARY_VISIBILITY UEFIX86_64TargetInfo
825 : public UEFITargetInfo<X86_64TargetInfo> {
826 public:
827 UEFIX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
828 : UEFITargetInfo<X86_64TargetInfo>(Triple, Opts) {
829 this->TheCXXABI.set(TargetCXXABI::Microsoft);
830 this->MaxTLSAlign = 8192u * this->getCharWidth();
831 this->resetDataLayout("e-m:w-p270:32:32-p271:32:32-p272:64:64-"
832 "i64:64-i128:128-f80:128-n8:16:32:64-S128");
835 void getTargetDefines(const LangOptions &Opts,
836 MacroBuilder &Builder) const override {
837 getOSDefines(Opts, X86TargetInfo::getTriple(), Builder);
840 BuiltinVaListKind getBuiltinVaListKind() const override {
841 return TargetInfo::CharPtrBuiltinVaList;
844 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
845 switch (CC) {
846 case CC_C:
847 case CC_Win64:
848 return CCCR_OK;
849 default:
850 return CCCR_Warning;
854 TargetInfo::CallingConvKind
855 getCallingConvKind(bool ClangABICompat4) const override {
856 return CCK_MicrosoftWin64;
860 // x86-64 Windows target
861 class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
862 : public WindowsTargetInfo<X86_64TargetInfo> {
863 public:
864 WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
865 : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
866 LongWidth = LongAlign = 32;
867 DoubleAlign = LongLongAlign = 64;
868 IntMaxType = SignedLongLong;
869 Int64Type = SignedLongLong;
870 SizeType = UnsignedLongLong;
871 PtrDiffType = SignedLongLong;
872 IntPtrType = SignedLongLong;
875 BuiltinVaListKind getBuiltinVaListKind() const override {
876 return TargetInfo::CharPtrBuiltinVaList;
879 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
880 switch (CC) {
881 case CC_X86StdCall:
882 case CC_X86ThisCall:
883 case CC_X86FastCall:
884 return CCCR_Ignore;
885 case CC_C:
886 case CC_X86VectorCall:
887 case CC_IntelOclBicc:
888 case CC_PreserveMost:
889 case CC_PreserveAll:
890 case CC_PreserveNone:
891 case CC_X86_64SysV:
892 case CC_Swift:
893 case CC_SwiftAsync:
894 case CC_X86RegCall:
895 case CC_OpenCLKernel:
896 return CCCR_OK;
897 default:
898 return CCCR_Warning;
903 // x86-64 Windows Visual Studio target
904 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
905 : public WindowsX86_64TargetInfo {
906 public:
907 MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
908 const TargetOptions &Opts)
909 : WindowsX86_64TargetInfo(Triple, Opts) {
910 LongDoubleWidth = LongDoubleAlign = 64;
911 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
914 void getTargetDefines(const LangOptions &Opts,
915 MacroBuilder &Builder) const override {
916 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
917 Builder.defineMacro("_M_X64", "100");
918 Builder.defineMacro("_M_AMD64", "100");
921 TargetInfo::CallingConvKind
922 getCallingConvKind(bool ClangABICompat4) const override {
923 return CCK_MicrosoftWin64;
927 // x86-64 MinGW target
928 class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
929 : public WindowsX86_64TargetInfo {
930 public:
931 MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
932 : WindowsX86_64TargetInfo(Triple, Opts) {
933 // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
934 // with x86 FP ops. Weird.
935 LongDoubleWidth = LongDoubleAlign = 128;
936 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
937 HasFloat128 = true;
941 // x86-64 Cygwin target
942 class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {
943 public:
944 CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
945 : X86_64TargetInfo(Triple, Opts) {
946 this->WCharType = TargetInfo::UnsignedShort;
947 TLSSupported = false;
950 void getTargetDefines(const LangOptions &Opts,
951 MacroBuilder &Builder) const override {
952 X86_64TargetInfo::getTargetDefines(Opts, Builder);
953 Builder.defineMacro("__x86_64__");
954 Builder.defineMacro("__CYGWIN__");
955 Builder.defineMacro("__CYGWIN64__");
956 addCygMingDefines(Opts, Builder);
957 DefineStd(Builder, "unix", Opts);
958 if (Opts.CPlusPlus)
959 Builder.defineMacro("_GNU_SOURCE");
963 class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
964 : public DarwinTargetInfo<X86_64TargetInfo> {
965 public:
966 DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
967 : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
968 Int64Type = SignedLongLong;
969 // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
970 llvm::Triple T = llvm::Triple(Triple);
971 if (T.isiOS())
972 UseSignedCharForObjCBool = false;
973 resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
974 "f80:128-n8:16:32:64-S128",
975 "_");
978 bool handleTargetFeatures(std::vector<std::string> &Features,
979 DiagnosticsEngine &Diags) override {
980 if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
981 Diags))
982 return false;
983 // We now know the features we have: we can decide how to align vectors.
984 MaxVectorAlign =
985 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
986 return true;
990 class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
991 : public OpenBSDTargetInfo<X86_64TargetInfo> {
992 public:
993 OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
994 : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
995 IntMaxType = SignedLongLong;
996 Int64Type = SignedLongLong;
1000 // x86_32 Android target
1001 class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
1002 : public LinuxTargetInfo<X86_32TargetInfo> {
1003 public:
1004 AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1005 : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
1006 SuitableAlign = 32;
1007 LongDoubleWidth = 64;
1008 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1012 // x86_64 Android target
1013 class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
1014 : public LinuxTargetInfo<X86_64TargetInfo> {
1015 public:
1016 AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1017 : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
1018 LongDoubleFormat = &llvm::APFloat::IEEEquad();
1022 // x86_32 OHOS target
1023 class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo
1024 : public OHOSTargetInfo<X86_32TargetInfo> {
1025 public:
1026 OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1027 : OHOSTargetInfo<X86_32TargetInfo>(Triple, Opts) {
1028 SuitableAlign = 32;
1029 LongDoubleWidth = 64;
1030 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1034 // x86_64 OHOS target
1035 class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo
1036 : public OHOSTargetInfo<X86_64TargetInfo> {
1037 public:
1038 OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1039 : OHOSTargetInfo<X86_64TargetInfo>(Triple, Opts) {
1040 LongDoubleFormat = &llvm::APFloat::IEEEquad();
1043 } // namespace targets
1044 } // namespace clang
1045 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H