1 //===--- X86.h - Declare X86 target feature support -------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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"
27 static const unsigned X86AddrSpaceMap
[] = {
34 0, // opencl_global_device
35 0, // opencl_global_host
40 0, // sycl_global_device
41 0, // sycl_global_host
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
{
70 } MMX3DNowLevel
= NoMMX3DNow
;
71 enum XOPEnum
{ NoXOP
, SSE4A
, FMA4
, XOP
} XOPLevel
= NoXOP
;
72 enum AddrSpace
{ ptr32_sptr
= 270, ptr32_uptr
= 271, ptr64
= 272 };
76 bool HasPCLMUL
= false;
77 bool HasVPCLMULQDQ
= false;
79 bool HasLZCNT
= false;
80 bool HasRDRND
= false;
81 bool HasFSGSBASE
= false;
84 bool HasPOPCNT
= false;
86 bool HasPRFCHW
= false;
87 bool HasRDSEED
= 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;
109 bool HasSHSTK
= 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;
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;
152 llvm::X86::CPUKind CPU
= llvm::X86::CK_None
;
154 enum FPMathKind
{ FP_Default
, FP_SSE
, FP_387
} FPMath
= FP_Default
;
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
;
166 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
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
{
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(
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
219 if (RegName
.equals("esp") || RegName
.equals("ebp")) {
220 // Check that the register size is 32-bit.
221 HasSizeMismatch
= RegSize
!= 32;
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
;
235 checkCFProtectionReturnSupported(DiagnosticsEngine
&Diags
) const override
{
240 checkCFProtectionBranchSupported(DiagnosticsEngine
&Diags
) const override
{
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
== '@')
262 // For the register constraints, return the matching register name
275 // In case the constraint is 'r' we need to return Expression
278 // Double letters Y<x> constraints
280 if ((++I
!= E
) && ((*I
== '0') || (*I
== 'z')))
289 bool useFP16ConversionIntrinsics() const override
{
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
;
300 initFeatureMap(llvm::StringMap
<bool> &Features
, DiagnosticsEngine
&Diags
,
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
)
314 if (getTriple().getArch() == llvm::Triple::x86_64
&& SSELevel
>= AVX
)
316 if (getTriple().getArch() == llvm::Triple::x86
&&
317 MMX3DNowLevel
== NoMMX3DNow
)
322 bool supportsTargetAttributeTune() const override
{
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")
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.
364 case CC_X86VectorCall
:
367 case CC_PreserveMost
:
370 case CC_IntelOclBicc
:
371 case CC_OpenCLKernel
:
380 bool checkArithmeticFenceSupported() const override
{ return true; }
382 CallingConv
getDefaultCallingConv() const override
{
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
)
393 if (AddrSpace
== ptr64
)
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
{
408 X86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
409 : X86TargetInfo(Triple
, Opts
) {
410 DoubleAlign
= LongLongAlign
= 32;
411 LongDoubleWidth
= 96;
412 LongDoubleAlign
= 32;
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
;
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
{
448 bool validateOperandSize(const llvm::StringMap
<bool> &FeatureMap
,
449 StringRef Constraint
, unsigned Size
) const override
{
450 switch (Constraint
[0]) {
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
> {
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
> {
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
> {
510 DarwinI386TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
511 : DarwinTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
512 LongDoubleWidth
= 128;
513 LongDoubleAlign
= 128;
515 MaxVectorAlign
= 256;
516 // The watchOS simulator uses the builtin bool type for Objective-C.
517 llvm::Triple T
= llvm::Triple(Triple
);
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
,
532 // We now know the features we have: we can decide how to align vectors.
534 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
539 // x86-32 Windows target
540 class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
541 : public WindowsTargetInfo
<X86_32TargetInfo
> {
543 WindowsX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
544 : WindowsTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
545 DoubleAlign
= LongLongAlign
= 64;
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
{
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
{
582 MinGWX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
583 : WindowsX86_32TargetInfo(Triple
, Opts
) {
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
{
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",
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
);
615 Builder
.defineMacro("_GNU_SOURCE");
619 // x86-32 Haiku target
620 class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
621 : public HaikuTargetInfo
<X86_32TargetInfo
> {
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__");
634 class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo
: public X86_32TargetInfo
{
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
{
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
{
681 X86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
682 : X86TargetInfo(Triple
, Opts
) {
683 const bool IsX32
= getTriple().isX32();
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;
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
;
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
{
733 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
738 case CC_X86VectorCall
:
739 case CC_IntelOclBicc
:
741 case CC_PreserveMost
:
744 case CC_OpenCLKernel
:
751 CallingConv
getDefaultCallingConv() const override
{
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
766 if (RegName
.equals("rsp") || RegName
.equals("rbp")) {
767 // Check that the register size is 64-bit.
768 HasSizeMismatch
= RegSize
!= 64;
772 // Check if the register is a 32-bit register the backend can handle.
773 return X86TargetInfo::validateGlobalRegisterVariable(RegName
, RegSize
,
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
> {
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
{
813 case CC_X86VectorCall
:
814 case CC_IntelOclBicc
:
815 case CC_PreserveMost
:
821 case CC_OpenCLKernel
:
829 // x86-64 Windows Visual Studio target
830 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
831 : public WindowsX86_64TargetInfo
{
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
{
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();
867 // x86-64 Cygwin target
868 class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo
: public X86_64TargetInfo
{
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
);
885 Builder
.defineMacro("_GNU_SOURCE");
889 class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
890 : public DarwinTargetInfo
<X86_64TargetInfo
> {
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
);
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
,
908 // We now know the features we have: we can decide how to align vectors.
910 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
915 class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
916 : public OpenBSDTargetInfo
<X86_64TargetInfo
> {
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
> {
929 AndroidX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
930 : LinuxTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
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
> {
941 AndroidX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
942 : LinuxTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
943 LongDoubleFormat
= &llvm::APFloat::IEEEquad();
946 } // namespace targets
948 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H