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/Support/Compiler.h"
21 #include "llvm/TargetParser/Triple.h"
22 #include "llvm/TargetParser/X86TargetParser.h"
28 static const unsigned X86AddrSpaceMap
[] = {
35 0, // opencl_global_device
36 0, // opencl_global_host
41 0, // sycl_global_device
42 0, // sycl_global_host
48 0, // hlsl_groupshared
49 // Wasm address space values for this target are dummy values,
50 // as it is only enabled for Wasm targets.
54 // X86 target abstract base class; x86-32 and x86-64 are very close, so
55 // most of the implementation can be shared.
56 class LLVM_LIBRARY_VISIBILITY X86TargetInfo
: public TargetInfo
{
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 HasAVX10_1
= false;
94 bool HasAVX10_1_512
= false;
95 bool HasAVX10_2
= false;
96 bool HasAVX10_2_512
= false;
97 bool HasEVEX512
= false;
98 bool HasAVX512CD
= false;
99 bool HasAVX512VPOPCNTDQ
= false;
100 bool HasAVX512VNNI
= false;
101 bool HasAVX512FP16
= false;
102 bool HasAVX512BF16
= false;
103 bool HasAVX512DQ
= false;
104 bool HasAVX512BITALG
= false;
105 bool HasAVX512BW
= false;
106 bool HasAVX512VL
= false;
107 bool HasAVX512VBMI
= false;
108 bool HasAVX512VBMI2
= false;
109 bool HasAVXIFMA
= false;
110 bool HasAVX512IFMA
= false;
111 bool HasAVX512VP2INTERSECT
= false;
113 bool HasSHA512
= false;
114 bool HasSHSTK
= false;
119 bool HasCX16
= false;
120 bool HasFXSR
= false;
121 bool HasXSAVE
= false;
122 bool HasXSAVEOPT
= false;
123 bool HasXSAVEC
= false;
124 bool HasXSAVES
= false;
125 bool HasMWAITX
= false;
126 bool HasCLZERO
= false;
127 bool HasCLDEMOTE
= false;
128 bool HasPCONFIG
= false;
130 bool HasCLFLUSHOPT
= false;
131 bool HasCLWB
= false;
132 bool HasMOVBE
= false;
133 bool HasMOVRS
= false;
134 bool HasPREFETCHI
= false;
135 bool HasRDPID
= false;
136 bool HasRDPRU
= false;
137 bool HasRetpolineExternalThunk
= false;
138 bool HasLAHFSAHF
= false;
139 bool HasWBNOINVD
= false;
140 bool HasWAITPKG
= false;
141 bool HasMOVDIRI
= false;
142 bool HasMOVDIR64B
= false;
143 bool HasPTWRITE
= false;
144 bool HasINVPCID
= false;
145 bool HasENQCMD
= false;
146 bool HasAVXVNNIINT16
= false;
147 bool HasAMXFP16
= false;
148 bool HasCMPCCXADD
= false;
149 bool HasRAOINT
= false;
150 bool HasAVXVNNIINT8
= false;
151 bool HasAVXNECONVERT
= false;
152 bool HasKL
= false; // For key locker
153 bool HasWIDEKL
= false; // For wide key locker
154 bool HasHRESET
= false;
155 bool HasAVXVNNI
= false;
156 bool HasAMXTILE
= false;
157 bool HasAMXINT8
= false;
158 bool HasAMXBF16
= false;
159 bool HasAMXCOMPLEX
= false;
160 bool HasAMXFP8
= false;
161 bool HasAMXMOVRS
= false;
162 bool HasAMXTRANSPOSE
= false;
163 bool HasAMXAVX512
= false;
164 bool HasAMXTF32
= false;
165 bool HasSERIALIZE
= false;
166 bool HasTSXLDTRK
= false;
167 bool HasUSERMSR
= false;
168 bool HasUINTR
= false;
169 bool HasCRC32
= false;
171 bool HasEGPR
= false;
172 bool HasPush2Pop2
= false;
175 bool HasCCMP
= false;
179 bool HasInlineAsmUseGPR32
= false;
180 bool HasBranchHint
= false;
183 llvm::X86::CPUKind CPU
= llvm::X86::CK_None
;
185 enum FPMathKind
{ FP_Default
, FP_SSE
, FP_387
} FPMath
= FP_Default
;
188 X86TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&)
189 : TargetInfo(Triple
) {
190 BFloat16Width
= BFloat16Align
= 16;
191 BFloat16Format
= &llvm::APFloat::BFloat();
192 LongDoubleFormat
= &llvm::APFloat::x87DoubleExtended();
193 AddrSpaceMap
= &X86AddrSpaceMap
;
195 HasUnalignedAccess
= true;
198 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
200 MaxVectorAlign
= MaxTLSAlign
= 8192u * getCharWidth();
203 const char *getLongDoubleMangling() const override
{
204 return LongDoubleFormat
== &llvm::APFloat::IEEEquad() ? "g" : "e";
207 LangOptions::FPEvalMethodKind
getFPEvalMethod() const override
{
208 // X87 evaluates with 80 bits "long double" precision.
209 return SSELevel
== NoSSE
? LangOptions::FPEvalMethodKind::FEM_Extended
210 : LangOptions::FPEvalMethodKind::FEM_Source
;
213 // EvalMethod `source` is not supported for targets with `NoSSE` feature.
214 bool supportSourceEvalMethod() const override
{ return SSELevel
> NoSSE
; }
216 ArrayRef
<const char *> getGCCRegNames() const override
;
218 ArrayRef
<TargetInfo::GCCRegAlias
> getGCCRegAliases() const override
{
222 ArrayRef
<TargetInfo::AddlRegName
> getGCCAddlRegNames() const override
;
224 bool isSPRegName(StringRef RegName
) const override
{
225 return RegName
== "esp" || RegName
== "rsp";
228 bool supportsCpuSupports() const override
{ return true; }
229 bool supportsCpuIs() const override
{ return true; }
230 bool supportsCpuInit() const override
{ return true; }
232 bool validateCpuSupports(StringRef FeatureStr
) const override
;
234 bool validateCpuIs(StringRef FeatureStr
) const override
;
236 bool validateCPUSpecificCPUDispatch(StringRef Name
) const override
;
238 char CPUSpecificManglingCharacter(StringRef Name
) const override
;
240 void getCPUSpecificCPUDispatchFeatures(
242 llvm::SmallVectorImpl
<StringRef
> &Features
) const override
;
244 std::optional
<unsigned> getCPUCacheLineSize() const override
;
246 bool validateAsmConstraint(const char *&Name
,
247 TargetInfo::ConstraintInfo
&info
) const override
;
249 bool validateGlobalRegisterVariable(StringRef RegName
, unsigned RegSize
,
250 bool &HasSizeMismatch
) const override
{
251 // esp and ebp are the only 32-bit registers the x86 backend can currently
253 if (RegName
== "esp" || RegName
== "ebp") {
254 // Check that the register size is 32-bit.
255 HasSizeMismatch
= RegSize
!= 32;
262 bool validateOutputSize(const llvm::StringMap
<bool> &FeatureMap
,
263 StringRef Constraint
, unsigned Size
) const override
;
265 bool validateInputSize(const llvm::StringMap
<bool> &FeatureMap
,
266 StringRef Constraint
, unsigned Size
) const override
;
269 checkCFProtectionReturnSupported(DiagnosticsEngine
&Diags
) const override
{
270 if (CPU
== llvm::X86::CK_None
|| CPU
>= llvm::X86::CK_PentiumPro
)
272 return TargetInfo::checkCFProtectionReturnSupported(Diags
);
276 checkCFProtectionBranchSupported(DiagnosticsEngine
&Diags
) const override
{
277 if (CPU
== llvm::X86::CK_None
|| CPU
>= llvm::X86::CK_PentiumPro
)
279 return TargetInfo::checkCFProtectionBranchSupported(Diags
);
282 virtual bool validateOperandSize(const llvm::StringMap
<bool> &FeatureMap
,
283 StringRef Constraint
, unsigned Size
) const;
285 std::string
convertConstraint(const char *&Constraint
) const override
;
286 std::string_view
getClobbers() const override
{
287 return "~{dirflag},~{fpsr},~{flags}";
290 StringRef
getConstraintRegister(StringRef Constraint
,
291 StringRef Expression
) const override
{
292 StringRef::iterator I
, E
;
293 for (I
= Constraint
.begin(), E
= Constraint
.end(); I
!= E
; ++I
) {
294 if (isalpha(*I
) || *I
== '@')
300 // For the register constraints, return the matching register name
313 // In case the constraint is 'r' we need to return Expression
316 // Double letters Y<x> constraints
318 if ((++I
!= E
) && ((*I
== '0') || (*I
== 'z')))
327 bool useFP16ConversionIntrinsics() const override
{
331 void getTargetDefines(const LangOptions
&Opts
,
332 MacroBuilder
&Builder
) const override
;
334 void setFeatureEnabled(llvm::StringMap
<bool> &Features
, StringRef Name
,
335 bool Enabled
) const final
;
338 initFeatureMap(llvm::StringMap
<bool> &Features
, DiagnosticsEngine
&Diags
,
340 const std::vector
<std::string
> &FeaturesVec
) const override
;
342 bool isValidFeatureName(StringRef Name
) const override
;
344 bool hasFeature(StringRef Feature
) const final
;
346 bool handleTargetFeatures(std::vector
<std::string
> &Features
,
347 DiagnosticsEngine
&Diags
) override
;
349 StringRef
getABI() const override
{
350 if (getTriple().getArch() == llvm::Triple::x86_64
&& SSELevel
>= AVX512F
)
352 if (getTriple().getArch() == llvm::Triple::x86_64
&& SSELevel
>= AVX
)
354 if (getTriple().getArch() == llvm::Triple::x86
&& !HasMMX
)
359 bool supportsTargetAttributeTune() const override
{
363 bool isValidCPUName(StringRef Name
) const override
{
364 bool Only64Bit
= getTriple().getArch() != llvm::Triple::x86
;
365 return llvm::X86::parseArchX86(Name
, Only64Bit
) != llvm::X86::CK_None
;
368 bool isValidTuneCPUName(StringRef Name
) const override
{
369 if (Name
== "generic")
372 // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
373 // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
374 // since mtune was ignored by clang for so long.
375 return llvm::X86::parseTuneCPU(Name
) != llvm::X86::CK_None
;
378 void fillValidCPUList(SmallVectorImpl
<StringRef
> &Values
) const override
;
379 void fillValidTuneCPUList(SmallVectorImpl
<StringRef
> &Values
) const override
;
381 bool setCPU(const std::string
&Name
) override
{
382 bool Only64Bit
= getTriple().getArch() != llvm::Triple::x86
;
383 CPU
= llvm::X86::parseArchX86(Name
, Only64Bit
);
384 return CPU
!= llvm::X86::CK_None
;
387 unsigned getFMVPriority(ArrayRef
<StringRef
> Features
) const override
;
389 bool setFPMath(StringRef Name
) override
;
391 bool supportsExtendIntArgs() const override
{
392 return getTriple().getArch() != llvm::Triple::x86
;
395 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
396 // Most of the non-ARM calling conventions are i386 conventions.
401 case CC_X86VectorCall
:
404 case CC_PreserveMost
:
407 case CC_IntelOclBicc
:
408 case CC_OpenCLKernel
:
417 bool checkArithmeticFenceSupported() const override
{ return true; }
419 CallingConv
getDefaultCallingConv() const override
{
423 bool hasSjLjLowering() const override
{ return true; }
425 void setSupportedOpenCLOpts() override
{ supportAllOpenCLOpts(); }
427 uint64_t getPointerWidthV(LangAS AS
) const override
{
428 unsigned TargetAddrSpace
= getTargetAddressSpace(AS
);
429 if (TargetAddrSpace
== ptr32_sptr
|| TargetAddrSpace
== ptr32_uptr
)
431 if (TargetAddrSpace
== ptr64
)
436 uint64_t getPointerAlignV(LangAS AddrSpace
) const override
{
437 return getPointerWidthV(AddrSpace
);
442 // X86-32 generic target
443 class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo
: public X86TargetInfo
{
445 X86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
446 : X86TargetInfo(Triple
, Opts
) {
447 DoubleAlign
= LongLongAlign
= 32;
448 LongDoubleWidth
= 96;
449 LongDoubleAlign
= 32;
451 resetDataLayout(Triple
.isOSBinFormatMachO()
452 ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
453 "128-f64:32:64-f80:32-n8:16:32-S128"
454 : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
455 "128-f64:32:64-f80:32-n8:16:32-S128",
456 Triple
.isOSBinFormatMachO() ? "_" : "");
457 SizeType
= UnsignedInt
;
458 PtrDiffType
= SignedInt
;
459 IntPtrType
= SignedInt
;
462 // Use fpret for all types.
463 RealTypeUsesObjCFPRetMask
=
464 (unsigned)(FloatModeKind::Float
| FloatModeKind::Double
|
465 FloatModeKind::LongDouble
);
467 // x86-32 has atomics up to 8 bytes
468 MaxAtomicPromoteWidth
= 64;
469 MaxAtomicInlineWidth
= 32;
472 BuiltinVaListKind
getBuiltinVaListKind() const override
{
473 return TargetInfo::CharPtrBuiltinVaList
;
476 int getEHDataRegisterNumber(unsigned RegNo
) const override
{
484 bool validateOperandSize(const llvm::StringMap
<bool> &FeatureMap
,
485 StringRef Constraint
, unsigned Size
) const override
{
486 switch (Constraint
[0]) {
503 return X86TargetInfo::validateOperandSize(FeatureMap
, Constraint
, Size
);
506 void setMaxAtomicWidth() override
{
507 if (hasFeature("cx8"))
508 MaxAtomicInlineWidth
= 64;
511 ArrayRef
<Builtin::Info
> getTargetBuiltins() const override
;
513 bool hasBitIntType() const override
{ return true; }
514 size_t getMaxBitIntWidth() const override
{
515 return llvm::IntegerType::MAX_INT_BITS
;
519 class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
520 : public NetBSDTargetInfo
<X86_32TargetInfo
> {
522 NetBSDI386TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
523 : NetBSDTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {}
526 class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
527 : public OpenBSDTargetInfo
<X86_32TargetInfo
> {
529 OpenBSDI386TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
530 : OpenBSDTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
531 SizeType
= UnsignedLong
;
532 IntPtrType
= SignedLong
;
533 PtrDiffType
= SignedLong
;
537 class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
538 : public DarwinTargetInfo
<X86_32TargetInfo
> {
540 DarwinI386TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
541 : DarwinTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
542 LongDoubleWidth
= 128;
543 LongDoubleAlign
= 128;
545 MaxVectorAlign
= 256;
546 // The watchOS simulator uses the builtin bool type for Objective-C.
547 llvm::Triple T
= llvm::Triple(Triple
);
549 UseSignedCharForObjCBool
= false;
550 SizeType
= UnsignedLong
;
551 IntPtrType
= SignedLong
;
552 resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-"
553 "f64:32:64-f80:128-n8:16:32-S128",
555 HasAlignMac68kSupport
= true;
558 bool handleTargetFeatures(std::vector
<std::string
> &Features
,
559 DiagnosticsEngine
&Diags
) override
{
560 if (!DarwinTargetInfo
<X86_32TargetInfo
>::handleTargetFeatures(Features
,
563 // We now know the features we have: we can decide how to align vectors.
565 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
570 // x86-32 Windows target
571 class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
572 : public WindowsTargetInfo
<X86_32TargetInfo
> {
574 WindowsX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
575 : WindowsTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
576 DoubleAlign
= LongLongAlign
= 64;
578 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
579 bool IsMSVC
= getTriple().isWindowsMSVCEnvironment();
580 std::string Layout
= IsWinCOFF
? "e-m:x" : "e-m:e";
581 Layout
+= "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-";
582 Layout
+= IsMSVC
? "f80:128" : "f80:32";
583 Layout
+= "-n8:16:32-a:0:32-S32";
584 resetDataLayout(Layout
, IsWinCOFF
? "_" : "");
588 // x86-32 Windows Visual Studio target
589 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
590 : public WindowsX86_32TargetInfo
{
592 MicrosoftX86_32TargetInfo(const llvm::Triple
&Triple
,
593 const TargetOptions
&Opts
)
594 : WindowsX86_32TargetInfo(Triple
, Opts
) {
595 LongDoubleWidth
= LongDoubleAlign
= 64;
596 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
599 void getTargetDefines(const LangOptions
&Opts
,
600 MacroBuilder
&Builder
) const override
{
601 WindowsX86_32TargetInfo::getTargetDefines(Opts
, Builder
);
602 // The value of the following reflects processor type.
603 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
604 // We lost the original triple, so we use the default.
605 Builder
.defineMacro("_M_IX86", "600");
609 // x86-32 MinGW target
610 class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
611 : public WindowsX86_32TargetInfo
{
613 MinGWX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
614 : WindowsX86_32TargetInfo(Triple
, Opts
) {
618 void getTargetDefines(const LangOptions
&Opts
,
619 MacroBuilder
&Builder
) const override
{
620 WindowsX86_32TargetInfo::getTargetDefines(Opts
, Builder
);
621 Builder
.defineMacro("_X86_");
625 // x86-32 Cygwin target
626 class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo
: public X86_32TargetInfo
{
628 CygwinX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
629 : X86_32TargetInfo(Triple
, Opts
) {
630 this->WCharType
= TargetInfo::UnsignedShort
;
631 DoubleAlign
= LongLongAlign
= 64;
632 resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"
633 "i128:128-f80:32-n8:16:32-a:0:32-S32",
637 void getTargetDefines(const LangOptions
&Opts
,
638 MacroBuilder
&Builder
) const override
{
639 X86_32TargetInfo::getTargetDefines(Opts
, Builder
);
640 Builder
.defineMacro("_X86_");
641 Builder
.defineMacro("__CYGWIN__");
642 Builder
.defineMacro("__CYGWIN32__");
643 addCygMingDefines(Opts
, Builder
);
644 DefineStd(Builder
, "unix", Opts
);
646 Builder
.defineMacro("_GNU_SOURCE");
650 // x86-32 Haiku target
651 class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
652 : public HaikuTargetInfo
<X86_32TargetInfo
> {
654 HaikuX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
655 : HaikuTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {}
657 void getTargetDefines(const LangOptions
&Opts
,
658 MacroBuilder
&Builder
) const override
{
659 HaikuTargetInfo
<X86_32TargetInfo
>::getTargetDefines(Opts
, Builder
);
660 Builder
.defineMacro("__INTEL__");
665 class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo
: public X86_32TargetInfo
{
667 MCUX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
668 : X86_32TargetInfo(Triple
, Opts
) {
669 LongDoubleWidth
= 64;
670 DefaultAlignForAttributeAligned
= 32;
671 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
672 resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-"
673 "f64:32-f128:32-n8:16:32-a:0:32-S32");
674 WIntType
= UnsignedInt
;
677 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
678 // On MCU we support only C calling convention.
679 return CC
== CC_C
? CCCR_OK
: CCCR_Warning
;
682 void getTargetDefines(const LangOptions
&Opts
,
683 MacroBuilder
&Builder
) const override
{
684 X86_32TargetInfo::getTargetDefines(Opts
, Builder
);
685 Builder
.defineMacro("__iamcu");
686 Builder
.defineMacro("__iamcu__");
689 bool allowsLargerPreferedTypeAlignment() const override
{ return false; }
692 // x86-32 RTEMS target
693 class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo
: public X86_32TargetInfo
{
695 RTEMSX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
696 : X86_32TargetInfo(Triple
, Opts
) {
697 SizeType
= UnsignedLong
;
698 IntPtrType
= SignedLong
;
699 PtrDiffType
= SignedLong
;
702 void getTargetDefines(const LangOptions
&Opts
,
703 MacroBuilder
&Builder
) const override
{
704 X86_32TargetInfo::getTargetDefines(Opts
, Builder
);
705 Builder
.defineMacro("__INTEL__");
706 Builder
.defineMacro("__rtems__");
710 // x86-64 generic target
711 class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo
: public X86TargetInfo
{
713 X86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
714 : X86TargetInfo(Triple
, Opts
) {
715 const bool IsX32
= getTriple().isX32();
717 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
718 LongWidth
= LongAlign
= PointerWidth
= PointerAlign
= IsX32
? 32 : 64;
719 LongDoubleWidth
= 128;
720 LongDoubleAlign
= 128;
721 LargeArrayMinWidth
= 128;
722 LargeArrayAlign
= 128;
724 SizeType
= IsX32
? UnsignedInt
: UnsignedLong
;
725 PtrDiffType
= IsX32
? SignedInt
: SignedLong
;
726 IntPtrType
= IsX32
? SignedInt
: SignedLong
;
727 IntMaxType
= IsX32
? SignedLongLong
: SignedLong
;
728 Int64Type
= IsX32
? SignedLongLong
: SignedLong
;
731 // Pointers are 32-bit in x32.
732 resetDataLayout(IsX32
? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
733 "i64:64-i128:128-f80:128-n8:16:32:64-S128"
734 : IsWinCOFF
? "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:"
735 "64-i128:128-f80:128-n8:16:32:64-S128"
736 : "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:"
737 "64-i128:128-f80:128-n8:16:32:64-S128");
739 // Use fpret only for long double.
740 RealTypeUsesObjCFPRetMask
= (unsigned)FloatModeKind::LongDouble
;
742 // Use fp2ret for _Complex long double.
743 ComplexLongDoubleUsesFP2Ret
= true;
745 // Make __builtin_ms_va_list available.
746 HasBuiltinMSVaList
= true;
748 // x86-64 has atomics up to 16 bytes.
749 MaxAtomicPromoteWidth
= 128;
750 MaxAtomicInlineWidth
= 64;
753 BuiltinVaListKind
getBuiltinVaListKind() const override
{
754 return TargetInfo::X86_64ABIBuiltinVaList
;
757 int getEHDataRegisterNumber(unsigned RegNo
) const override
{
765 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
770 case CC_X86VectorCall
:
771 case CC_IntelOclBicc
:
773 case CC_PreserveMost
:
775 case CC_PreserveNone
:
777 case CC_OpenCLKernel
:
784 CallingConv
getDefaultCallingConv() const override
{
788 // for x32 we need it here explicitly
789 bool hasInt128Type() const override
{ return true; }
791 unsigned getUnwindWordWidth() const override
{ return 64; }
793 unsigned getRegisterWidth() const override
{ return 64; }
795 bool validateGlobalRegisterVariable(StringRef RegName
, unsigned RegSize
,
796 bool &HasSizeMismatch
) const override
{
797 // rsp and rbp are the only 64-bit registers the x86 backend can currently
799 if (RegName
== "rsp" || RegName
== "rbp") {
800 // Check that the register size is 64-bit.
801 HasSizeMismatch
= RegSize
!= 64;
805 // Check if the register is a 32-bit register the backend can handle.
806 return X86TargetInfo::validateGlobalRegisterVariable(RegName
, RegSize
,
810 void setMaxAtomicWidth() override
{
811 if (hasFeature("cx16"))
812 MaxAtomicInlineWidth
= 128;
815 ArrayRef
<Builtin::Info
> getTargetBuiltins() const override
;
817 bool hasBitIntType() const override
{ return true; }
818 size_t getMaxBitIntWidth() const override
{
819 return llvm::IntegerType::MAX_INT_BITS
;
823 // x86-64 UEFI target
824 class LLVM_LIBRARY_VISIBILITY UEFIX86_64TargetInfo
825 : public UEFITargetInfo
<X86_64TargetInfo
> {
827 UEFIX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
828 : UEFITargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
829 this->TheCXXABI
.set(TargetCXXABI::Microsoft
);
830 this->MaxTLSAlign
= 8192u * this->getCharWidth();
831 this->resetDataLayout("e-m:w-p270:32:32-p271:32:32-p272:64:64-"
832 "i64:64-i128:128-f80:128-n8:16:32:64-S128");
835 void getTargetDefines(const LangOptions
&Opts
,
836 MacroBuilder
&Builder
) const override
{
837 getOSDefines(Opts
, X86TargetInfo::getTriple(), Builder
);
840 BuiltinVaListKind
getBuiltinVaListKind() const override
{
841 return TargetInfo::CharPtrBuiltinVaList
;
844 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
854 TargetInfo::CallingConvKind
855 getCallingConvKind(bool ClangABICompat4
) const override
{
856 return CCK_MicrosoftWin64
;
860 // x86-64 Windows target
861 class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
862 : public WindowsTargetInfo
<X86_64TargetInfo
> {
864 WindowsX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
865 : WindowsTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
866 LongWidth
= LongAlign
= 32;
867 DoubleAlign
= LongLongAlign
= 64;
868 IntMaxType
= SignedLongLong
;
869 Int64Type
= SignedLongLong
;
870 SizeType
= UnsignedLongLong
;
871 PtrDiffType
= SignedLongLong
;
872 IntPtrType
= SignedLongLong
;
875 BuiltinVaListKind
getBuiltinVaListKind() const override
{
876 return TargetInfo::CharPtrBuiltinVaList
;
879 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
886 case CC_X86VectorCall
:
887 case CC_IntelOclBicc
:
888 case CC_PreserveMost
:
890 case CC_PreserveNone
:
895 case CC_OpenCLKernel
:
903 // x86-64 Windows Visual Studio target
904 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
905 : public WindowsX86_64TargetInfo
{
907 MicrosoftX86_64TargetInfo(const llvm::Triple
&Triple
,
908 const TargetOptions
&Opts
)
909 : WindowsX86_64TargetInfo(Triple
, Opts
) {
910 LongDoubleWidth
= LongDoubleAlign
= 64;
911 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
914 void getTargetDefines(const LangOptions
&Opts
,
915 MacroBuilder
&Builder
) const override
{
916 WindowsX86_64TargetInfo::getTargetDefines(Opts
, Builder
);
917 Builder
.defineMacro("_M_X64", "100");
918 Builder
.defineMacro("_M_AMD64", "100");
921 TargetInfo::CallingConvKind
922 getCallingConvKind(bool ClangABICompat4
) const override
{
923 return CCK_MicrosoftWin64
;
927 // x86-64 MinGW target
928 class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
929 : public WindowsX86_64TargetInfo
{
931 MinGWX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
932 : WindowsX86_64TargetInfo(Triple
, Opts
) {
933 // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
934 // with x86 FP ops. Weird.
935 LongDoubleWidth
= LongDoubleAlign
= 128;
936 LongDoubleFormat
= &llvm::APFloat::x87DoubleExtended();
941 // x86-64 Cygwin target
942 class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo
: public X86_64TargetInfo
{
944 CygwinX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
945 : X86_64TargetInfo(Triple
, Opts
) {
946 this->WCharType
= TargetInfo::UnsignedShort
;
947 TLSSupported
= false;
950 void getTargetDefines(const LangOptions
&Opts
,
951 MacroBuilder
&Builder
) const override
{
952 X86_64TargetInfo::getTargetDefines(Opts
, Builder
);
953 Builder
.defineMacro("__x86_64__");
954 Builder
.defineMacro("__CYGWIN__");
955 Builder
.defineMacro("__CYGWIN64__");
956 addCygMingDefines(Opts
, Builder
);
957 DefineStd(Builder
, "unix", Opts
);
959 Builder
.defineMacro("_GNU_SOURCE");
963 class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
964 : public DarwinTargetInfo
<X86_64TargetInfo
> {
966 DarwinX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
967 : DarwinTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
968 Int64Type
= SignedLongLong
;
969 // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
970 llvm::Triple T
= llvm::Triple(Triple
);
972 UseSignedCharForObjCBool
= false;
973 resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
974 "f80:128-n8:16:32:64-S128",
978 bool handleTargetFeatures(std::vector
<std::string
> &Features
,
979 DiagnosticsEngine
&Diags
) override
{
980 if (!DarwinTargetInfo
<X86_64TargetInfo
>::handleTargetFeatures(Features
,
983 // We now know the features we have: we can decide how to align vectors.
985 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
990 class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
991 : public OpenBSDTargetInfo
<X86_64TargetInfo
> {
993 OpenBSDX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
994 : OpenBSDTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
995 IntMaxType
= SignedLongLong
;
996 Int64Type
= SignedLongLong
;
1000 // x86_32 Android target
1001 class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
1002 : public LinuxTargetInfo
<X86_32TargetInfo
> {
1004 AndroidX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
1005 : LinuxTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
1007 LongDoubleWidth
= 64;
1008 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
1012 // x86_64 Android target
1013 class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
1014 : public LinuxTargetInfo
<X86_64TargetInfo
> {
1016 AndroidX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
1017 : LinuxTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
1018 LongDoubleFormat
= &llvm::APFloat::IEEEquad();
1022 // x86_32 OHOS target
1023 class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo
1024 : public OHOSTargetInfo
<X86_32TargetInfo
> {
1026 OHOSX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
1027 : OHOSTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
1029 LongDoubleWidth
= 64;
1030 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
1034 // x86_64 OHOS target
1035 class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo
1036 : public OHOSTargetInfo
<X86_64TargetInfo
> {
1038 OHOSX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
1039 : OHOSTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
1040 LongDoubleFormat
= &llvm::APFloat::IEEEquad();
1043 } // namespace targets
1044 } // namespace clang
1045 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H