brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.7 KiB · e7da262 Raw
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