1112 lines · c
1//===--- X86.h - Declare X86 target feature support -------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file declares X86 TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_X86_H14#define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H15 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"23#include <optional>24 25namespace clang {26namespace targets {27 28static const unsigned X86AddrSpaceMap[] = {29 0, // Default30 0, // opencl_global31 0, // opencl_local32 0, // opencl_constant33 0, // opencl_private34 0, // opencl_generic35 0, // opencl_global_device36 0, // opencl_global_host37 0, // cuda_device38 0, // cuda_constant39 0, // cuda_shared40 0, // sycl_global41 0, // sycl_global_device42 0, // sycl_global_host43 0, // sycl_local44 0, // sycl_private45 270, // ptr32_sptr46 271, // ptr32_uptr47 272, // ptr6448 0, // hlsl_groupshared49 0, // hlsl_constant50 0, // hlsl_private51 0, // hlsl_device52 0, // hlsl_input53 // Wasm address space values for this target are dummy values,54 // as it is only enabled for Wasm targets.55 20, // wasm_funcref56};57 58// X86 target abstract base class; x86-32 and x86-64 are very close, so59// most of the implementation can be shared.60class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {61 62 enum X86SSEEnum {63 NoSSE,64 SSE1,65 SSE2,66 SSE3,67 SSSE3,68 SSE41,69 SSE42,70 AVX,71 AVX2,72 AVX512F73 } SSELevel = NoSSE;74 bool HasMMX = false;75 enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;76 enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };77 78 bool HasAES = false;79 bool HasVAES = false;80 bool HasPCLMUL = false;81 bool HasVPCLMULQDQ = false;82 bool HasGFNI = false;83 bool HasLZCNT = false;84 bool HasRDRND = false;85 bool HasFSGSBASE = false;86 bool HasBMI = false;87 bool HasBMI2 = false;88 bool HasPOPCNT = false;89 bool HasRTM = false;90 bool HasPRFCHW = false;91 bool HasRDSEED = false;92 bool HasADX = false;93 bool HasTBM = false;94 bool HasLWP = false;95 bool HasFMA = false;96 bool HasF16C = false;97 bool HasAVX10_1 = false;98 bool HasAVX10_2 = false;99 bool HasAVX512CD = false;100 bool HasAVX512VPOPCNTDQ = false;101 bool HasAVX512VNNI = false;102 bool HasAVX512FP16 = false;103 bool HasAVX512BF16 = false;104 bool HasAVX512DQ = false;105 bool HasAVX512BITALG = false;106 bool HasAVX512BW = false;107 bool HasAVX512VL = false;108 bool HasAVX512VBMI = false;109 bool HasAVX512VBMI2 = false;110 bool HasAVXIFMA = false;111 bool HasAVX512IFMA = false;112 bool HasAVX512VP2INTERSECT = false;113 bool HasSHA = false;114 bool HasSHA512 = false;115 bool HasSHSTK = false;116 bool HasSM3 = false;117 bool HasSGX = false;118 bool HasSM4 = false;119 bool HasCX8 = false;120 bool HasCX16 = false;121 bool HasFXSR = false;122 bool HasXSAVE = false;123 bool HasXSAVEOPT = false;124 bool HasXSAVEC = false;125 bool HasXSAVES = false;126 bool HasMWAITX = false;127 bool HasCLZERO = false;128 bool HasCLDEMOTE = false;129 bool HasPCONFIG = false;130 bool HasPKU = false;131 bool HasCLFLUSHOPT = false;132 bool HasCLWB = false;133 bool HasMOVBE = false;134 bool HasMOVRS = false;135 bool HasPREFETCHI = false;136 bool HasRDPID = false;137 bool HasRDPRU = false;138 bool HasRetpolineExternalThunk = false;139 bool HasLAHFSAHF = false;140 bool HasWBNOINVD = false;141 bool HasWAITPKG = false;142 bool HasMOVDIRI = false;143 bool HasMOVDIR64B = false;144 bool HasPTWRITE = false;145 bool HasINVPCID = false;146 bool HasENQCMD = false;147 bool HasAVXVNNIINT16 = false;148 bool HasAMXFP16 = false;149 bool HasCMPCCXADD = false;150 bool HasRAOINT = false;151 bool HasAVXVNNIINT8 = false;152 bool HasAVXNECONVERT = false;153 bool HasKL = false; // For key locker154 bool HasWIDEKL = false; // For wide key locker155 bool HasHRESET = false;156 bool HasAVXVNNI = false;157 bool HasAMXTILE = false;158 bool HasAMXINT8 = false;159 bool HasAMXBF16 = false;160 bool HasAMXCOMPLEX = false;161 bool HasAMXFP8 = false;162 bool HasAMXMOVRS = 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;170 bool HasX87 = false;171 bool HasEGPR = false;172 bool HasPush2Pop2 = false;173 bool HasPPX = false;174 bool HasNDD = false;175 bool HasCCMP = false;176 bool HasNF = false;177 bool HasCF = false;178 bool HasZU = false;179 bool HasInlineAsmUseGPR32 = false;180 bool HasBranchHint = false;181 182protected:183 llvm::X86::CPUKind CPU = llvm::X86::CK_None;184 185 enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;186 187public: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;194 HasStrictFP = true;195 HasUnalignedAccess = true;196 197 bool IsWinCOFF =198 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();199 if (IsWinCOFF)200 MaxVectorAlign = MaxTLSAlign = 8192u * getCharWidth();201 }202 203 const char *getLongDoubleMangling() const override {204 return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";205 }206 207 LangOptions::FPEvalMethodKind getFPEvalMethod() const override {208 // X87 evaluates with 80 bits "long double" precision.209 return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended210 : LangOptions::FPEvalMethodKind::FEM_Source;211 }212 213 // EvalMethod `source` is not supported for targets with `NoSSE` feature.214 bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; }215 216 ArrayRef<const char *> getGCCRegNames() const override;217 218 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {219 return {};220 }221 222 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;223 224 bool isSPRegName(StringRef RegName) const override {225 return RegName == "esp" || RegName == "rsp";226 }227 228 bool supportsCpuSupports() const override { return true; }229 bool supportsCpuIs() const override { return true; }230 bool supportsCpuInit() const override { return true; }231 232 bool validateCpuSupports(StringRef FeatureStr) const override;233 234 bool validateCpuIs(StringRef FeatureStr) const override;235 236 bool validateCPUSpecificCPUDispatch(StringRef Name) const override;237 238 char CPUSpecificManglingCharacter(StringRef Name) const override;239 240 void getCPUSpecificCPUDispatchFeatures(241 StringRef Name,242 llvm::SmallVectorImpl<StringRef> &Features) const override;243 244 std::optional<unsigned> getCPUCacheLineSize() const override;245 246 bool validateAsmConstraint(const char *&Name,247 TargetInfo::ConstraintInfo &info) const override;248 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 currently252 // handle.253 if (RegName == "esp" || RegName == "ebp") {254 // Check that the register size is 32-bit.255 HasSizeMismatch = RegSize != 32;256 return true;257 }258 259 return false;260 }261 262 bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,263 StringRef Constraint, unsigned Size) const override;264 265 bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,266 StringRef Constraint, unsigned Size) const override;267 268 bool269 checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {270 if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)271 return true;272 return TargetInfo::checkCFProtectionReturnSupported(Diags);273 };274 275 bool276 checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {277 if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)278 return true;279 return TargetInfo::checkCFProtectionBranchSupported(Diags);280 };281 282 virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,283 StringRef Constraint, unsigned Size) const;284 285 std::string convertConstraint(const char *&Constraint) const override;286 std::string_view getClobbers() const override {287 return "~{dirflag},~{fpsr},~{flags}";288 }289 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 == '@')295 break;296 }297 if (I == E)298 return "";299 switch (*I) {300 // For the register constraints, return the matching register name301 case 'a':302 return "ax";303 case 'b':304 return "bx";305 case 'c':306 return "cx";307 case 'd':308 return "dx";309 case 'S':310 return "si";311 case 'D':312 return "di";313 // In case the constraint is 'r' we need to return Expression314 case 'r':315 return Expression;316 // Double letters Y<x> constraints317 case 'Y':318 if ((++I != E) && ((*I == '0') || (*I == 'z')))319 return "xmm0";320 break;321 default:322 break;323 }324 return "";325 }326 327 bool useFP16ConversionIntrinsics() const override {328 return false;329 }330 331 void getTargetDefines(const LangOptions &Opts,332 MacroBuilder &Builder) const override;333 334 void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,335 bool Enabled) const final;336 337 bool338 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,339 StringRef CPU,340 const std::vector<std::string> &FeaturesVec) const override;341 342 bool isValidFeatureName(StringRef Name) const override;343 344 bool hasFeature(StringRef Feature) const final;345 346 bool handleTargetFeatures(std::vector<std::string> &Features,347 DiagnosticsEngine &Diags) override;348 349 StringRef getABI() const override {350 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)351 return "avx512";352 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)353 return "avx";354 if (getTriple().getArch() == llvm::Triple::x86 && !HasMMX)355 return "no-mmx";356 return "";357 }358 359 bool supportsTargetAttributeTune() const override {360 return true;361 }362 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;366 }367 368 bool isValidTuneCPUName(StringRef Name) const override {369 if (Name == "generic")370 return true;371 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 lenient374 // since mtune was ignored by clang for so long.375 return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None;376 }377 378 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;379 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;380 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;385 }386 387 llvm::APInt getFMVPriority(ArrayRef<StringRef> Features) const override;388 389 bool setFPMath(StringRef Name) override;390 391 bool supportsExtendIntArgs() const override {392 return getTriple().getArch() != llvm::Triple::x86;393 }394 395 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {396 // Most of the non-ARM calling conventions are i386 conventions.397 switch (CC) {398 case CC_X86ThisCall:399 case CC_X86FastCall:400 case CC_X86StdCall:401 case CC_X86VectorCall:402 case CC_X86RegCall:403 case CC_C:404 case CC_PreserveMost:405 case CC_Swift:406 case CC_X86Pascal:407 case CC_IntelOclBicc:408 return CCCR_OK;409 case CC_SwiftAsync:410 return CCCR_Error;411 case CC_DeviceKernel:412 return IsOpenCL ? CCCR_OK : CCCR_Warning;413 default:414 return CCCR_Warning;415 }416 }417 418 bool checkArithmeticFenceSupported() const override { return true; }419 420 CallingConv getDefaultCallingConv() const override {421 return CC_C;422 }423 424 bool hasSjLjLowering() const override { return true; }425 426 void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }427 428 uint64_t getPointerWidthV(LangAS AS) const override {429 unsigned TargetAddrSpace = getTargetAddressSpace(AS);430 if (TargetAddrSpace == ptr32_sptr || TargetAddrSpace == ptr32_uptr)431 return 32;432 if (TargetAddrSpace == ptr64)433 return 64;434 return PointerWidth;435 }436 437 uint64_t getPointerAlignV(LangAS AddrSpace) const override {438 return getPointerWidthV(AddrSpace);439 }440 void adjust(DiagnosticsEngine &Diags, LangOptions &Opts,441 const TargetInfo *Aux) override {442 TargetInfo::adjust(Diags, Opts, Aux);443 IsOpenCL = Opts.OpenCL;444 }445 446private:447 bool IsOpenCL = false;448};449 450// X86-32 generic target451class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {452public:453 X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)454 : X86TargetInfo(Triple, Opts) {455 DoubleAlign = LongLongAlign = 32;456 LongDoubleWidth = 96;457 LongDoubleAlign = 32;458 SuitableAlign = 128;459 resetDataLayout(Triple.isOSBinFormatMachO()460 ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"461 "128-f64:32:64-f80:32-n8:16:32-S128"462 : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"463 "128-f64:32:64-f80:32-n8:16:32-S128",464 Triple.isOSBinFormatMachO() ? "_" : "");465 SizeType = UnsignedInt;466 PtrDiffType = SignedInt;467 IntPtrType = SignedInt;468 RegParmMax = 3;469 470 // Use fpret for all types.471 RealTypeUsesObjCFPRetMask =472 (unsigned)(FloatModeKind::Float | FloatModeKind::Double |473 FloatModeKind::LongDouble);474 475 // x86-32 has atomics up to 8 bytes476 MaxAtomicPromoteWidth = 64;477 MaxAtomicInlineWidth = 32;478 }479 480 BuiltinVaListKind getBuiltinVaListKind() const override {481 return TargetInfo::CharPtrBuiltinVaList;482 }483 484 int getEHDataRegisterNumber(unsigned RegNo) const override {485 if (RegNo == 0)486 return 0;487 if (RegNo == 1)488 return 2;489 return -1;490 }491 492 bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,493 StringRef Constraint, unsigned Size) const override {494 switch (Constraint[0]) {495 default:496 break;497 case 'R':498 case 'q':499 case 'Q':500 case 'a':501 case 'b':502 case 'c':503 case 'd':504 case 'S':505 case 'D':506 return Size <= 32;507 case 'A':508 return Size <= 64;509 }510 511 return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);512 }513 514 void setMaxAtomicWidth() override {515 if (hasFeature("cx8"))516 MaxAtomicInlineWidth = 64;517 }518 519 llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;520 521 bool hasBitIntType() const override { return true; }522 size_t getMaxBitIntWidth() const override {523 return llvm::IntegerType::MAX_INT_BITS;524 }525};526 527class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo528 : public NetBSDTargetInfo<X86_32TargetInfo> {529public:530 NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)531 : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}532};533 534class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo535 : public OpenBSDTargetInfo<X86_32TargetInfo> {536public:537 OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)538 : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {539 SizeType = UnsignedLong;540 IntPtrType = SignedLong;541 PtrDiffType = SignedLong;542 }543};544 545class LLVM_LIBRARY_VISIBILITY AppleMachOI386TargetInfo546 : public AppleMachOTargetInfo<X86_32TargetInfo> {547public:548 AppleMachOI386TargetInfo(const llvm::Triple &Triple,549 const TargetOptions &Opts)550 : AppleMachOTargetInfo<X86_32TargetInfo>(Triple, Opts) {}551};552 553class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo554 : public DarwinTargetInfo<X86_32TargetInfo> {555public:556 DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)557 : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {558 LongDoubleWidth = 128;559 LongDoubleAlign = 128;560 SuitableAlign = 128;561 MaxVectorAlign = 256;562 // The watchOS simulator uses the builtin bool type for Objective-C.563 llvm::Triple T = llvm::Triple(Triple);564 if (T.isWatchOS())565 UseSignedCharForObjCBool = false;566 SizeType = UnsignedLong;567 IntPtrType = SignedLong;568 resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-"569 "f64:32:64-f80:128-n8:16:32-S128",570 "_");571 HasAlignMac68kSupport = true;572 }573 574 bool handleTargetFeatures(std::vector<std::string> &Features,575 DiagnosticsEngine &Diags) override {576 if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,577 Diags))578 return false;579 // We now know the features we have: we can decide how to align vectors.580 MaxVectorAlign =581 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;582 return true;583 }584};585 586// x86-32 Windows target587class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo588 : public WindowsTargetInfo<X86_32TargetInfo> {589public:590 WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)591 : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {592 DoubleAlign = LongLongAlign = 64;593 bool IsWinCOFF =594 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();595 bool IsMSVC = getTriple().isWindowsMSVCEnvironment();596 std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e";597 Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-";598 Layout += IsMSVC ? "f80:128" : "f80:32";599 Layout += "-n8:16:32-a:0:32-S32";600 resetDataLayout(Layout, IsWinCOFF ? "_" : "");601 }602};603 604// x86-32 Windows Visual Studio target605class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo606 : public WindowsX86_32TargetInfo {607public:608 MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,609 const TargetOptions &Opts)610 : WindowsX86_32TargetInfo(Triple, Opts) {611 LongDoubleWidth = LongDoubleAlign = 64;612 LongDoubleFormat = &llvm::APFloat::IEEEdouble();613 }614 615 void getTargetDefines(const LangOptions &Opts,616 MacroBuilder &Builder) const override {617 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);618 // The value of the following reflects processor type.619 // 300=386, 400=486, 500=Pentium, 600=Blend (default)620 // We lost the original triple, so we use the default.621 Builder.defineMacro("_M_IX86", "600");622 }623};624 625// x86-32 MinGW target626class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo627 : public WindowsX86_32TargetInfo {628public:629 MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)630 : WindowsX86_32TargetInfo(Triple, Opts) {631 HasFloat128 = true;632 }633 634 void getTargetDefines(const LangOptions &Opts,635 MacroBuilder &Builder) const override {636 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);637 Builder.defineMacro("_X86_");638 }639};640 641// x86-32 Cygwin target642class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {643public:644 CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)645 : X86_32TargetInfo(Triple, Opts) {646 this->WCharType = TargetInfo::UnsignedShort;647 this->WIntType = TargetInfo::UnsignedInt;648 this->UseMicrosoftManglingForC = true;649 DoubleAlign = LongLongAlign = 64;650 resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"651 "i128:128-f80:32-n8:16:32-a:0:32-S32",652 "_");653 }654 655 void getTargetDefines(const LangOptions &Opts,656 MacroBuilder &Builder) const override {657 X86_32TargetInfo::getTargetDefines(Opts, Builder);658 Builder.defineMacro("_X86_");659 Builder.defineMacro("__CYGWIN__");660 Builder.defineMacro("__CYGWIN32__");661 addCygMingDefines(Opts, Builder);662 DefineStd(Builder, "unix", Opts);663 if (Opts.CPlusPlus)664 Builder.defineMacro("_GNU_SOURCE");665 }666};667 668// x86-32 Haiku target669class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo670 : public HaikuTargetInfo<X86_32TargetInfo> {671public:672 HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)673 : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}674 675 void getTargetDefines(const LangOptions &Opts,676 MacroBuilder &Builder) const override {677 HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);678 Builder.defineMacro("__INTEL__");679 }680};681 682// X86-32 MCU target683class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {684public:685 MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)686 : X86_32TargetInfo(Triple, Opts) {687 LongDoubleWidth = 64;688 DefaultAlignForAttributeAligned = 32;689 LongDoubleFormat = &llvm::APFloat::IEEEdouble();690 resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-"691 "f64:32-f128:32-n8:16:32-a:0:32-S32");692 WIntType = UnsignedInt;693 }694 695 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {696 // On MCU we support only C calling convention.697 return CC == CC_C ? CCCR_OK : CCCR_Warning;698 }699 700 void getTargetDefines(const LangOptions &Opts,701 MacroBuilder &Builder) const override {702 X86_32TargetInfo::getTargetDefines(Opts, Builder);703 Builder.defineMacro("__iamcu");704 Builder.defineMacro("__iamcu__");705 }706 707 bool allowsLargerPreferedTypeAlignment() const override { return false; }708};709 710// x86-32 RTEMS target711class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {712public:713 RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)714 : X86_32TargetInfo(Triple, Opts) {715 SizeType = UnsignedLong;716 IntPtrType = SignedLong;717 PtrDiffType = SignedLong;718 }719 720 void getTargetDefines(const LangOptions &Opts,721 MacroBuilder &Builder) const override {722 X86_32TargetInfo::getTargetDefines(Opts, Builder);723 Builder.defineMacro("__INTEL__");724 Builder.defineMacro("__rtems__");725 }726};727 728// x86-64 generic target729class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {730public:731 X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)732 : X86TargetInfo(Triple, Opts) {733 const bool IsX32 = getTriple().isX32();734 bool IsWinCOFF =735 getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();736 LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;737 LongDoubleWidth = 128;738 LongDoubleAlign = 128;739 LargeArrayMinWidth = 128;740 LargeArrayAlign = 128;741 SuitableAlign = 128;742 SizeType = IsX32 ? UnsignedInt : UnsignedLong;743 PtrDiffType = IsX32 ? SignedInt : SignedLong;744 IntPtrType = IsX32 ? SignedInt : SignedLong;745 IntMaxType = IsX32 ? SignedLongLong : SignedLong;746 Int64Type = IsX32 ? SignedLongLong : SignedLong;747 RegParmMax = 6;748 749 // Pointers are 32-bit in x32.750 resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"751 "i64:64-i128:128-f80:128-n8:16:32:64-S128"752 : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:"753 "64-i128:128-f80:128-n8:16:32:64-S128"754 : "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:"755 "64-i128:128-f80:128-n8:16:32:64-S128");756 757 // Use fpret only for long double.758 RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;759 760 // Use fp2ret for _Complex long double.761 ComplexLongDoubleUsesFP2Ret = true;762 763 // Make __builtin_ms_va_list available.764 HasBuiltinMSVaList = true;765 766 // x86-64 has atomics up to 16 bytes.767 MaxAtomicPromoteWidth = 128;768 MaxAtomicInlineWidth = 64;769 }770 771 BuiltinVaListKind getBuiltinVaListKind() const override {772 return TargetInfo::X86_64ABIBuiltinVaList;773 }774 775 int getEHDataRegisterNumber(unsigned RegNo) const override {776 if (RegNo == 0)777 return 0;778 if (RegNo == 1)779 return 1;780 return -1;781 }782 783 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {784 switch (CC) {785 case CC_C:786 case CC_Swift:787 case CC_SwiftAsync:788 case CC_X86VectorCall:789 case CC_IntelOclBicc:790 case CC_Win64:791 case CC_PreserveMost:792 case CC_PreserveAll:793 case CC_PreserveNone:794 case CC_X86RegCall:795 return CCCR_OK;796 case CC_DeviceKernel:797 return IsOpenCL ? CCCR_OK : CCCR_Warning;798 default:799 return CCCR_Warning;800 }801 }802 803 CallingConv getDefaultCallingConv() const override {804 return CC_C;805 }806 807 // for x32 we need it here explicitly808 bool hasInt128Type() const override { return true; }809 810 unsigned getUnwindWordWidth() const override { return 64; }811 812 unsigned getRegisterWidth() const override { return 64; }813 814 bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,815 bool &HasSizeMismatch) const override {816 // rsp and rbp are the only 64-bit registers the x86 backend can currently817 // handle.818 if (RegName == "rsp" || RegName == "rbp") {819 // Check that the register size is 64-bit.820 HasSizeMismatch = RegSize != 64;821 return true;822 }823 824 // Check if the register is a 32-bit register the backend can handle.825 return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,826 HasSizeMismatch);827 }828 void setMaxAtomicWidth() override {829 if (hasFeature("cx16"))830 MaxAtomicInlineWidth = 128;831 }832 833 llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;834 835 bool hasBitIntType() const override { return true; }836 size_t getMaxBitIntWidth() const override {837 return llvm::IntegerType::MAX_INT_BITS;838 }839 840 void adjust(DiagnosticsEngine &Diags, LangOptions &Opts,841 const TargetInfo *Aux) override {842 TargetInfo::adjust(Diags, Opts, Aux);843 IsOpenCL = Opts.OpenCL;844 }845 846private:847 bool IsOpenCL = false;848};849 850// x86-64 UEFI target851class LLVM_LIBRARY_VISIBILITY UEFIX86_64TargetInfo852 : public UEFITargetInfo<X86_64TargetInfo> {853public:854 UEFIX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)855 : UEFITargetInfo<X86_64TargetInfo>(Triple, Opts) {856 // The UEFI spec does not mandate specific C++ ABI, integer widths, or857 // alignment. We are setting these defaults to match the Windows target as858 // it is the only way to build EFI applications with Clang/LLVM today. We859 // intend to offer flexibility by supporting choices that are not default in860 // Windows target in the future.861 this->TheCXXABI.set(TargetCXXABI::Microsoft);862 LongWidth = LongAlign = 32;863 DoubleAlign = LongLongAlign = 64;864 LongDoubleWidth = LongDoubleAlign = 64;865 LongDoubleFormat = &llvm::APFloat::IEEEdouble();866 IntMaxType = SignedLongLong;867 Int64Type = SignedLongLong;868 SizeType = UnsignedLongLong;869 PtrDiffType = SignedLongLong;870 IntPtrType = SignedLongLong;871 WCharType = UnsignedShort;872 WIntType = UnsignedShort;873 this->resetDataLayout("e-m:w-p270:32:32-p271:32:32-p272:64:64-"874 "i64:64-i128:128-f80:128-n8:16:32:64-S128");875 }876 877 BuiltinVaListKind getBuiltinVaListKind() const override {878 return TargetInfo::CharPtrBuiltinVaList;879 }880 881 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {882 switch (CC) {883 case CC_C:884 case CC_Win64:885 case CC_X86_64SysV:886 return CCCR_OK;887 default:888 return CCCR_Warning;889 }890 }891 892 TargetInfo::CallingConvKind893 getCallingConvKind(bool ClangABICompat4) const override {894 return CCK_MicrosoftWin64;895 }896};897 898// x86-64 Windows target899class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo900 : public WindowsTargetInfo<X86_64TargetInfo> {901public:902 WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)903 : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {904 LongWidth = LongAlign = 32;905 DoubleAlign = LongLongAlign = 64;906 IntMaxType = SignedLongLong;907 Int64Type = SignedLongLong;908 SizeType = UnsignedLongLong;909 PtrDiffType = SignedLongLong;910 IntPtrType = SignedLongLong;911 }912 913 BuiltinVaListKind getBuiltinVaListKind() const override {914 return TargetInfo::CharPtrBuiltinVaList;915 }916 917 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {918 switch (CC) {919 case CC_X86StdCall:920 case CC_X86ThisCall:921 case CC_X86FastCall:922 return CCCR_Ignore;923 case CC_C:924 case CC_X86VectorCall:925 case CC_IntelOclBicc:926 case CC_PreserveMost:927 case CC_PreserveAll:928 case CC_PreserveNone:929 case CC_X86_64SysV:930 case CC_Swift:931 case CC_SwiftAsync:932 case CC_X86RegCall:933 case CC_DeviceKernel:934 return CCCR_OK;935 default:936 return CCCR_Warning;937 }938 }939};940 941// x86-64 Windows Visual Studio target942class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo943 : public WindowsX86_64TargetInfo {944public:945 MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,946 const TargetOptions &Opts)947 : WindowsX86_64TargetInfo(Triple, Opts) {948 LongDoubleWidth = LongDoubleAlign = 64;949 LongDoubleFormat = &llvm::APFloat::IEEEdouble();950 }951 952 void getTargetDefines(const LangOptions &Opts,953 MacroBuilder &Builder) const override {954 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);955 Builder.defineMacro("_M_X64", "100");956 Builder.defineMacro("_M_AMD64", "100");957 }958 959 TargetInfo::CallingConvKind960 getCallingConvKind(bool ClangABICompat4) const override {961 return CCK_MicrosoftWin64;962 }963};964 965// x86-64 MinGW target966class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo967 : public WindowsX86_64TargetInfo {968public:969 MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)970 : WindowsX86_64TargetInfo(Triple, Opts) {971 // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks972 // with x86 FP ops. Weird.973 LongDoubleWidth = LongDoubleAlign = 128;974 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();975 HasFloat128 = true;976 }977};978 979// x86-64 Cygwin target980class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {981public:982 CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)983 : X86_64TargetInfo(Triple, Opts) {984 this->WCharType = TargetInfo::UnsignedShort;985 this->WIntType = TargetInfo::UnsignedInt;986 this->UseMicrosoftManglingForC = true;987 }988 989 void getTargetDefines(const LangOptions &Opts,990 MacroBuilder &Builder) const override {991 X86_64TargetInfo::getTargetDefines(Opts, Builder);992 Builder.defineMacro("__x86_64__");993 Builder.defineMacro("__CYGWIN__");994 Builder.defineMacro("__CYGWIN64__");995 addCygMingDefines(Opts, Builder);996 DefineStd(Builder, "unix", Opts);997 if (Opts.CPlusPlus)998 Builder.defineMacro("_GNU_SOURCE");999 }1000 1001 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {1002 switch (CC) {1003 case CC_X86StdCall:1004 case CC_X86ThisCall:1005 case CC_X86FastCall:1006 return CCCR_Ignore;1007 case CC_C:1008 case CC_X86VectorCall:1009 case CC_IntelOclBicc:1010 case CC_PreserveMost:1011 case CC_PreserveAll:1012 case CC_PreserveNone:1013 case CC_X86_64SysV:1014 case CC_Swift:1015 case CC_SwiftAsync:1016 case CC_X86RegCall:1017 case CC_DeviceKernel:1018 return CCCR_OK;1019 default:1020 return CCCR_Warning;1021 }1022 }1023 1024 BuiltinVaListKind getBuiltinVaListKind() const override {1025 return TargetInfo::CharPtrBuiltinVaList;1026 }1027};1028 1029class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo1030 : public DarwinTargetInfo<X86_64TargetInfo> {1031public:1032 DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)1033 : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {1034 Int64Type = SignedLongLong;1035 // The 64-bit iOS simulator uses the builtin bool type for Objective-C.1036 llvm::Triple T = llvm::Triple(Triple);1037 if (T.isiOS())1038 UseSignedCharForObjCBool = false;1039 resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"1040 "f80:128-n8:16:32:64-S128",1041 "_");1042 }1043 1044 bool handleTargetFeatures(std::vector<std::string> &Features,1045 DiagnosticsEngine &Diags) override {1046 if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,1047 Diags))1048 return false;1049 // We now know the features we have: we can decide how to align vectors.1050 MaxVectorAlign =1051 hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;1052 return true;1053 }1054};1055 1056class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo1057 : public OpenBSDTargetInfo<X86_64TargetInfo> {1058public:1059 OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)1060 : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {1061 IntMaxType = SignedLongLong;1062 Int64Type = SignedLongLong;1063 }1064};1065 1066// x86_32 Android target1067class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo1068 : public LinuxTargetInfo<X86_32TargetInfo> {1069public:1070 AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)1071 : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {1072 SuitableAlign = 32;1073 LongDoubleWidth = 64;1074 LongDoubleFormat = &llvm::APFloat::IEEEdouble();1075 }1076};1077 1078// x86_64 Android target1079class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo1080 : public LinuxTargetInfo<X86_64TargetInfo> {1081public:1082 AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)1083 : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {1084 LongDoubleFormat = &llvm::APFloat::IEEEquad();1085 }1086};1087 1088// x86_32 OHOS target1089class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo1090 : public OHOSTargetInfo<X86_32TargetInfo> {1091public:1092 OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)1093 : OHOSTargetInfo<X86_32TargetInfo>(Triple, Opts) {1094 SuitableAlign = 32;1095 LongDoubleWidth = 64;1096 LongDoubleFormat = &llvm::APFloat::IEEEdouble();1097 }1098};1099 1100// x86_64 OHOS target1101class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo1102 : public OHOSTargetInfo<X86_64TargetInfo> {1103public:1104 OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)1105 : OHOSTargetInfo<X86_64TargetInfo>(Triple, Opts) {1106 LongDoubleFormat = &llvm::APFloat::IEEEquad();1107 }1108};1109} // namespace targets1110} // namespace clang1111#endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H1112