[clang-format] Fix a bug in aligning comments above PPDirective (#72791)
[llvm-project.git] / clang / lib / Basic / Targets / X86.h
blob99a64501d263ce4b330287a09cbf94c40285123b
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 enum MMX3DNowEnum {
71 NoMMX3DNow,
72 MMX,
73 AMD3DNow,
74 AMD3DNowAthlon
75 } MMX3DNowLevel = NoMMX3DNow;
76 enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;
77 enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
79 bool HasAES = false;
80 bool HasVAES = false;
81 bool HasPCLMUL = false;
82 bool HasVPCLMULQDQ = false;
83 bool HasGFNI = false;
84 bool HasLZCNT = false;
85 bool HasRDRND = false;
86 bool HasFSGSBASE = false;
87 bool HasBMI = false;
88 bool HasBMI2 = false;
89 bool HasPOPCNT = false;
90 bool HasRTM = false;
91 bool HasPRFCHW = false;
92 bool HasRDSEED = false;
93 bool HasADX = false;
94 bool HasTBM = false;
95 bool HasLWP = false;
96 bool HasFMA = false;
97 bool HasF16C = false;
98 bool HasAVX10_1 = false;
99 bool HasAVX10_1_512 = false;
100 bool HasEVEX512 = false;
101 bool HasAVX512CD = false;
102 bool HasAVX512VPOPCNTDQ = false;
103 bool HasAVX512VNNI = false;
104 bool HasAVX512FP16 = false;
105 bool HasAVX512BF16 = false;
106 bool HasAVX512ER = false;
107 bool HasAVX512PF = false;
108 bool HasAVX512DQ = false;
109 bool HasAVX512BITALG = false;
110 bool HasAVX512BW = false;
111 bool HasAVX512VL = false;
112 bool HasAVX512VBMI = false;
113 bool HasAVX512VBMI2 = false;
114 bool HasAVXIFMA = false;
115 bool HasAVX512IFMA = false;
116 bool HasAVX512VP2INTERSECT = false;
117 bool HasSHA = false;
118 bool HasSHA512 = false;
119 bool HasSHSTK = false;
120 bool HasSM3 = false;
121 bool HasSGX = false;
122 bool HasSM4 = false;
123 bool HasCX8 = false;
124 bool HasCX16 = false;
125 bool HasFXSR = false;
126 bool HasXSAVE = false;
127 bool HasXSAVEOPT = false;
128 bool HasXSAVEC = false;
129 bool HasXSAVES = false;
130 bool HasMWAITX = false;
131 bool HasCLZERO = false;
132 bool HasCLDEMOTE = false;
133 bool HasPCONFIG = false;
134 bool HasPKU = false;
135 bool HasCLFLUSHOPT = false;
136 bool HasCLWB = false;
137 bool HasMOVBE = false;
138 bool HasPREFETCHI = false;
139 bool HasPREFETCHWT1 = false;
140 bool HasRDPID = false;
141 bool HasRDPRU = false;
142 bool HasRetpolineExternalThunk = false;
143 bool HasLAHFSAHF = false;
144 bool HasWBNOINVD = false;
145 bool HasWAITPKG = false;
146 bool HasMOVDIRI = false;
147 bool HasMOVDIR64B = false;
148 bool HasPTWRITE = false;
149 bool HasINVPCID = false;
150 bool HasENQCMD = false;
151 bool HasAVXVNNIINT16 = false;
152 bool HasAMXFP16 = false;
153 bool HasCMPCCXADD = false;
154 bool HasRAOINT = false;
155 bool HasAVXVNNIINT8 = false;
156 bool HasAVXNECONVERT = false;
157 bool HasKL = false; // For key locker
158 bool HasWIDEKL = false; // For wide key locker
159 bool HasHRESET = false;
160 bool HasAVXVNNI = false;
161 bool HasAMXTILE = false;
162 bool HasAMXINT8 = false;
163 bool HasAMXBF16 = false;
164 bool HasAMXCOMPLEX = 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;
172 protected:
173 llvm::X86::CPUKind CPU = llvm::X86::CK_None;
175 enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
177 public:
178 X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
179 : TargetInfo(Triple) {
180 BFloat16Width = BFloat16Align = 16;
181 BFloat16Format = &llvm::APFloat::BFloat();
182 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
183 AddrSpaceMap = &X86AddrSpaceMap;
184 HasStrictFP = true;
186 bool IsWinCOFF =
187 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
188 if (IsWinCOFF)
189 MaxVectorAlign = MaxTLSAlign = 8192u * getCharWidth();
192 const char *getLongDoubleMangling() const override {
193 return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
196 LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
197 // X87 evaluates with 80 bits "long double" precision.
198 return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended
199 : LangOptions::FPEvalMethodKind::FEM_Source;
202 // EvalMethod `source` is not supported for targets with `NoSSE` feature.
203 bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; }
205 ArrayRef<const char *> getGCCRegNames() const override;
207 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
208 return std::nullopt;
211 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
213 bool isSPRegName(StringRef RegName) const override {
214 return RegName.equals("esp") || RegName.equals("rsp");
217 bool validateCpuSupports(StringRef FeatureStr) const override;
219 bool validateCpuIs(StringRef FeatureStr) const override;
221 bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
223 char CPUSpecificManglingCharacter(StringRef Name) const override;
225 void getCPUSpecificCPUDispatchFeatures(
226 StringRef Name,
227 llvm::SmallVectorImpl<StringRef> &Features) const override;
229 std::optional<unsigned> getCPUCacheLineSize() const override;
231 bool validateAsmConstraint(const char *&Name,
232 TargetInfo::ConstraintInfo &info) const override;
234 bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
235 bool &HasSizeMismatch) const override {
236 // esp and ebp are the only 32-bit registers the x86 backend can currently
237 // handle.
238 if (RegName.equals("esp") || RegName.equals("ebp")) {
239 // Check that the register size is 32-bit.
240 HasSizeMismatch = RegSize != 32;
241 return true;
244 return false;
247 bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
248 StringRef Constraint, unsigned Size) const override;
250 bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
251 StringRef Constraint, unsigned Size) const override;
253 bool
254 checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
255 if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
256 return true;
257 return TargetInfo::checkCFProtectionReturnSupported(Diags);
260 bool
261 checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
262 if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
263 return true;
264 return TargetInfo::checkCFProtectionBranchSupported(Diags);
267 virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
268 StringRef Constraint, unsigned Size) const;
270 std::string convertConstraint(const char *&Constraint) const override;
271 std::string_view getClobbers() const override {
272 return "~{dirflag},~{fpsr},~{flags}";
275 StringRef getConstraintRegister(StringRef Constraint,
276 StringRef Expression) const override {
277 StringRef::iterator I, E;
278 for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
279 if (isalpha(*I) || *I == '@')
280 break;
282 if (I == E)
283 return "";
284 switch (*I) {
285 // For the register constraints, return the matching register name
286 case 'a':
287 return "ax";
288 case 'b':
289 return "bx";
290 case 'c':
291 return "cx";
292 case 'd':
293 return "dx";
294 case 'S':
295 return "si";
296 case 'D':
297 return "di";
298 // In case the constraint is 'r' we need to return Expression
299 case 'r':
300 return Expression;
301 // Double letters Y<x> constraints
302 case 'Y':
303 if ((++I != E) && ((*I == '0') || (*I == 'z')))
304 return "xmm0";
305 break;
306 default:
307 break;
309 return "";
312 bool useFP16ConversionIntrinsics() const override {
313 return false;
316 void getTargetDefines(const LangOptions &Opts,
317 MacroBuilder &Builder) const override;
319 void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
320 bool Enabled) const final;
322 bool
323 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
324 StringRef CPU,
325 const std::vector<std::string> &FeaturesVec) const override;
327 bool isValidFeatureName(StringRef Name) const override;
329 bool hasFeature(StringRef Feature) const final;
331 bool handleTargetFeatures(std::vector<std::string> &Features,
332 DiagnosticsEngine &Diags) override;
334 StringRef getABI() const override {
335 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
336 return "avx512";
337 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
338 return "avx";
339 if (getTriple().getArch() == llvm::Triple::x86 &&
340 MMX3DNowLevel == NoMMX3DNow)
341 return "no-mmx";
342 return "";
345 bool supportsTargetAttributeTune() const override {
346 return true;
349 bool isValidCPUName(StringRef Name) const override {
350 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
351 return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None;
354 bool isValidTuneCPUName(StringRef Name) const override {
355 if (Name == "generic")
356 return true;
358 // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
359 // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
360 // since mtune was ignored by clang for so long.
361 return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None;
364 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
365 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
367 bool setCPU(const std::string &Name) override {
368 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
369 CPU = llvm::X86::parseArchX86(Name, Only64Bit);
370 return CPU != llvm::X86::CK_None;
373 unsigned multiVersionSortPriority(StringRef Name) const override;
375 bool setFPMath(StringRef Name) override;
377 bool supportsExtendIntArgs() const override {
378 return getTriple().getArch() != llvm::Triple::x86;
381 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
382 // Most of the non-ARM calling conventions are i386 conventions.
383 switch (CC) {
384 case CC_X86ThisCall:
385 case CC_X86FastCall:
386 case CC_X86StdCall:
387 case CC_X86VectorCall:
388 case CC_X86RegCall:
389 case CC_C:
390 case CC_PreserveMost:
391 case CC_Swift:
392 case CC_X86Pascal:
393 case CC_IntelOclBicc:
394 case CC_OpenCLKernel:
395 return CCCR_OK;
396 case CC_SwiftAsync:
397 return CCCR_Error;
398 default:
399 return CCCR_Warning;
403 bool checkArithmeticFenceSupported() const override { return true; }
405 CallingConv getDefaultCallingConv() const override {
406 return CC_C;
409 bool hasSjLjLowering() const override { return true; }
411 void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
413 uint64_t getPointerWidthV(LangAS AS) const override {
414 unsigned TargetAddrSpace = getTargetAddressSpace(AS);
415 if (TargetAddrSpace == ptr32_sptr || TargetAddrSpace == ptr32_uptr)
416 return 32;
417 if (TargetAddrSpace == ptr64)
418 return 64;
419 return PointerWidth;
422 uint64_t getPointerAlignV(LangAS AddrSpace) const override {
423 return getPointerWidthV(AddrSpace);
428 // X86-32 generic target
429 class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {
430 public:
431 X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
432 : X86TargetInfo(Triple, Opts) {
433 DoubleAlign = LongLongAlign = 32;
434 LongDoubleWidth = 96;
435 LongDoubleAlign = 32;
436 SuitableAlign = 128;
437 resetDataLayout(Triple.isOSBinFormatMachO()
438 ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
439 "128-f64:32:64-f80:32-n8:16:32-S128"
440 : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
441 "128-f64:32:64-f80:32-n8:16:32-S128",
442 Triple.isOSBinFormatMachO() ? "_" : "");
443 SizeType = UnsignedInt;
444 PtrDiffType = SignedInt;
445 IntPtrType = SignedInt;
446 RegParmMax = 3;
448 // Use fpret for all types.
449 RealTypeUsesObjCFPRetMask =
450 (unsigned)(FloatModeKind::Float | FloatModeKind::Double |
451 FloatModeKind::LongDouble);
453 // x86-32 has atomics up to 8 bytes
454 MaxAtomicPromoteWidth = 64;
455 MaxAtomicInlineWidth = 32;
458 BuiltinVaListKind getBuiltinVaListKind() const override {
459 return TargetInfo::CharPtrBuiltinVaList;
462 int getEHDataRegisterNumber(unsigned RegNo) const override {
463 if (RegNo == 0)
464 return 0;
465 if (RegNo == 1)
466 return 2;
467 return -1;
470 bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
471 StringRef Constraint, unsigned Size) const override {
472 switch (Constraint[0]) {
473 default:
474 break;
475 case 'R':
476 case 'q':
477 case 'Q':
478 case 'a':
479 case 'b':
480 case 'c':
481 case 'd':
482 case 'S':
483 case 'D':
484 return Size <= 32;
485 case 'A':
486 return Size <= 64;
489 return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);
492 void setMaxAtomicWidth() override {
493 if (hasFeature("cx8"))
494 MaxAtomicInlineWidth = 64;
497 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
499 bool hasBitIntType() const override { return true; }
500 size_t getMaxBitIntWidth() const override {
501 return llvm::IntegerType::MAX_INT_BITS;
505 class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
506 : public NetBSDTargetInfo<X86_32TargetInfo> {
507 public:
508 NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
509 : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
511 LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
512 VersionTuple OsVersion = getTriple().getOSVersion();
513 // New NetBSD uses the default rounding mode.
514 if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0)
515 return X86_32TargetInfo::getFPEvalMethod();
516 // NetBSD before 6.99.26 defaults to "double" rounding.
517 return LangOptions::FPEvalMethodKind::FEM_Double;
521 class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
522 : public OpenBSDTargetInfo<X86_32TargetInfo> {
523 public:
524 OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
525 : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
526 SizeType = UnsignedLong;
527 IntPtrType = SignedLong;
528 PtrDiffType = SignedLong;
532 class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
533 : public DarwinTargetInfo<X86_32TargetInfo> {
534 public:
535 DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
536 : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
537 LongDoubleWidth = 128;
538 LongDoubleAlign = 128;
539 SuitableAlign = 128;
540 MaxVectorAlign = 256;
541 // The watchOS simulator uses the builtin bool type for Objective-C.
542 llvm::Triple T = llvm::Triple(Triple);
543 if (T.isWatchOS())
544 UseSignedCharForObjCBool = false;
545 SizeType = UnsignedLong;
546 IntPtrType = SignedLong;
547 resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-"
548 "f64:32:64-f80:128-n8:16:32-S128",
549 "_");
550 HasAlignMac68kSupport = true;
553 bool handleTargetFeatures(std::vector<std::string> &Features,
554 DiagnosticsEngine &Diags) override {
555 if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
556 Diags))
557 return false;
558 // We now know the features we have: we can decide how to align vectors.
559 MaxVectorAlign =
560 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
561 return true;
565 // x86-32 Windows target
566 class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
567 : public WindowsTargetInfo<X86_32TargetInfo> {
568 public:
569 WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
570 : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
571 DoubleAlign = LongLongAlign = 64;
572 bool IsWinCOFF =
573 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
574 bool IsMSVC = getTriple().isWindowsMSVCEnvironment();
575 std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e";
576 Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-";
577 Layout += IsMSVC ? "f80:128" : "f80:32";
578 Layout += "-n8:16:32-a:0:32-S32";
579 resetDataLayout(Layout, IsWinCOFF ? "_" : "");
583 // x86-32 Windows Visual Studio target
584 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
585 : public WindowsX86_32TargetInfo {
586 public:
587 MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
588 const TargetOptions &Opts)
589 : WindowsX86_32TargetInfo(Triple, Opts) {
590 LongDoubleWidth = LongDoubleAlign = 64;
591 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
594 void getTargetDefines(const LangOptions &Opts,
595 MacroBuilder &Builder) const override {
596 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
597 // The value of the following reflects processor type.
598 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
599 // We lost the original triple, so we use the default.
600 Builder.defineMacro("_M_IX86", "600");
604 // x86-32 MinGW target
605 class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
606 : public WindowsX86_32TargetInfo {
607 public:
608 MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
609 : WindowsX86_32TargetInfo(Triple, Opts) {
610 HasFloat128 = true;
613 void getTargetDefines(const LangOptions &Opts,
614 MacroBuilder &Builder) const override {
615 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
616 Builder.defineMacro("_X86_");
620 // x86-32 Cygwin target
621 class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {
622 public:
623 CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
624 : X86_32TargetInfo(Triple, Opts) {
625 this->WCharType = TargetInfo::UnsignedShort;
626 DoubleAlign = LongLongAlign = 64;
627 resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"
628 "i128:128-f80:32-n8:16:32-a:0:32-S32",
629 "_");
632 void getTargetDefines(const LangOptions &Opts,
633 MacroBuilder &Builder) const override {
634 X86_32TargetInfo::getTargetDefines(Opts, Builder);
635 Builder.defineMacro("_X86_");
636 Builder.defineMacro("__CYGWIN__");
637 Builder.defineMacro("__CYGWIN32__");
638 addCygMingDefines(Opts, Builder);
639 DefineStd(Builder, "unix", Opts);
640 if (Opts.CPlusPlus)
641 Builder.defineMacro("_GNU_SOURCE");
645 // x86-32 Haiku target
646 class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
647 : public HaikuTargetInfo<X86_32TargetInfo> {
648 public:
649 HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
650 : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
652 void getTargetDefines(const LangOptions &Opts,
653 MacroBuilder &Builder) const override {
654 HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
655 Builder.defineMacro("__INTEL__");
659 // X86-32 MCU target
660 class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {
661 public:
662 MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
663 : X86_32TargetInfo(Triple, Opts) {
664 LongDoubleWidth = 64;
665 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
666 resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-"
667 "f64:32-f128:32-n8:16:32-a:0:32-S32");
668 WIntType = UnsignedInt;
671 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
672 // On MCU we support only C calling convention.
673 return CC == CC_C ? CCCR_OK : CCCR_Warning;
676 void getTargetDefines(const LangOptions &Opts,
677 MacroBuilder &Builder) const override {
678 X86_32TargetInfo::getTargetDefines(Opts, Builder);
679 Builder.defineMacro("__iamcu");
680 Builder.defineMacro("__iamcu__");
683 bool allowsLargerPreferedTypeAlignment() const override { return false; }
686 // x86-32 RTEMS target
687 class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {
688 public:
689 RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
690 : X86_32TargetInfo(Triple, Opts) {
691 SizeType = UnsignedLong;
692 IntPtrType = SignedLong;
693 PtrDiffType = SignedLong;
696 void getTargetDefines(const LangOptions &Opts,
697 MacroBuilder &Builder) const override {
698 X86_32TargetInfo::getTargetDefines(Opts, Builder);
699 Builder.defineMacro("__INTEL__");
700 Builder.defineMacro("__rtems__");
704 // x86-64 generic target
705 class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
706 public:
707 X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
708 : X86TargetInfo(Triple, Opts) {
709 const bool IsX32 = getTriple().isX32();
710 bool IsWinCOFF =
711 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
712 LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
713 LongDoubleWidth = 128;
714 LongDoubleAlign = 128;
715 LargeArrayMinWidth = 128;
716 LargeArrayAlign = 128;
717 SuitableAlign = 128;
718 SizeType = IsX32 ? UnsignedInt : UnsignedLong;
719 PtrDiffType = IsX32 ? SignedInt : SignedLong;
720 IntPtrType = IsX32 ? SignedInt : SignedLong;
721 IntMaxType = IsX32 ? SignedLongLong : SignedLong;
722 Int64Type = IsX32 ? SignedLongLong : SignedLong;
723 RegParmMax = 6;
725 // Pointers are 32-bit in x32.
726 resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
727 "i64:64-i128:128-f80:128-n8:16:32:64-S128"
728 : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:"
729 "64-i128:128-f80:128-n8:16:32:64-S128"
730 : "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:"
731 "64-i128:128-f80:128-n8:16:32:64-S128");
733 // Use fpret only for long double.
734 RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;
736 // Use fp2ret for _Complex long double.
737 ComplexLongDoubleUsesFP2Ret = true;
739 // Make __builtin_ms_va_list available.
740 HasBuiltinMSVaList = true;
742 // x86-64 has atomics up to 16 bytes.
743 MaxAtomicPromoteWidth = 128;
744 MaxAtomicInlineWidth = 64;
747 BuiltinVaListKind getBuiltinVaListKind() const override {
748 return TargetInfo::X86_64ABIBuiltinVaList;
751 int getEHDataRegisterNumber(unsigned RegNo) const override {
752 if (RegNo == 0)
753 return 0;
754 if (RegNo == 1)
755 return 1;
756 return -1;
759 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
760 switch (CC) {
761 case CC_C:
762 case CC_Swift:
763 case CC_SwiftAsync:
764 case CC_X86VectorCall:
765 case CC_IntelOclBicc:
766 case CC_Win64:
767 case CC_PreserveMost:
768 case CC_PreserveAll:
769 case CC_X86RegCall:
770 case CC_OpenCLKernel:
771 return CCCR_OK;
772 default:
773 return CCCR_Warning;
777 CallingConv getDefaultCallingConv() const override {
778 return CC_C;
781 // for x32 we need it here explicitly
782 bool hasInt128Type() const override { return true; }
784 unsigned getUnwindWordWidth() const override { return 64; }
786 unsigned getRegisterWidth() const override { return 64; }
788 bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
789 bool &HasSizeMismatch) const override {
790 // rsp and rbp are the only 64-bit registers the x86 backend can currently
791 // handle.
792 if (RegName.equals("rsp") || RegName.equals("rbp")) {
793 // Check that the register size is 64-bit.
794 HasSizeMismatch = RegSize != 64;
795 return true;
798 // Check if the register is a 32-bit register the backend can handle.
799 return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
800 HasSizeMismatch);
803 void setMaxAtomicWidth() override {
804 if (hasFeature("cx16"))
805 MaxAtomicInlineWidth = 128;
808 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
810 bool hasBitIntType() const override { return true; }
811 size_t getMaxBitIntWidth() const override {
812 return llvm::IntegerType::MAX_INT_BITS;
816 // x86-64 Windows target
817 class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
818 : public WindowsTargetInfo<X86_64TargetInfo> {
819 public:
820 WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
821 : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
822 LongWidth = LongAlign = 32;
823 DoubleAlign = LongLongAlign = 64;
824 IntMaxType = SignedLongLong;
825 Int64Type = SignedLongLong;
826 SizeType = UnsignedLongLong;
827 PtrDiffType = SignedLongLong;
828 IntPtrType = SignedLongLong;
831 BuiltinVaListKind getBuiltinVaListKind() const override {
832 return TargetInfo::CharPtrBuiltinVaList;
835 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
836 switch (CC) {
837 case CC_X86StdCall:
838 case CC_X86ThisCall:
839 case CC_X86FastCall:
840 return CCCR_Ignore;
841 case CC_C:
842 case CC_X86VectorCall:
843 case CC_IntelOclBicc:
844 case CC_PreserveMost:
845 case CC_PreserveAll:
846 case CC_X86_64SysV:
847 case CC_Swift:
848 case CC_SwiftAsync:
849 case CC_X86RegCall:
850 case CC_OpenCLKernel:
851 return CCCR_OK;
852 default:
853 return CCCR_Warning;
858 // x86-64 Windows Visual Studio target
859 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
860 : public WindowsX86_64TargetInfo {
861 public:
862 MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
863 const TargetOptions &Opts)
864 : WindowsX86_64TargetInfo(Triple, Opts) {
865 LongDoubleWidth = LongDoubleAlign = 64;
866 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
869 void getTargetDefines(const LangOptions &Opts,
870 MacroBuilder &Builder) const override {
871 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
872 Builder.defineMacro("_M_X64", "100");
873 Builder.defineMacro("_M_AMD64", "100");
876 TargetInfo::CallingConvKind
877 getCallingConvKind(bool ClangABICompat4) const override {
878 return CCK_MicrosoftWin64;
882 // x86-64 MinGW target
883 class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
884 : public WindowsX86_64TargetInfo {
885 public:
886 MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
887 : WindowsX86_64TargetInfo(Triple, Opts) {
888 // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
889 // with x86 FP ops. Weird.
890 LongDoubleWidth = LongDoubleAlign = 128;
891 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
892 HasFloat128 = true;
896 // x86-64 Cygwin target
897 class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {
898 public:
899 CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
900 : X86_64TargetInfo(Triple, Opts) {
901 this->WCharType = TargetInfo::UnsignedShort;
902 TLSSupported = false;
905 void getTargetDefines(const LangOptions &Opts,
906 MacroBuilder &Builder) const override {
907 X86_64TargetInfo::getTargetDefines(Opts, Builder);
908 Builder.defineMacro("__x86_64__");
909 Builder.defineMacro("__CYGWIN__");
910 Builder.defineMacro("__CYGWIN64__");
911 addCygMingDefines(Opts, Builder);
912 DefineStd(Builder, "unix", Opts);
913 if (Opts.CPlusPlus)
914 Builder.defineMacro("_GNU_SOURCE");
918 class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
919 : public DarwinTargetInfo<X86_64TargetInfo> {
920 public:
921 DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
922 : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
923 Int64Type = SignedLongLong;
924 // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
925 llvm::Triple T = llvm::Triple(Triple);
926 if (T.isiOS())
927 UseSignedCharForObjCBool = false;
928 resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
929 "f80:128-n8:16:32:64-S128",
930 "_");
933 bool handleTargetFeatures(std::vector<std::string> &Features,
934 DiagnosticsEngine &Diags) override {
935 if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
936 Diags))
937 return false;
938 // We now know the features we have: we can decide how to align vectors.
939 MaxVectorAlign =
940 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
941 return true;
945 class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
946 : public OpenBSDTargetInfo<X86_64TargetInfo> {
947 public:
948 OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
949 : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
950 IntMaxType = SignedLongLong;
951 Int64Type = SignedLongLong;
955 // x86_32 Android target
956 class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
957 : public LinuxTargetInfo<X86_32TargetInfo> {
958 public:
959 AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
960 : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
961 SuitableAlign = 32;
962 LongDoubleWidth = 64;
963 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
967 // x86_64 Android target
968 class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
969 : public LinuxTargetInfo<X86_64TargetInfo> {
970 public:
971 AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
972 : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
973 LongDoubleFormat = &llvm::APFloat::IEEEquad();
977 // x86_32 OHOS target
978 class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo
979 : public OHOSTargetInfo<X86_32TargetInfo> {
980 public:
981 OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
982 : OHOSTargetInfo<X86_32TargetInfo>(Triple, Opts) {
983 SuitableAlign = 32;
984 LongDoubleWidth = 64;
985 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
989 // x86_64 OHOS target
990 class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo
991 : public OHOSTargetInfo<X86_64TargetInfo> {
992 public:
993 OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
994 : OHOSTargetInfo<X86_64TargetInfo>(Triple, Opts) {
995 LongDoubleFormat = &llvm::APFloat::IEEEquad();
998 } // namespace targets
999 } // namespace clang
1000 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H