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
{
75 } MMX3DNowLevel
= NoMMX3DNow
;
76 enum XOPEnum
{ NoXOP
, SSE4A
, FMA4
, XOP
} XOPLevel
= NoXOP
;
77 enum AddrSpace
{ ptr32_sptr
= 270, ptr32_uptr
= 271, ptr64
= 272 };
81 bool HasPCLMUL
= false;
82 bool HasVPCLMULQDQ
= false;
84 bool HasLZCNT
= false;
85 bool HasRDRND
= false;
86 bool HasFSGSBASE
= false;
89 bool HasPOPCNT
= false;
91 bool HasPRFCHW
= false;
92 bool HasRDSEED
= false;
98 bool HasAVX10_1
= false;
99 bool HasAVX10_1_512
= false;
100 bool HasEVEX512
= false;
101 bool HasAVX512CD
= false;
102 bool HasAVX512VPOPCNTDQ
= false;
103 bool HasAVX512VNNI
= false;
104 bool HasAVX512FP16
= false;
105 bool HasAVX512BF16
= false;
106 bool HasAVX512ER
= false;
107 bool HasAVX512PF
= false;
108 bool HasAVX512DQ
= false;
109 bool HasAVX512BITALG
= false;
110 bool HasAVX512BW
= false;
111 bool HasAVX512VL
= false;
112 bool HasAVX512VBMI
= false;
113 bool HasAVX512VBMI2
= false;
114 bool HasAVXIFMA
= false;
115 bool HasAVX512IFMA
= false;
116 bool HasAVX512VP2INTERSECT
= false;
118 bool HasSHA512
= false;
119 bool HasSHSTK
= false;
124 bool HasCX16
= false;
125 bool HasFXSR
= false;
126 bool HasXSAVE
= false;
127 bool HasXSAVEOPT
= false;
128 bool HasXSAVEC
= false;
129 bool HasXSAVES
= false;
130 bool HasMWAITX
= false;
131 bool HasCLZERO
= false;
132 bool HasCLDEMOTE
= false;
133 bool HasPCONFIG
= false;
135 bool HasCLFLUSHOPT
= false;
136 bool HasCLWB
= false;
137 bool HasMOVBE
= false;
138 bool HasPREFETCHI
= false;
139 bool HasPREFETCHWT1
= false;
140 bool HasRDPID
= false;
141 bool HasRDPRU
= false;
142 bool HasRetpolineExternalThunk
= false;
143 bool HasLAHFSAHF
= false;
144 bool HasWBNOINVD
= false;
145 bool HasWAITPKG
= false;
146 bool HasMOVDIRI
= false;
147 bool HasMOVDIR64B
= false;
148 bool HasPTWRITE
= false;
149 bool HasINVPCID
= false;
150 bool HasENQCMD
= false;
151 bool HasAVXVNNIINT16
= false;
152 bool HasAMXFP16
= false;
153 bool HasCMPCCXADD
= false;
154 bool HasRAOINT
= false;
155 bool HasAVXVNNIINT8
= false;
156 bool HasAVXNECONVERT
= false;
157 bool HasKL
= false; // For key locker
158 bool HasWIDEKL
= false; // For wide key locker
159 bool HasHRESET
= false;
160 bool HasAVXVNNI
= false;
161 bool HasAMXTILE
= false;
162 bool HasAMXINT8
= false;
163 bool HasAMXBF16
= false;
164 bool HasAMXCOMPLEX
= false;
165 bool HasSERIALIZE
= false;
166 bool HasTSXLDTRK
= false;
167 bool HasUSERMSR
= false;
168 bool HasUINTR
= false;
169 bool HasCRC32
= false;
173 llvm::X86::CPUKind CPU
= llvm::X86::CK_None
;
175 enum FPMathKind
{ FP_Default
, FP_SSE
, FP_387
} FPMath
= FP_Default
;
178 X86TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&)
179 : TargetInfo(Triple
) {
180 BFloat16Width
= BFloat16Align
= 16;
181 BFloat16Format
= &llvm::APFloat::BFloat();
182 LongDoubleFormat
= &llvm::APFloat::x87DoubleExtended();
183 AddrSpaceMap
= &X86AddrSpaceMap
;
187 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
189 MaxVectorAlign
= MaxTLSAlign
= 8192u * getCharWidth();
192 const char *getLongDoubleMangling() const override
{
193 return LongDoubleFormat
== &llvm::APFloat::IEEEquad() ? "g" : "e";
196 LangOptions::FPEvalMethodKind
getFPEvalMethod() const override
{
197 // X87 evaluates with 80 bits "long double" precision.
198 return SSELevel
== NoSSE
? LangOptions::FPEvalMethodKind::FEM_Extended
199 : LangOptions::FPEvalMethodKind::FEM_Source
;
202 // EvalMethod `source` is not supported for targets with `NoSSE` feature.
203 bool supportSourceEvalMethod() const override
{ return SSELevel
> NoSSE
; }
205 ArrayRef
<const char *> getGCCRegNames() const override
;
207 ArrayRef
<TargetInfo::GCCRegAlias
> getGCCRegAliases() const override
{
211 ArrayRef
<TargetInfo::AddlRegName
> getGCCAddlRegNames() const override
;
213 bool isSPRegName(StringRef RegName
) const override
{
214 return RegName
.equals("esp") || RegName
.equals("rsp");
217 bool validateCpuSupports(StringRef FeatureStr
) const override
;
219 bool validateCpuIs(StringRef FeatureStr
) const override
;
221 bool validateCPUSpecificCPUDispatch(StringRef Name
) const override
;
223 char CPUSpecificManglingCharacter(StringRef Name
) const override
;
225 void getCPUSpecificCPUDispatchFeatures(
227 llvm::SmallVectorImpl
<StringRef
> &Features
) const override
;
229 std::optional
<unsigned> getCPUCacheLineSize() const override
;
231 bool validateAsmConstraint(const char *&Name
,
232 TargetInfo::ConstraintInfo
&info
) const override
;
234 bool validateGlobalRegisterVariable(StringRef RegName
, unsigned RegSize
,
235 bool &HasSizeMismatch
) const override
{
236 // esp and ebp are the only 32-bit registers the x86 backend can currently
238 if (RegName
.equals("esp") || RegName
.equals("ebp")) {
239 // Check that the register size is 32-bit.
240 HasSizeMismatch
= RegSize
!= 32;
247 bool validateOutputSize(const llvm::StringMap
<bool> &FeatureMap
,
248 StringRef Constraint
, unsigned Size
) const override
;
250 bool validateInputSize(const llvm::StringMap
<bool> &FeatureMap
,
251 StringRef Constraint
, unsigned Size
) const override
;
254 checkCFProtectionReturnSupported(DiagnosticsEngine
&Diags
) const override
{
255 if (CPU
== llvm::X86::CK_None
|| CPU
>= llvm::X86::CK_PentiumPro
)
257 return TargetInfo::checkCFProtectionReturnSupported(Diags
);
261 checkCFProtectionBranchSupported(DiagnosticsEngine
&Diags
) const override
{
262 if (CPU
== llvm::X86::CK_None
|| CPU
>= llvm::X86::CK_PentiumPro
)
264 return TargetInfo::checkCFProtectionBranchSupported(Diags
);
267 virtual bool validateOperandSize(const llvm::StringMap
<bool> &FeatureMap
,
268 StringRef Constraint
, unsigned Size
) const;
270 std::string
convertConstraint(const char *&Constraint
) const override
;
271 std::string_view
getClobbers() const override
{
272 return "~{dirflag},~{fpsr},~{flags}";
275 StringRef
getConstraintRegister(StringRef Constraint
,
276 StringRef Expression
) const override
{
277 StringRef::iterator I
, E
;
278 for (I
= Constraint
.begin(), E
= Constraint
.end(); I
!= E
; ++I
) {
279 if (isalpha(*I
) || *I
== '@')
285 // For the register constraints, return the matching register name
298 // In case the constraint is 'r' we need to return Expression
301 // Double letters Y<x> constraints
303 if ((++I
!= E
) && ((*I
== '0') || (*I
== 'z')))
312 bool useFP16ConversionIntrinsics() const override
{
316 void getTargetDefines(const LangOptions
&Opts
,
317 MacroBuilder
&Builder
) const override
;
319 void setFeatureEnabled(llvm::StringMap
<bool> &Features
, StringRef Name
,
320 bool Enabled
) const final
;
323 initFeatureMap(llvm::StringMap
<bool> &Features
, DiagnosticsEngine
&Diags
,
325 const std::vector
<std::string
> &FeaturesVec
) const override
;
327 bool isValidFeatureName(StringRef Name
) const override
;
329 bool hasFeature(StringRef Feature
) const final
;
331 bool handleTargetFeatures(std::vector
<std::string
> &Features
,
332 DiagnosticsEngine
&Diags
) override
;
334 StringRef
getABI() const override
{
335 if (getTriple().getArch() == llvm::Triple::x86_64
&& SSELevel
>= AVX512F
)
337 if (getTriple().getArch() == llvm::Triple::x86_64
&& SSELevel
>= AVX
)
339 if (getTriple().getArch() == llvm::Triple::x86
&&
340 MMX3DNowLevel
== NoMMX3DNow
)
345 bool supportsTargetAttributeTune() const override
{
349 bool isValidCPUName(StringRef Name
) const override
{
350 bool Only64Bit
= getTriple().getArch() != llvm::Triple::x86
;
351 return llvm::X86::parseArchX86(Name
, Only64Bit
) != llvm::X86::CK_None
;
354 bool isValidTuneCPUName(StringRef Name
) const override
{
355 if (Name
== "generic")
358 // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
359 // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
360 // since mtune was ignored by clang for so long.
361 return llvm::X86::parseTuneCPU(Name
) != llvm::X86::CK_None
;
364 void fillValidCPUList(SmallVectorImpl
<StringRef
> &Values
) const override
;
365 void fillValidTuneCPUList(SmallVectorImpl
<StringRef
> &Values
) const override
;
367 bool setCPU(const std::string
&Name
) override
{
368 bool Only64Bit
= getTriple().getArch() != llvm::Triple::x86
;
369 CPU
= llvm::X86::parseArchX86(Name
, Only64Bit
);
370 return CPU
!= llvm::X86::CK_None
;
373 unsigned multiVersionSortPriority(StringRef Name
) const override
;
375 bool setFPMath(StringRef Name
) override
;
377 bool supportsExtendIntArgs() const override
{
378 return getTriple().getArch() != llvm::Triple::x86
;
381 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
382 // Most of the non-ARM calling conventions are i386 conventions.
387 case CC_X86VectorCall
:
390 case CC_PreserveMost
:
393 case CC_IntelOclBicc
:
394 case CC_OpenCLKernel
:
403 bool checkArithmeticFenceSupported() const override
{ return true; }
405 CallingConv
getDefaultCallingConv() const override
{
409 bool hasSjLjLowering() const override
{ return true; }
411 void setSupportedOpenCLOpts() override
{ supportAllOpenCLOpts(); }
413 uint64_t getPointerWidthV(LangAS AS
) const override
{
414 unsigned TargetAddrSpace
= getTargetAddressSpace(AS
);
415 if (TargetAddrSpace
== ptr32_sptr
|| TargetAddrSpace
== ptr32_uptr
)
417 if (TargetAddrSpace
== ptr64
)
422 uint64_t getPointerAlignV(LangAS AddrSpace
) const override
{
423 return getPointerWidthV(AddrSpace
);
428 // X86-32 generic target
429 class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo
: public X86TargetInfo
{
431 X86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
432 : X86TargetInfo(Triple
, Opts
) {
433 DoubleAlign
= LongLongAlign
= 32;
434 LongDoubleWidth
= 96;
435 LongDoubleAlign
= 32;
437 resetDataLayout(Triple
.isOSBinFormatMachO()
438 ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
439 "128-f64:32:64-f80:32-n8:16:32-S128"
440 : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
441 "128-f64:32:64-f80:32-n8:16:32-S128",
442 Triple
.isOSBinFormatMachO() ? "_" : "");
443 SizeType
= UnsignedInt
;
444 PtrDiffType
= SignedInt
;
445 IntPtrType
= SignedInt
;
448 // Use fpret for all types.
449 RealTypeUsesObjCFPRetMask
=
450 (unsigned)(FloatModeKind::Float
| FloatModeKind::Double
|
451 FloatModeKind::LongDouble
);
453 // x86-32 has atomics up to 8 bytes
454 MaxAtomicPromoteWidth
= 64;
455 MaxAtomicInlineWidth
= 32;
458 BuiltinVaListKind
getBuiltinVaListKind() const override
{
459 return TargetInfo::CharPtrBuiltinVaList
;
462 int getEHDataRegisterNumber(unsigned RegNo
) const override
{
470 bool validateOperandSize(const llvm::StringMap
<bool> &FeatureMap
,
471 StringRef Constraint
, unsigned Size
) const override
{
472 switch (Constraint
[0]) {
489 return X86TargetInfo::validateOperandSize(FeatureMap
, Constraint
, Size
);
492 void setMaxAtomicWidth() override
{
493 if (hasFeature("cx8"))
494 MaxAtomicInlineWidth
= 64;
497 ArrayRef
<Builtin::Info
> getTargetBuiltins() const override
;
499 bool hasBitIntType() const override
{ return true; }
500 size_t getMaxBitIntWidth() const override
{
501 return llvm::IntegerType::MAX_INT_BITS
;
505 class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
506 : public NetBSDTargetInfo
<X86_32TargetInfo
> {
508 NetBSDI386TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
509 : NetBSDTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {}
511 LangOptions::FPEvalMethodKind
getFPEvalMethod() const override
{
512 VersionTuple OsVersion
= getTriple().getOSVersion();
513 // New NetBSD uses the default rounding mode.
514 if (OsVersion
>= VersionTuple(6, 99, 26) || OsVersion
.getMajor() == 0)
515 return X86_32TargetInfo::getFPEvalMethod();
516 // NetBSD before 6.99.26 defaults to "double" rounding.
517 return LangOptions::FPEvalMethodKind::FEM_Double
;
521 class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
522 : public OpenBSDTargetInfo
<X86_32TargetInfo
> {
524 OpenBSDI386TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
525 : OpenBSDTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
526 SizeType
= UnsignedLong
;
527 IntPtrType
= SignedLong
;
528 PtrDiffType
= SignedLong
;
532 class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
533 : public DarwinTargetInfo
<X86_32TargetInfo
> {
535 DarwinI386TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
536 : DarwinTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
537 LongDoubleWidth
= 128;
538 LongDoubleAlign
= 128;
540 MaxVectorAlign
= 256;
541 // The watchOS simulator uses the builtin bool type for Objective-C.
542 llvm::Triple T
= llvm::Triple(Triple
);
544 UseSignedCharForObjCBool
= false;
545 SizeType
= UnsignedLong
;
546 IntPtrType
= SignedLong
;
547 resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-"
548 "f64:32:64-f80:128-n8:16:32-S128",
550 HasAlignMac68kSupport
= true;
553 bool handleTargetFeatures(std::vector
<std::string
> &Features
,
554 DiagnosticsEngine
&Diags
) override
{
555 if (!DarwinTargetInfo
<X86_32TargetInfo
>::handleTargetFeatures(Features
,
558 // We now know the features we have: we can decide how to align vectors.
560 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
565 // x86-32 Windows target
566 class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
567 : public WindowsTargetInfo
<X86_32TargetInfo
> {
569 WindowsX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
570 : WindowsTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
571 DoubleAlign
= LongLongAlign
= 64;
573 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
574 bool IsMSVC
= getTriple().isWindowsMSVCEnvironment();
575 std::string Layout
= IsWinCOFF
? "e-m:x" : "e-m:e";
576 Layout
+= "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-";
577 Layout
+= IsMSVC
? "f80:128" : "f80:32";
578 Layout
+= "-n8:16:32-a:0:32-S32";
579 resetDataLayout(Layout
, IsWinCOFF
? "_" : "");
583 // x86-32 Windows Visual Studio target
584 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
585 : public WindowsX86_32TargetInfo
{
587 MicrosoftX86_32TargetInfo(const llvm::Triple
&Triple
,
588 const TargetOptions
&Opts
)
589 : WindowsX86_32TargetInfo(Triple
, Opts
) {
590 LongDoubleWidth
= LongDoubleAlign
= 64;
591 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
594 void getTargetDefines(const LangOptions
&Opts
,
595 MacroBuilder
&Builder
) const override
{
596 WindowsX86_32TargetInfo::getTargetDefines(Opts
, Builder
);
597 // The value of the following reflects processor type.
598 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
599 // We lost the original triple, so we use the default.
600 Builder
.defineMacro("_M_IX86", "600");
604 // x86-32 MinGW target
605 class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
606 : public WindowsX86_32TargetInfo
{
608 MinGWX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
609 : WindowsX86_32TargetInfo(Triple
, Opts
) {
613 void getTargetDefines(const LangOptions
&Opts
,
614 MacroBuilder
&Builder
) const override
{
615 WindowsX86_32TargetInfo::getTargetDefines(Opts
, Builder
);
616 Builder
.defineMacro("_X86_");
620 // x86-32 Cygwin target
621 class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo
: public X86_32TargetInfo
{
623 CygwinX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
624 : X86_32TargetInfo(Triple
, Opts
) {
625 this->WCharType
= TargetInfo::UnsignedShort
;
626 DoubleAlign
= LongLongAlign
= 64;
627 resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"
628 "i128:128-f80:32-n8:16:32-a:0:32-S32",
632 void getTargetDefines(const LangOptions
&Opts
,
633 MacroBuilder
&Builder
) const override
{
634 X86_32TargetInfo::getTargetDefines(Opts
, Builder
);
635 Builder
.defineMacro("_X86_");
636 Builder
.defineMacro("__CYGWIN__");
637 Builder
.defineMacro("__CYGWIN32__");
638 addCygMingDefines(Opts
, Builder
);
639 DefineStd(Builder
, "unix", Opts
);
641 Builder
.defineMacro("_GNU_SOURCE");
645 // x86-32 Haiku target
646 class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
647 : public HaikuTargetInfo
<X86_32TargetInfo
> {
649 HaikuX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
650 : HaikuTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {}
652 void getTargetDefines(const LangOptions
&Opts
,
653 MacroBuilder
&Builder
) const override
{
654 HaikuTargetInfo
<X86_32TargetInfo
>::getTargetDefines(Opts
, Builder
);
655 Builder
.defineMacro("__INTEL__");
660 class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo
: public X86_32TargetInfo
{
662 MCUX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
663 : X86_32TargetInfo(Triple
, Opts
) {
664 LongDoubleWidth
= 64;
665 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
666 resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-"
667 "f64:32-f128:32-n8:16:32-a:0:32-S32");
668 WIntType
= UnsignedInt
;
671 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
672 // On MCU we support only C calling convention.
673 return CC
== CC_C
? CCCR_OK
: CCCR_Warning
;
676 void getTargetDefines(const LangOptions
&Opts
,
677 MacroBuilder
&Builder
) const override
{
678 X86_32TargetInfo::getTargetDefines(Opts
, Builder
);
679 Builder
.defineMacro("__iamcu");
680 Builder
.defineMacro("__iamcu__");
683 bool allowsLargerPreferedTypeAlignment() const override
{ return false; }
686 // x86-32 RTEMS target
687 class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo
: public X86_32TargetInfo
{
689 RTEMSX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
690 : X86_32TargetInfo(Triple
, Opts
) {
691 SizeType
= UnsignedLong
;
692 IntPtrType
= SignedLong
;
693 PtrDiffType
= SignedLong
;
696 void getTargetDefines(const LangOptions
&Opts
,
697 MacroBuilder
&Builder
) const override
{
698 X86_32TargetInfo::getTargetDefines(Opts
, Builder
);
699 Builder
.defineMacro("__INTEL__");
700 Builder
.defineMacro("__rtems__");
704 // x86-64 generic target
705 class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo
: public X86TargetInfo
{
707 X86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
708 : X86TargetInfo(Triple
, Opts
) {
709 const bool IsX32
= getTriple().isX32();
711 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
712 LongWidth
= LongAlign
= PointerWidth
= PointerAlign
= IsX32
? 32 : 64;
713 LongDoubleWidth
= 128;
714 LongDoubleAlign
= 128;
715 LargeArrayMinWidth
= 128;
716 LargeArrayAlign
= 128;
718 SizeType
= IsX32
? UnsignedInt
: UnsignedLong
;
719 PtrDiffType
= IsX32
? SignedInt
: SignedLong
;
720 IntPtrType
= IsX32
? SignedInt
: SignedLong
;
721 IntMaxType
= IsX32
? SignedLongLong
: SignedLong
;
722 Int64Type
= IsX32
? SignedLongLong
: SignedLong
;
725 // Pointers are 32-bit in x32.
726 resetDataLayout(IsX32
? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
727 "i64:64-i128:128-f80:128-n8:16:32:64-S128"
728 : IsWinCOFF
? "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:"
729 "64-i128:128-f80:128-n8:16:32:64-S128"
730 : "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:"
731 "64-i128:128-f80:128-n8:16:32:64-S128");
733 // Use fpret only for long double.
734 RealTypeUsesObjCFPRetMask
= (unsigned)FloatModeKind::LongDouble
;
736 // Use fp2ret for _Complex long double.
737 ComplexLongDoubleUsesFP2Ret
= true;
739 // Make __builtin_ms_va_list available.
740 HasBuiltinMSVaList
= true;
742 // x86-64 has atomics up to 16 bytes.
743 MaxAtomicPromoteWidth
= 128;
744 MaxAtomicInlineWidth
= 64;
747 BuiltinVaListKind
getBuiltinVaListKind() const override
{
748 return TargetInfo::X86_64ABIBuiltinVaList
;
751 int getEHDataRegisterNumber(unsigned RegNo
) const override
{
759 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
764 case CC_X86VectorCall
:
765 case CC_IntelOclBicc
:
767 case CC_PreserveMost
:
770 case CC_OpenCLKernel
:
777 CallingConv
getDefaultCallingConv() const override
{
781 // for x32 we need it here explicitly
782 bool hasInt128Type() const override
{ return true; }
784 unsigned getUnwindWordWidth() const override
{ return 64; }
786 unsigned getRegisterWidth() const override
{ return 64; }
788 bool validateGlobalRegisterVariable(StringRef RegName
, unsigned RegSize
,
789 bool &HasSizeMismatch
) const override
{
790 // rsp and rbp are the only 64-bit registers the x86 backend can currently
792 if (RegName
.equals("rsp") || RegName
.equals("rbp")) {
793 // Check that the register size is 64-bit.
794 HasSizeMismatch
= RegSize
!= 64;
798 // Check if the register is a 32-bit register the backend can handle.
799 return X86TargetInfo::validateGlobalRegisterVariable(RegName
, RegSize
,
803 void setMaxAtomicWidth() override
{
804 if (hasFeature("cx16"))
805 MaxAtomicInlineWidth
= 128;
808 ArrayRef
<Builtin::Info
> getTargetBuiltins() const override
;
810 bool hasBitIntType() const override
{ return true; }
811 size_t getMaxBitIntWidth() const override
{
812 return llvm::IntegerType::MAX_INT_BITS
;
816 // x86-64 Windows target
817 class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
818 : public WindowsTargetInfo
<X86_64TargetInfo
> {
820 WindowsX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
821 : WindowsTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
822 LongWidth
= LongAlign
= 32;
823 DoubleAlign
= LongLongAlign
= 64;
824 IntMaxType
= SignedLongLong
;
825 Int64Type
= SignedLongLong
;
826 SizeType
= UnsignedLongLong
;
827 PtrDiffType
= SignedLongLong
;
828 IntPtrType
= SignedLongLong
;
831 BuiltinVaListKind
getBuiltinVaListKind() const override
{
832 return TargetInfo::CharPtrBuiltinVaList
;
835 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
842 case CC_X86VectorCall
:
843 case CC_IntelOclBicc
:
844 case CC_PreserveMost
:
850 case CC_OpenCLKernel
:
858 // x86-64 Windows Visual Studio target
859 class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
860 : public WindowsX86_64TargetInfo
{
862 MicrosoftX86_64TargetInfo(const llvm::Triple
&Triple
,
863 const TargetOptions
&Opts
)
864 : WindowsX86_64TargetInfo(Triple
, Opts
) {
865 LongDoubleWidth
= LongDoubleAlign
= 64;
866 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
869 void getTargetDefines(const LangOptions
&Opts
,
870 MacroBuilder
&Builder
) const override
{
871 WindowsX86_64TargetInfo::getTargetDefines(Opts
, Builder
);
872 Builder
.defineMacro("_M_X64", "100");
873 Builder
.defineMacro("_M_AMD64", "100");
876 TargetInfo::CallingConvKind
877 getCallingConvKind(bool ClangABICompat4
) const override
{
878 return CCK_MicrosoftWin64
;
882 // x86-64 MinGW target
883 class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
884 : public WindowsX86_64TargetInfo
{
886 MinGWX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
887 : WindowsX86_64TargetInfo(Triple
, Opts
) {
888 // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
889 // with x86 FP ops. Weird.
890 LongDoubleWidth
= LongDoubleAlign
= 128;
891 LongDoubleFormat
= &llvm::APFloat::x87DoubleExtended();
896 // x86-64 Cygwin target
897 class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo
: public X86_64TargetInfo
{
899 CygwinX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
900 : X86_64TargetInfo(Triple
, Opts
) {
901 this->WCharType
= TargetInfo::UnsignedShort
;
902 TLSSupported
= false;
905 void getTargetDefines(const LangOptions
&Opts
,
906 MacroBuilder
&Builder
) const override
{
907 X86_64TargetInfo::getTargetDefines(Opts
, Builder
);
908 Builder
.defineMacro("__x86_64__");
909 Builder
.defineMacro("__CYGWIN__");
910 Builder
.defineMacro("__CYGWIN64__");
911 addCygMingDefines(Opts
, Builder
);
912 DefineStd(Builder
, "unix", Opts
);
914 Builder
.defineMacro("_GNU_SOURCE");
918 class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
919 : public DarwinTargetInfo
<X86_64TargetInfo
> {
921 DarwinX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
922 : DarwinTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
923 Int64Type
= SignedLongLong
;
924 // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
925 llvm::Triple T
= llvm::Triple(Triple
);
927 UseSignedCharForObjCBool
= false;
928 resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
929 "f80:128-n8:16:32:64-S128",
933 bool handleTargetFeatures(std::vector
<std::string
> &Features
,
934 DiagnosticsEngine
&Diags
) override
{
935 if (!DarwinTargetInfo
<X86_64TargetInfo
>::handleTargetFeatures(Features
,
938 // We now know the features we have: we can decide how to align vectors.
940 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
945 class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
946 : public OpenBSDTargetInfo
<X86_64TargetInfo
> {
948 OpenBSDX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
949 : OpenBSDTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
950 IntMaxType
= SignedLongLong
;
951 Int64Type
= SignedLongLong
;
955 // x86_32 Android target
956 class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
957 : public LinuxTargetInfo
<X86_32TargetInfo
> {
959 AndroidX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
960 : LinuxTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
962 LongDoubleWidth
= 64;
963 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
967 // x86_64 Android target
968 class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
969 : public LinuxTargetInfo
<X86_64TargetInfo
> {
971 AndroidX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
972 : LinuxTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
973 LongDoubleFormat
= &llvm::APFloat::IEEEquad();
977 // x86_32 OHOS target
978 class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo
979 : public OHOSTargetInfo
<X86_32TargetInfo
> {
981 OHOSX86_32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
982 : OHOSTargetInfo
<X86_32TargetInfo
>(Triple
, Opts
) {
984 LongDoubleWidth
= 64;
985 LongDoubleFormat
= &llvm::APFloat::IEEEdouble();
989 // x86_64 OHOS target
990 class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo
991 : public OHOSTargetInfo
<X86_64TargetInfo
> {
993 OHOSX86_64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
994 : OHOSTargetInfo
<X86_64TargetInfo
>(Triple
, Opts
) {
995 LongDoubleFormat
= &llvm::APFloat::IEEEquad();
998 } // namespace targets
1000 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H