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 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
;
304 initFeatureMap(llvm::StringMap
<bool> &Features
, DiagnosticsEngine
&Diags
,
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
)
318 if (getTriple().getArch() == llvm::Triple::x86_64
&& SSELevel
>= AVX
)
320 if (getTriple().getArch() == llvm::Triple::x86
&&
321 MMX3DNowLevel
== NoMMX3DNow
)
326 bool supportsTargetAttributeTune() const override
{
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")
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.
368 case CC_X86VectorCall
:
371 case CC_PreserveMost
:
374 case CC_IntelOclBicc
:
375 case CC_OpenCLKernel
:
384 bool checkArithmeticFenceSupported() const override
{ return true; }
386 CallingConv
getDefaultCallingConv() const override
{
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
)
397 if (AddrSpace
== ptr64
)
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
{
412 X86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
413 : X86TargetInfo(Triple
, Opts
) {
414 DoubleAlign
= LongLongAlign
= 32;
415 LongDoubleWidth
= 96;
416 LongDoubleAlign
= 32;
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
;
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
{
452 bool validateOperandSize(const llvm::StringMap
<bool> &FeatureMap
,
453 StringRef Constraint
, unsigned Size
) const override
{
454 switch (Constraint
[0]) {
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
> {
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
> {
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
> {
514 DarwinI386TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
515 : DarwinTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
516 LongDoubleWidth
= 128;
517 LongDoubleAlign
= 128;
519 MaxVectorAlign
= 256;
520 // The watchOS simulator uses the builtin bool type for Objective-C.
521 llvm::Triple T
= llvm::Triple(Triple
);
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
,
536 // We now know the features we have: we can decide how to align vectors.
538 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
543 // x86-32 Windows target
544 class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
545 : public WindowsTargetInfo
<X86_32TargetInfo
> {
547 WindowsX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
548 : WindowsTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
549 DoubleAlign
= LongLongAlign
= 64;
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
{
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
{
586 MinGWX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
587 : WindowsX86_32TargetInfo(Triple
, Opts
) {
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
{
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",
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
);
619 Builder
.defineMacro("_GNU_SOURCE");
623 // x86-32 Haiku target
624 class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
625 : public HaikuTargetInfo
<X86_32TargetInfo
> {
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__");
638 class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo
: public X86_32TargetInfo
{
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
{
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
{
685 X86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
686 : X86TargetInfo(Triple
, Opts
) {
687 const bool IsX32
= getTriple().isX32();
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;
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
;
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
{
737 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
742 case CC_X86VectorCall
:
743 case CC_IntelOclBicc
:
745 case CC_PreserveMost
:
748 case CC_OpenCLKernel
:
755 CallingConv
getDefaultCallingConv() const override
{
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
770 if (RegName
.equals("rsp") || RegName
.equals("rbp")) {
771 // Check that the register size is 64-bit.
772 HasSizeMismatch
= RegSize
!= 64;
776 // Check if the register is a 32-bit register the backend can handle.
777 return X86TargetInfo::validateGlobalRegisterVariable(RegName
, RegSize
,
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
> {
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
{
817 case CC_X86VectorCall
:
818 case CC_IntelOclBicc
:
819 case CC_PreserveMost
:
825 case CC_OpenCLKernel
:
833 // x86-64 Windows Visual Studio target
834 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
835 : public WindowsX86_64TargetInfo
{
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
{
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();
871 // x86-64 Cygwin target
872 class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo
: public X86_64TargetInfo
{
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
);
889 Builder
.defineMacro("_GNU_SOURCE");
893 class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
894 : public DarwinTargetInfo
<X86_64TargetInfo
> {
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
);
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
,
912 // We now know the features we have: we can decide how to align vectors.
914 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
919 class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
920 : public OpenBSDTargetInfo
<X86_64TargetInfo
> {
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
> {
933 AndroidX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
934 : LinuxTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
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
> {
945 AndroidX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
946 : LinuxTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
947 LongDoubleFormat
= &llvm::APFloat::IEEEquad();
950 } // namespace targets
952 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H