[docs] Fix build-docs.sh
[llvm-project.git] / clang / lib / Basic / Targets / X86.h
blob7c1fe0d50fac0c6b079125b076620962d55021c5
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/ADT/Triple.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/X86TargetParser.h"
24 namespace clang {
25 namespace targets {
27 static const unsigned X86AddrSpaceMap[] = {
28 0, // Default
29 0, // opencl_global
30 0, // opencl_local
31 0, // opencl_constant
32 0, // opencl_private
33 0, // opencl_generic
34 0, // opencl_global_device
35 0, // opencl_global_host
36 0, // cuda_device
37 0, // cuda_constant
38 0, // cuda_shared
39 0, // sycl_global
40 0, // sycl_global_device
41 0, // sycl_global_host
42 0, // sycl_local
43 0, // sycl_private
44 270, // ptr32_sptr
45 271, // ptr32_uptr
46 272 // ptr64
49 // X86 target abstract base class; x86-32 and x86-64 are very close, so
50 // most of the implementation can be shared.
51 class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
53 enum X86SSEEnum {
54 NoSSE,
55 SSE1,
56 SSE2,
57 SSE3,
58 SSSE3,
59 SSE41,
60 SSE42,
61 AVX,
62 AVX2,
63 AVX512F
64 } SSELevel = NoSSE;
65 enum MMX3DNowEnum {
66 NoMMX3DNow,
67 MMX,
68 AMD3DNow,
69 AMD3DNowAthlon
70 } MMX3DNowLevel = NoMMX3DNow;
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 HasAVX512CD = false;
94 bool HasAVX512VPOPCNTDQ = false;
95 bool HasAVX512VNNI = false;
96 bool HasAVX512FP16 = false;
97 bool HasAVX512BF16 = false;
98 bool HasAVX512ER = false;
99 bool HasAVX512PF = false;
100 bool HasAVX512DQ = false;
101 bool HasAVX512BITALG = false;
102 bool HasAVX512BW = false;
103 bool HasAVX512VL = false;
104 bool HasAVX512VBMI = false;
105 bool HasAVX512VBMI2 = false;
106 bool HasAVX512IFMA = false;
107 bool HasAVX512VP2INTERSECT = false;
108 bool HasSHA = false;
109 bool HasSHSTK = false;
110 bool HasSGX = false;
111 bool HasCX8 = false;
112 bool HasCX16 = false;
113 bool HasFXSR = false;
114 bool HasXSAVE = false;
115 bool HasXSAVEOPT = false;
116 bool HasXSAVEC = false;
117 bool HasXSAVES = false;
118 bool HasMWAITX = false;
119 bool HasCLZERO = false;
120 bool HasCLDEMOTE = false;
121 bool HasPCONFIG = false;
122 bool HasPKU = false;
123 bool HasCLFLUSHOPT = false;
124 bool HasCLWB = false;
125 bool HasMOVBE = false;
126 bool HasPREFETCHWT1 = false;
127 bool HasRDPID = false;
128 bool HasRDPRU = false;
129 bool HasRetpolineExternalThunk = false;
130 bool HasLAHFSAHF = false;
131 bool HasWBNOINVD = false;
132 bool HasWAITPKG = false;
133 bool HasMOVDIRI = false;
134 bool HasMOVDIR64B = false;
135 bool HasPTWRITE = false;
136 bool HasINVPCID = false;
137 bool HasENQCMD = false;
138 bool HasKL = false; // For key locker
139 bool HasWIDEKL = false; // For wide key locker
140 bool HasHRESET = false;
141 bool HasAVXVNNI = false;
142 bool HasAMXTILE = false;
143 bool HasAMXINT8 = false;
144 bool HasAMXBF16 = false;
145 bool HasSERIALIZE = false;
146 bool HasTSXLDTRK = false;
147 bool HasUINTR = false;
148 bool HasCRC32 = false;
149 bool HasX87 = false;
151 protected:
152 llvm::X86::CPUKind CPU = llvm::X86::CK_None;
154 enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
156 public:
157 X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
158 : TargetInfo(Triple) {
159 BFloat16Width = BFloat16Align = 16;
160 BFloat16Format = &llvm::APFloat::BFloat();
161 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
162 AddrSpaceMap = &X86AddrSpaceMap;
163 HasStrictFP = true;
165 bool IsWinCOFF =
166 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
167 if (IsWinCOFF)
168 MaxVectorAlign = MaxTLSAlign = 8192u * getCharWidth();
171 const char *getLongDoubleMangling() const override {
172 return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
175 LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
176 // X87 evaluates with 80 bits "long double" precision.
177 return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended
178 : LangOptions::FPEvalMethodKind::FEM_Source;
181 // EvalMethod `source` is not supported for targets with `NoSSE` feature.
182 bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; }
184 ArrayRef<const char *> getGCCRegNames() const override;
186 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
187 return None;
190 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
192 bool isSPRegName(StringRef RegName) const override {
193 return RegName.equals("esp") || RegName.equals("rsp");
196 bool validateCpuSupports(StringRef Name) const override;
198 bool validateCpuIs(StringRef Name) const override;
200 bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
202 char CPUSpecificManglingCharacter(StringRef Name) const override;
204 void getCPUSpecificCPUDispatchFeatures(
205 StringRef Name,
206 llvm::SmallVectorImpl<StringRef> &Features) const override;
208 StringRef getCPUSpecificTuneName(StringRef Name) const override;
210 Optional<unsigned> getCPUCacheLineSize() const override;
212 bool validateAsmConstraint(const char *&Name,
213 TargetInfo::ConstraintInfo &info) const override;
215 bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
216 bool &HasSizeMismatch) const override {
217 // esp and ebp are the only 32-bit registers the x86 backend can currently
218 // handle.
219 if (RegName.equals("esp") || RegName.equals("ebp")) {
220 // Check that the register size is 32-bit.
221 HasSizeMismatch = RegSize != 32;
222 return true;
225 return false;
228 bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
229 StringRef Constraint, unsigned Size) const override;
231 bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
232 StringRef Constraint, unsigned Size) const override;
234 bool
235 checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
236 return true;
239 bool
240 checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
241 return true;
244 virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
245 StringRef Constraint, unsigned Size) const;
247 std::string convertConstraint(const char *&Constraint) const override;
248 const char *getClobbers() const override {
249 return "~{dirflag},~{fpsr},~{flags}";
252 StringRef getConstraintRegister(StringRef Constraint,
253 StringRef Expression) const override {
254 StringRef::iterator I, E;
255 for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
256 if (isalpha(*I) || *I == '@')
257 break;
259 if (I == E)
260 return "";
261 switch (*I) {
262 // For the register constraints, return the matching register name
263 case 'a':
264 return "ax";
265 case 'b':
266 return "bx";
267 case 'c':
268 return "cx";
269 case 'd':
270 return "dx";
271 case 'S':
272 return "si";
273 case 'D':
274 return "di";
275 // In case the constraint is 'r' we need to return Expression
276 case 'r':
277 return Expression;
278 // Double letters Y<x> constraints
279 case 'Y':
280 if ((++I != E) && ((*I == '0') || (*I == 'z')))
281 return "xmm0";
282 break;
283 default:
284 break;
286 return "";
289 bool useFP16ConversionIntrinsics() const override {
290 return false;
293 bool shouldEmitFloat16WithExcessPrecision() const override {
294 return HasFloat16 && !hasLegalHalfType();
297 void getTargetDefines(const LangOptions &Opts,
298 MacroBuilder &Builder) const override;
300 void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
301 bool Enabled) const final;
303 bool
304 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
305 StringRef CPU,
306 const std::vector<std::string> &FeaturesVec) const override;
308 bool isValidFeatureName(StringRef Name) const override;
310 bool hasFeature(StringRef Feature) const final;
312 bool handleTargetFeatures(std::vector<std::string> &Features,
313 DiagnosticsEngine &Diags) override;
315 StringRef getABI() const override {
316 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
317 return "avx512";
318 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
319 return "avx";
320 if (getTriple().getArch() == llvm::Triple::x86 &&
321 MMX3DNowLevel == NoMMX3DNow)
322 return "no-mmx";
323 return "";
326 bool supportsTargetAttributeTune() const override {
327 return true;
330 bool isValidCPUName(StringRef Name) const override {
331 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
332 return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None;
335 bool isValidTuneCPUName(StringRef Name) const override {
336 if (Name == "generic")
337 return true;
339 // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
340 // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
341 // since mtune was ignored by clang for so long.
342 return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None;
345 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
346 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
348 bool setCPU(const std::string &Name) override {
349 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
350 CPU = llvm::X86::parseArchX86(Name, Only64Bit);
351 return CPU != llvm::X86::CK_None;
354 unsigned multiVersionSortPriority(StringRef Name) const override;
356 bool setFPMath(StringRef Name) override;
358 bool supportsExtendIntArgs() const override {
359 return getTriple().getArch() != llvm::Triple::x86;
362 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
363 // Most of the non-ARM calling conventions are i386 conventions.
364 switch (CC) {
365 case CC_X86ThisCall:
366 case CC_X86FastCall:
367 case CC_X86StdCall:
368 case CC_X86VectorCall:
369 case CC_X86RegCall:
370 case CC_C:
371 case CC_PreserveMost:
372 case CC_Swift:
373 case CC_X86Pascal:
374 case CC_IntelOclBicc:
375 case CC_OpenCLKernel:
376 return CCCR_OK;
377 case CC_SwiftAsync:
378 return CCCR_Error;
379 default:
380 return CCCR_Warning;
384 bool checkArithmeticFenceSupported() const override { return true; }
386 CallingConv getDefaultCallingConv() const override {
387 return CC_C;
390 bool hasSjLjLowering() const override { return true; }
392 void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
394 uint64_t getPointerWidthV(unsigned AddrSpace) const override {
395 if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr)
396 return 32;
397 if (AddrSpace == ptr64)
398 return 64;
399 return PointerWidth;
402 uint64_t getPointerAlignV(unsigned AddrSpace) const override {
403 return getPointerWidthV(AddrSpace);
406 const char *getBFloat16Mangling() const override { return "u6__bf16"; };
409 // X86-32 generic target
410 class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {
411 public:
412 X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
413 : X86TargetInfo(Triple, Opts) {
414 DoubleAlign = LongLongAlign = 32;
415 LongDoubleWidth = 96;
416 LongDoubleAlign = 32;
417 SuitableAlign = 128;
418 resetDataLayout(
419 Triple.isOSBinFormatMachO()
420 ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
421 "f80:32-n8:16:32-S128"
422 : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
423 "f80:32-n8:16:32-S128",
424 Triple.isOSBinFormatMachO() ? "_" : "");
425 SizeType = UnsignedInt;
426 PtrDiffType = SignedInt;
427 IntPtrType = SignedInt;
428 RegParmMax = 3;
430 // Use fpret for all types.
431 RealTypeUsesObjCFPRetMask =
432 (unsigned)(FloatModeKind::Float | FloatModeKind::Double |
433 FloatModeKind::LongDouble);
435 // x86-32 has atomics up to 8 bytes
436 MaxAtomicPromoteWidth = 64;
437 MaxAtomicInlineWidth = 32;
440 BuiltinVaListKind getBuiltinVaListKind() const override {
441 return TargetInfo::CharPtrBuiltinVaList;
444 int getEHDataRegisterNumber(unsigned RegNo) const override {
445 if (RegNo == 0)
446 return 0;
447 if (RegNo == 1)
448 return 2;
449 return -1;
452 bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
453 StringRef Constraint, unsigned Size) const override {
454 switch (Constraint[0]) {
455 default:
456 break;
457 case 'R':
458 case 'q':
459 case 'Q':
460 case 'a':
461 case 'b':
462 case 'c':
463 case 'd':
464 case 'S':
465 case 'D':
466 return Size <= 32;
467 case 'A':
468 return Size <= 64;
471 return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);
474 void setMaxAtomicWidth() override {
475 if (hasFeature("cx8"))
476 MaxAtomicInlineWidth = 64;
479 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
481 bool hasBitIntType() const override { return true; }
484 class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
485 : public NetBSDTargetInfo<X86_32TargetInfo> {
486 public:
487 NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
488 : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
490 LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
491 VersionTuple OsVersion = getTriple().getOSVersion();
492 // New NetBSD uses the default rounding mode.
493 if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0)
494 return X86_32TargetInfo::getFPEvalMethod();
495 // NetBSD before 6.99.26 defaults to "double" rounding.
496 return LangOptions::FPEvalMethodKind::FEM_Double;
500 class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
501 : public OpenBSDTargetInfo<X86_32TargetInfo> {
502 public:
503 OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
504 : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
505 SizeType = UnsignedLong;
506 IntPtrType = SignedLong;
507 PtrDiffType = SignedLong;
511 class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
512 : public DarwinTargetInfo<X86_32TargetInfo> {
513 public:
514 DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
515 : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
516 LongDoubleWidth = 128;
517 LongDoubleAlign = 128;
518 SuitableAlign = 128;
519 MaxVectorAlign = 256;
520 // The watchOS simulator uses the builtin bool type for Objective-C.
521 llvm::Triple T = llvm::Triple(Triple);
522 if (T.isWatchOS())
523 UseSignedCharForObjCBool = false;
524 SizeType = UnsignedLong;
525 IntPtrType = SignedLong;
526 resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
527 "f80:128-n8:16:32-S128", "_");
528 HasAlignMac68kSupport = true;
531 bool handleTargetFeatures(std::vector<std::string> &Features,
532 DiagnosticsEngine &Diags) override {
533 if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
534 Diags))
535 return false;
536 // We now know the features we have: we can decide how to align vectors.
537 MaxVectorAlign =
538 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
539 return true;
543 // x86-32 Windows target
544 class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
545 : public WindowsTargetInfo<X86_32TargetInfo> {
546 public:
547 WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
548 : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
549 DoubleAlign = LongLongAlign = 64;
550 bool IsWinCOFF =
551 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
552 bool IsMSVC = getTriple().isWindowsMSVCEnvironment();
553 std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e";
554 Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-";
555 Layout += IsMSVC ? "f80:128" : "f80:32";
556 Layout += "-n8:16:32-a:0:32-S32";
557 resetDataLayout(Layout, IsWinCOFF ? "_" : "");
561 // x86-32 Windows Visual Studio target
562 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
563 : public WindowsX86_32TargetInfo {
564 public:
565 MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
566 const TargetOptions &Opts)
567 : WindowsX86_32TargetInfo(Triple, Opts) {
568 LongDoubleWidth = LongDoubleAlign = 64;
569 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
572 void getTargetDefines(const LangOptions &Opts,
573 MacroBuilder &Builder) const override {
574 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
575 // The value of the following reflects processor type.
576 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
577 // We lost the original triple, so we use the default.
578 Builder.defineMacro("_M_IX86", "600");
582 // x86-32 MinGW target
583 class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
584 : public WindowsX86_32TargetInfo {
585 public:
586 MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
587 : WindowsX86_32TargetInfo(Triple, Opts) {
588 HasFloat128 = true;
591 void getTargetDefines(const LangOptions &Opts,
592 MacroBuilder &Builder) const override {
593 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
594 Builder.defineMacro("_X86_");
598 // x86-32 Cygwin target
599 class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {
600 public:
601 CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
602 : X86_32TargetInfo(Triple, Opts) {
603 this->WCharType = TargetInfo::UnsignedShort;
604 DoubleAlign = LongLongAlign = 64;
605 resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:"
606 "32-n8:16:32-a:0:32-S32",
607 "_");
610 void getTargetDefines(const LangOptions &Opts,
611 MacroBuilder &Builder) const override {
612 X86_32TargetInfo::getTargetDefines(Opts, Builder);
613 Builder.defineMacro("_X86_");
614 Builder.defineMacro("__CYGWIN__");
615 Builder.defineMacro("__CYGWIN32__");
616 addCygMingDefines(Opts, Builder);
617 DefineStd(Builder, "unix", Opts);
618 if (Opts.CPlusPlus)
619 Builder.defineMacro("_GNU_SOURCE");
623 // x86-32 Haiku target
624 class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
625 : public HaikuTargetInfo<X86_32TargetInfo> {
626 public:
627 HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
628 : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
630 void getTargetDefines(const LangOptions &Opts,
631 MacroBuilder &Builder) const override {
632 HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
633 Builder.defineMacro("__INTEL__");
637 // X86-32 MCU target
638 class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {
639 public:
640 MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
641 : X86_32TargetInfo(Triple, Opts) {
642 LongDoubleWidth = 64;
643 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
644 resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:"
645 "32-f128:32-n8:16:32-a:0:32-S32");
646 WIntType = UnsignedInt;
649 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
650 // On MCU we support only C calling convention.
651 return CC == CC_C ? CCCR_OK : CCCR_Warning;
654 void getTargetDefines(const LangOptions &Opts,
655 MacroBuilder &Builder) const override {
656 X86_32TargetInfo::getTargetDefines(Opts, Builder);
657 Builder.defineMacro("__iamcu");
658 Builder.defineMacro("__iamcu__");
661 bool allowsLargerPreferedTypeAlignment() const override { return false; }
664 // x86-32 RTEMS target
665 class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {
666 public:
667 RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
668 : X86_32TargetInfo(Triple, Opts) {
669 SizeType = UnsignedLong;
670 IntPtrType = SignedLong;
671 PtrDiffType = SignedLong;
674 void getTargetDefines(const LangOptions &Opts,
675 MacroBuilder &Builder) const override {
676 X86_32TargetInfo::getTargetDefines(Opts, Builder);
677 Builder.defineMacro("__INTEL__");
678 Builder.defineMacro("__rtems__");
682 // x86-64 generic target
683 class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
684 public:
685 X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
686 : X86TargetInfo(Triple, Opts) {
687 const bool IsX32 = getTriple().isX32();
688 bool IsWinCOFF =
689 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
690 LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
691 LongDoubleWidth = 128;
692 LongDoubleAlign = 128;
693 LargeArrayMinWidth = 128;
694 LargeArrayAlign = 128;
695 SuitableAlign = 128;
696 SizeType = IsX32 ? UnsignedInt : UnsignedLong;
697 PtrDiffType = IsX32 ? SignedInt : SignedLong;
698 IntPtrType = IsX32 ? SignedInt : SignedLong;
699 IntMaxType = IsX32 ? SignedLongLong : SignedLong;
700 Int64Type = IsX32 ? SignedLongLong : SignedLong;
701 RegParmMax = 6;
703 // Pointers are 32-bit in x32.
704 resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
705 "i64:64-f80:128-n8:16:32:64-S128"
706 : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:"
707 "64-i64:64-f80:128-n8:16:32:64-S128"
708 : "e-m:e-p270:32:32-p271:32:32-p272:64:"
709 "64-i64:64-f80:128-n8:16:32:64-S128");
711 // Use fpret only for long double.
712 RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;
714 // Use fp2ret for _Complex long double.
715 ComplexLongDoubleUsesFP2Ret = true;
717 // Make __builtin_ms_va_list available.
718 HasBuiltinMSVaList = true;
720 // x86-64 has atomics up to 16 bytes.
721 MaxAtomicPromoteWidth = 128;
722 MaxAtomicInlineWidth = 64;
725 BuiltinVaListKind getBuiltinVaListKind() const override {
726 return TargetInfo::X86_64ABIBuiltinVaList;
729 int getEHDataRegisterNumber(unsigned RegNo) const override {
730 if (RegNo == 0)
731 return 0;
732 if (RegNo == 1)
733 return 1;
734 return -1;
737 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
738 switch (CC) {
739 case CC_C:
740 case CC_Swift:
741 case CC_SwiftAsync:
742 case CC_X86VectorCall:
743 case CC_IntelOclBicc:
744 case CC_Win64:
745 case CC_PreserveMost:
746 case CC_PreserveAll:
747 case CC_X86RegCall:
748 case CC_OpenCLKernel:
749 return CCCR_OK;
750 default:
751 return CCCR_Warning;
755 CallingConv getDefaultCallingConv() const override {
756 return CC_C;
759 // for x32 we need it here explicitly
760 bool hasInt128Type() const override { return true; }
762 unsigned getUnwindWordWidth() const override { return 64; }
764 unsigned getRegisterWidth() const override { return 64; }
766 bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
767 bool &HasSizeMismatch) const override {
768 // rsp and rbp are the only 64-bit registers the x86 backend can currently
769 // handle.
770 if (RegName.equals("rsp") || RegName.equals("rbp")) {
771 // Check that the register size is 64-bit.
772 HasSizeMismatch = RegSize != 64;
773 return true;
776 // Check if the register is a 32-bit register the backend can handle.
777 return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
778 HasSizeMismatch);
781 void setMaxAtomicWidth() override {
782 if (hasFeature("cx16"))
783 MaxAtomicInlineWidth = 128;
786 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
788 bool hasBitIntType() const override { return true; }
791 // x86-64 Windows target
792 class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
793 : public WindowsTargetInfo<X86_64TargetInfo> {
794 public:
795 WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
796 : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
797 LongWidth = LongAlign = 32;
798 DoubleAlign = LongLongAlign = 64;
799 IntMaxType = SignedLongLong;
800 Int64Type = SignedLongLong;
801 SizeType = UnsignedLongLong;
802 PtrDiffType = SignedLongLong;
803 IntPtrType = SignedLongLong;
806 BuiltinVaListKind getBuiltinVaListKind() const override {
807 return TargetInfo::CharPtrBuiltinVaList;
810 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
811 switch (CC) {
812 case CC_X86StdCall:
813 case CC_X86ThisCall:
814 case CC_X86FastCall:
815 return CCCR_Ignore;
816 case CC_C:
817 case CC_X86VectorCall:
818 case CC_IntelOclBicc:
819 case CC_PreserveMost:
820 case CC_PreserveAll:
821 case CC_X86_64SysV:
822 case CC_Swift:
823 case CC_SwiftAsync:
824 case CC_X86RegCall:
825 case CC_OpenCLKernel:
826 return CCCR_OK;
827 default:
828 return CCCR_Warning;
833 // x86-64 Windows Visual Studio target
834 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
835 : public WindowsX86_64TargetInfo {
836 public:
837 MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
838 const TargetOptions &Opts)
839 : WindowsX86_64TargetInfo(Triple, Opts) {
840 LongDoubleWidth = LongDoubleAlign = 64;
841 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
844 void getTargetDefines(const LangOptions &Opts,
845 MacroBuilder &Builder) const override {
846 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
847 Builder.defineMacro("_M_X64", "100");
848 Builder.defineMacro("_M_AMD64", "100");
851 TargetInfo::CallingConvKind
852 getCallingConvKind(bool ClangABICompat4) const override {
853 return CCK_MicrosoftWin64;
857 // x86-64 MinGW target
858 class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
859 : public WindowsX86_64TargetInfo {
860 public:
861 MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
862 : WindowsX86_64TargetInfo(Triple, Opts) {
863 // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
864 // with x86 FP ops. Weird.
865 LongDoubleWidth = LongDoubleAlign = 128;
866 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
867 HasFloat128 = true;
871 // x86-64 Cygwin target
872 class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {
873 public:
874 CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
875 : X86_64TargetInfo(Triple, Opts) {
876 this->WCharType = TargetInfo::UnsignedShort;
877 TLSSupported = false;
880 void getTargetDefines(const LangOptions &Opts,
881 MacroBuilder &Builder) const override {
882 X86_64TargetInfo::getTargetDefines(Opts, Builder);
883 Builder.defineMacro("__x86_64__");
884 Builder.defineMacro("__CYGWIN__");
885 Builder.defineMacro("__CYGWIN64__");
886 addCygMingDefines(Opts, Builder);
887 DefineStd(Builder, "unix", Opts);
888 if (Opts.CPlusPlus)
889 Builder.defineMacro("_GNU_SOURCE");
893 class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
894 : public DarwinTargetInfo<X86_64TargetInfo> {
895 public:
896 DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
897 : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
898 Int64Type = SignedLongLong;
899 // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
900 llvm::Triple T = llvm::Triple(Triple);
901 if (T.isiOS())
902 UseSignedCharForObjCBool = false;
903 resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:"
904 "16:32:64-S128", "_");
907 bool handleTargetFeatures(std::vector<std::string> &Features,
908 DiagnosticsEngine &Diags) override {
909 if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
910 Diags))
911 return false;
912 // We now know the features we have: we can decide how to align vectors.
913 MaxVectorAlign =
914 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
915 return true;
919 class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
920 : public OpenBSDTargetInfo<X86_64TargetInfo> {
921 public:
922 OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
923 : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
924 IntMaxType = SignedLongLong;
925 Int64Type = SignedLongLong;
929 // x86_32 Android target
930 class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
931 : public LinuxTargetInfo<X86_32TargetInfo> {
932 public:
933 AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
934 : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
935 SuitableAlign = 32;
936 LongDoubleWidth = 64;
937 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
941 // x86_64 Android target
942 class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
943 : public LinuxTargetInfo<X86_64TargetInfo> {
944 public:
945 AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
946 : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
947 LongDoubleFormat = &llvm::APFloat::IEEEquad();
950 } // namespace targets
951 } // namespace clang
952 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H