[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / lib / Basic / Targets / X86.h
blobed0864aec6d2d2c986b994472a89f2dc08b23f8e
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 void getTargetDefines(const LangOptions &Opts,
294 MacroBuilder &Builder) const override;
296 void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
297 bool Enabled) const final;
299 bool
300 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
301 StringRef CPU,
302 const std::vector<std::string> &FeaturesVec) const override;
304 bool isValidFeatureName(StringRef Name) const override;
306 bool hasFeature(StringRef Feature) const final;
308 bool handleTargetFeatures(std::vector<std::string> &Features,
309 DiagnosticsEngine &Diags) override;
311 StringRef getABI() const override {
312 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
313 return "avx512";
314 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
315 return "avx";
316 if (getTriple().getArch() == llvm::Triple::x86 &&
317 MMX3DNowLevel == NoMMX3DNow)
318 return "no-mmx";
319 return "";
322 bool supportsTargetAttributeTune() const override {
323 return true;
326 bool isValidCPUName(StringRef Name) const override {
327 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
328 return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None;
331 bool isValidTuneCPUName(StringRef Name) const override {
332 if (Name == "generic")
333 return true;
335 // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
336 // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
337 // since mtune was ignored by clang for so long.
338 return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None;
341 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
342 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
344 bool setCPU(const std::string &Name) override {
345 bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
346 CPU = llvm::X86::parseArchX86(Name, Only64Bit);
347 return CPU != llvm::X86::CK_None;
350 unsigned multiVersionSortPriority(StringRef Name) const override;
352 bool setFPMath(StringRef Name) override;
354 bool supportsExtendIntArgs() const override {
355 return getTriple().getArch() != llvm::Triple::x86;
358 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
359 // Most of the non-ARM calling conventions are i386 conventions.
360 switch (CC) {
361 case CC_X86ThisCall:
362 case CC_X86FastCall:
363 case CC_X86StdCall:
364 case CC_X86VectorCall:
365 case CC_X86RegCall:
366 case CC_C:
367 case CC_PreserveMost:
368 case CC_Swift:
369 case CC_X86Pascal:
370 case CC_IntelOclBicc:
371 case CC_OpenCLKernel:
372 return CCCR_OK;
373 case CC_SwiftAsync:
374 return CCCR_Error;
375 default:
376 return CCCR_Warning;
380 bool checkArithmeticFenceSupported() const override { return true; }
382 CallingConv getDefaultCallingConv() const override {
383 return CC_C;
386 bool hasSjLjLowering() const override { return true; }
388 void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
390 uint64_t getPointerWidthV(unsigned AddrSpace) const override {
391 if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr)
392 return 32;
393 if (AddrSpace == ptr64)
394 return 64;
395 return PointerWidth;
398 uint64_t getPointerAlignV(unsigned AddrSpace) const override {
399 return getPointerWidthV(AddrSpace);
402 const char *getBFloat16Mangling() const override { return "u6__bf16"; };
405 // X86-32 generic target
406 class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {
407 public:
408 X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
409 : X86TargetInfo(Triple, Opts) {
410 DoubleAlign = LongLongAlign = 32;
411 LongDoubleWidth = 96;
412 LongDoubleAlign = 32;
413 SuitableAlign = 128;
414 resetDataLayout(
415 Triple.isOSBinFormatMachO()
416 ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
417 "f80:32-n8:16:32-S128"
418 : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
419 "f80:32-n8:16:32-S128",
420 Triple.isOSBinFormatMachO() ? "_" : "");
421 SizeType = UnsignedInt;
422 PtrDiffType = SignedInt;
423 IntPtrType = SignedInt;
424 RegParmMax = 3;
426 // Use fpret for all types.
427 RealTypeUsesObjCFPRetMask =
428 (unsigned)(FloatModeKind::Float | FloatModeKind::Double |
429 FloatModeKind::LongDouble);
431 // x86-32 has atomics up to 8 bytes
432 MaxAtomicPromoteWidth = 64;
433 MaxAtomicInlineWidth = 32;
436 BuiltinVaListKind getBuiltinVaListKind() const override {
437 return TargetInfo::CharPtrBuiltinVaList;
440 int getEHDataRegisterNumber(unsigned RegNo) const override {
441 if (RegNo == 0)
442 return 0;
443 if (RegNo == 1)
444 return 2;
445 return -1;
448 bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
449 StringRef Constraint, unsigned Size) const override {
450 switch (Constraint[0]) {
451 default:
452 break;
453 case 'R':
454 case 'q':
455 case 'Q':
456 case 'a':
457 case 'b':
458 case 'c':
459 case 'd':
460 case 'S':
461 case 'D':
462 return Size <= 32;
463 case 'A':
464 return Size <= 64;
467 return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);
470 void setMaxAtomicWidth() override {
471 if (hasFeature("cx8"))
472 MaxAtomicInlineWidth = 64;
475 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
477 bool hasBitIntType() const override { return true; }
480 class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
481 : public NetBSDTargetInfo<X86_32TargetInfo> {
482 public:
483 NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
484 : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
486 LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
487 VersionTuple OsVersion = getTriple().getOSVersion();
488 // New NetBSD uses the default rounding mode.
489 if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0)
490 return X86_32TargetInfo::getFPEvalMethod();
491 // NetBSD before 6.99.26 defaults to "double" rounding.
492 return LangOptions::FPEvalMethodKind::FEM_Double;
496 class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
497 : public OpenBSDTargetInfo<X86_32TargetInfo> {
498 public:
499 OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
500 : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
501 SizeType = UnsignedLong;
502 IntPtrType = SignedLong;
503 PtrDiffType = SignedLong;
507 class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
508 : public DarwinTargetInfo<X86_32TargetInfo> {
509 public:
510 DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
511 : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
512 LongDoubleWidth = 128;
513 LongDoubleAlign = 128;
514 SuitableAlign = 128;
515 MaxVectorAlign = 256;
516 // The watchOS simulator uses the builtin bool type for Objective-C.
517 llvm::Triple T = llvm::Triple(Triple);
518 if (T.isWatchOS())
519 UseSignedCharForObjCBool = false;
520 SizeType = UnsignedLong;
521 IntPtrType = SignedLong;
522 resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
523 "f80:128-n8:16:32-S128", "_");
524 HasAlignMac68kSupport = true;
527 bool handleTargetFeatures(std::vector<std::string> &Features,
528 DiagnosticsEngine &Diags) override {
529 if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
530 Diags))
531 return false;
532 // We now know the features we have: we can decide how to align vectors.
533 MaxVectorAlign =
534 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
535 return true;
539 // x86-32 Windows target
540 class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
541 : public WindowsTargetInfo<X86_32TargetInfo> {
542 public:
543 WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
544 : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
545 DoubleAlign = LongLongAlign = 64;
546 bool IsWinCOFF =
547 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
548 bool IsMSVC = getTriple().isWindowsMSVCEnvironment();
549 std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e";
550 Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-";
551 Layout += IsMSVC ? "f80:128" : "f80:32";
552 Layout += "-n8:16:32-a:0:32-S32";
553 resetDataLayout(Layout, IsWinCOFF ? "_" : "");
557 // x86-32 Windows Visual Studio target
558 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
559 : public WindowsX86_32TargetInfo {
560 public:
561 MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
562 const TargetOptions &Opts)
563 : WindowsX86_32TargetInfo(Triple, Opts) {
564 LongDoubleWidth = LongDoubleAlign = 64;
565 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
568 void getTargetDefines(const LangOptions &Opts,
569 MacroBuilder &Builder) const override {
570 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
571 // The value of the following reflects processor type.
572 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
573 // We lost the original triple, so we use the default.
574 Builder.defineMacro("_M_IX86", "600");
578 // x86-32 MinGW target
579 class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
580 : public WindowsX86_32TargetInfo {
581 public:
582 MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
583 : WindowsX86_32TargetInfo(Triple, Opts) {
584 HasFloat128 = true;
587 void getTargetDefines(const LangOptions &Opts,
588 MacroBuilder &Builder) const override {
589 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
590 Builder.defineMacro("_X86_");
594 // x86-32 Cygwin target
595 class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {
596 public:
597 CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
598 : X86_32TargetInfo(Triple, Opts) {
599 this->WCharType = TargetInfo::UnsignedShort;
600 DoubleAlign = LongLongAlign = 64;
601 resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:"
602 "32-n8:16:32-a:0:32-S32",
603 "_");
606 void getTargetDefines(const LangOptions &Opts,
607 MacroBuilder &Builder) const override {
608 X86_32TargetInfo::getTargetDefines(Opts, Builder);
609 Builder.defineMacro("_X86_");
610 Builder.defineMacro("__CYGWIN__");
611 Builder.defineMacro("__CYGWIN32__");
612 addCygMingDefines(Opts, Builder);
613 DefineStd(Builder, "unix", Opts);
614 if (Opts.CPlusPlus)
615 Builder.defineMacro("_GNU_SOURCE");
619 // x86-32 Haiku target
620 class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
621 : public HaikuTargetInfo<X86_32TargetInfo> {
622 public:
623 HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
624 : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
626 void getTargetDefines(const LangOptions &Opts,
627 MacroBuilder &Builder) const override {
628 HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
629 Builder.defineMacro("__INTEL__");
633 // X86-32 MCU target
634 class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {
635 public:
636 MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
637 : X86_32TargetInfo(Triple, Opts) {
638 LongDoubleWidth = 64;
639 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
640 resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:"
641 "32-f128:32-n8:16:32-a:0:32-S32");
642 WIntType = UnsignedInt;
645 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
646 // On MCU we support only C calling convention.
647 return CC == CC_C ? CCCR_OK : CCCR_Warning;
650 void getTargetDefines(const LangOptions &Opts,
651 MacroBuilder &Builder) const override {
652 X86_32TargetInfo::getTargetDefines(Opts, Builder);
653 Builder.defineMacro("__iamcu");
654 Builder.defineMacro("__iamcu__");
657 bool allowsLargerPreferedTypeAlignment() const override { return false; }
660 // x86-32 RTEMS target
661 class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {
662 public:
663 RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
664 : X86_32TargetInfo(Triple, Opts) {
665 SizeType = UnsignedLong;
666 IntPtrType = SignedLong;
667 PtrDiffType = SignedLong;
670 void getTargetDefines(const LangOptions &Opts,
671 MacroBuilder &Builder) const override {
672 X86_32TargetInfo::getTargetDefines(Opts, Builder);
673 Builder.defineMacro("__INTEL__");
674 Builder.defineMacro("__rtems__");
678 // x86-64 generic target
679 class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
680 public:
681 X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
682 : X86TargetInfo(Triple, Opts) {
683 const bool IsX32 = getTriple().isX32();
684 bool IsWinCOFF =
685 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
686 LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
687 LongDoubleWidth = 128;
688 LongDoubleAlign = 128;
689 LargeArrayMinWidth = 128;
690 LargeArrayAlign = 128;
691 SuitableAlign = 128;
692 SizeType = IsX32 ? UnsignedInt : UnsignedLong;
693 PtrDiffType = IsX32 ? SignedInt : SignedLong;
694 IntPtrType = IsX32 ? SignedInt : SignedLong;
695 IntMaxType = IsX32 ? SignedLongLong : SignedLong;
696 Int64Type = IsX32 ? SignedLongLong : SignedLong;
697 RegParmMax = 6;
699 // Pointers are 32-bit in x32.
700 resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
701 "i64:64-f80:128-n8:16:32:64-S128"
702 : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:"
703 "64-i64:64-f80:128-n8:16:32:64-S128"
704 : "e-m:e-p270:32:32-p271:32:32-p272:64:"
705 "64-i64:64-f80:128-n8:16:32:64-S128");
707 // Use fpret only for long double.
708 RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;
710 // Use fp2ret for _Complex long double.
711 ComplexLongDoubleUsesFP2Ret = true;
713 // Make __builtin_ms_va_list available.
714 HasBuiltinMSVaList = true;
716 // x86-64 has atomics up to 16 bytes.
717 MaxAtomicPromoteWidth = 128;
718 MaxAtomicInlineWidth = 64;
721 BuiltinVaListKind getBuiltinVaListKind() const override {
722 return TargetInfo::X86_64ABIBuiltinVaList;
725 int getEHDataRegisterNumber(unsigned RegNo) const override {
726 if (RegNo == 0)
727 return 0;
728 if (RegNo == 1)
729 return 1;
730 return -1;
733 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
734 switch (CC) {
735 case CC_C:
736 case CC_Swift:
737 case CC_SwiftAsync:
738 case CC_X86VectorCall:
739 case CC_IntelOclBicc:
740 case CC_Win64:
741 case CC_PreserveMost:
742 case CC_PreserveAll:
743 case CC_X86RegCall:
744 case CC_OpenCLKernel:
745 return CCCR_OK;
746 default:
747 return CCCR_Warning;
751 CallingConv getDefaultCallingConv() const override {
752 return CC_C;
755 // for x32 we need it here explicitly
756 bool hasInt128Type() const override { return true; }
758 unsigned getUnwindWordWidth() const override { return 64; }
760 unsigned getRegisterWidth() const override { return 64; }
762 bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
763 bool &HasSizeMismatch) const override {
764 // rsp and rbp are the only 64-bit registers the x86 backend can currently
765 // handle.
766 if (RegName.equals("rsp") || RegName.equals("rbp")) {
767 // Check that the register size is 64-bit.
768 HasSizeMismatch = RegSize != 64;
769 return true;
772 // Check if the register is a 32-bit register the backend can handle.
773 return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
774 HasSizeMismatch);
777 void setMaxAtomicWidth() override {
778 if (hasFeature("cx16"))
779 MaxAtomicInlineWidth = 128;
782 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
784 bool hasBitIntType() const override { return true; }
787 // x86-64 Windows target
788 class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
789 : public WindowsTargetInfo<X86_64TargetInfo> {
790 public:
791 WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
792 : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
793 LongWidth = LongAlign = 32;
794 DoubleAlign = LongLongAlign = 64;
795 IntMaxType = SignedLongLong;
796 Int64Type = SignedLongLong;
797 SizeType = UnsignedLongLong;
798 PtrDiffType = SignedLongLong;
799 IntPtrType = SignedLongLong;
802 BuiltinVaListKind getBuiltinVaListKind() const override {
803 return TargetInfo::CharPtrBuiltinVaList;
806 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
807 switch (CC) {
808 case CC_X86StdCall:
809 case CC_X86ThisCall:
810 case CC_X86FastCall:
811 return CCCR_Ignore;
812 case CC_C:
813 case CC_X86VectorCall:
814 case CC_IntelOclBicc:
815 case CC_PreserveMost:
816 case CC_PreserveAll:
817 case CC_X86_64SysV:
818 case CC_Swift:
819 case CC_SwiftAsync:
820 case CC_X86RegCall:
821 case CC_OpenCLKernel:
822 return CCCR_OK;
823 default:
824 return CCCR_Warning;
829 // x86-64 Windows Visual Studio target
830 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
831 : public WindowsX86_64TargetInfo {
832 public:
833 MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
834 const TargetOptions &Opts)
835 : WindowsX86_64TargetInfo(Triple, Opts) {
836 LongDoubleWidth = LongDoubleAlign = 64;
837 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
840 void getTargetDefines(const LangOptions &Opts,
841 MacroBuilder &Builder) const override {
842 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
843 Builder.defineMacro("_M_X64", "100");
844 Builder.defineMacro("_M_AMD64", "100");
847 TargetInfo::CallingConvKind
848 getCallingConvKind(bool ClangABICompat4) const override {
849 return CCK_MicrosoftWin64;
853 // x86-64 MinGW target
854 class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
855 : public WindowsX86_64TargetInfo {
856 public:
857 MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
858 : WindowsX86_64TargetInfo(Triple, Opts) {
859 // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
860 // with x86 FP ops. Weird.
861 LongDoubleWidth = LongDoubleAlign = 128;
862 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
863 HasFloat128 = true;
867 // x86-64 Cygwin target
868 class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {
869 public:
870 CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
871 : X86_64TargetInfo(Triple, Opts) {
872 this->WCharType = TargetInfo::UnsignedShort;
873 TLSSupported = false;
876 void getTargetDefines(const LangOptions &Opts,
877 MacroBuilder &Builder) const override {
878 X86_64TargetInfo::getTargetDefines(Opts, Builder);
879 Builder.defineMacro("__x86_64__");
880 Builder.defineMacro("__CYGWIN__");
881 Builder.defineMacro("__CYGWIN64__");
882 addCygMingDefines(Opts, Builder);
883 DefineStd(Builder, "unix", Opts);
884 if (Opts.CPlusPlus)
885 Builder.defineMacro("_GNU_SOURCE");
889 class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
890 : public DarwinTargetInfo<X86_64TargetInfo> {
891 public:
892 DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
893 : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
894 Int64Type = SignedLongLong;
895 // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
896 llvm::Triple T = llvm::Triple(Triple);
897 if (T.isiOS())
898 UseSignedCharForObjCBool = false;
899 resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:"
900 "16:32:64-S128", "_");
903 bool handleTargetFeatures(std::vector<std::string> &Features,
904 DiagnosticsEngine &Diags) override {
905 if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
906 Diags))
907 return false;
908 // We now know the features we have: we can decide how to align vectors.
909 MaxVectorAlign =
910 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
911 return true;
915 class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
916 : public OpenBSDTargetInfo<X86_64TargetInfo> {
917 public:
918 OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
919 : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
920 IntMaxType = SignedLongLong;
921 Int64Type = SignedLongLong;
925 // x86_32 Android target
926 class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
927 : public LinuxTargetInfo<X86_32TargetInfo> {
928 public:
929 AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
930 : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
931 SuitableAlign = 32;
932 LongDoubleWidth = 64;
933 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
937 // x86_64 Android target
938 class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
939 : public LinuxTargetInfo<X86_64TargetInfo> {
940 public:
941 AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
942 : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
943 LongDoubleFormat = &llvm::APFloat::IEEEquad();
946 } // namespace targets
947 } // namespace clang
948 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H