forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			899 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			899 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--- X86.h - Declare X86 target feature support -------------*- C++ -*-===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file declares X86 TargetInfo objects.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
 | |
| #define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
 | |
| 
 | |
| #include "OSTargets.h"
 | |
| #include "clang/Basic/TargetInfo.h"
 | |
| #include "clang/Basic/TargetOptions.h"
 | |
| #include "llvm/ADT/Triple.h"
 | |
| #include "llvm/Support/Compiler.h"
 | |
| 
 | |
| namespace clang {
 | |
| namespace targets {
 | |
| 
 | |
| static const unsigned X86AddrSpaceMap[] = {
 | |
|     0,   // Default
 | |
|     0,   // opencl_global
 | |
|     0,   // opencl_local
 | |
|     0,   // opencl_constant
 | |
|     0,   // opencl_private
 | |
|     0,   // opencl_generic
 | |
|     0,   // cuda_device
 | |
|     0,   // cuda_constant
 | |
|     0,   // cuda_shared
 | |
|     270, // ptr32_sptr
 | |
|     271, // ptr32_uptr
 | |
|     272  // ptr64
 | |
| };
 | |
| 
 | |
| // X86 target abstract base class; x86-32 and x86-64 are very close, so
 | |
| // most of the implementation can be shared.
 | |
| class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
 | |
| 
 | |
|   enum X86SSEEnum {
 | |
|     NoSSE,
 | |
|     SSE1,
 | |
|     SSE2,
 | |
|     SSE3,
 | |
|     SSSE3,
 | |
|     SSE41,
 | |
|     SSE42,
 | |
|     AVX,
 | |
|     AVX2,
 | |
|     AVX512F
 | |
|   } SSELevel = NoSSE;
 | |
|   enum MMX3DNowEnum {
 | |
|     NoMMX3DNow,
 | |
|     MMX,
 | |
|     AMD3DNow,
 | |
|     AMD3DNowAthlon
 | |
|   } MMX3DNowLevel = NoMMX3DNow;
 | |
|   enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;
 | |
|   enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
 | |
| 
 | |
|   bool HasAES = false;
 | |
|   bool HasVAES = false;
 | |
|   bool HasPCLMUL = false;
 | |
|   bool HasVPCLMULQDQ = false;
 | |
|   bool HasGFNI = false;
 | |
|   bool HasLZCNT = false;
 | |
|   bool HasRDRND = false;
 | |
|   bool HasFSGSBASE = false;
 | |
|   bool HasBMI = false;
 | |
|   bool HasBMI2 = false;
 | |
|   bool HasPOPCNT = false;
 | |
|   bool HasRTM = false;
 | |
|   bool HasPRFCHW = false;
 | |
|   bool HasRDSEED = false;
 | |
|   bool HasADX = false;
 | |
|   bool HasTBM = false;
 | |
|   bool HasLWP = false;
 | |
|   bool HasFMA = false;
 | |
|   bool HasF16C = false;
 | |
|   bool HasAVX512CD = false;
 | |
|   bool HasAVX512VPOPCNTDQ = false;
 | |
|   bool HasAVX512VNNI = false;
 | |
|   bool HasAVX512BF16 = false;
 | |
|   bool HasAVX512ER = false;
 | |
|   bool HasAVX512PF = false;
 | |
|   bool HasAVX512DQ = false;
 | |
|   bool HasAVX512BITALG = false;
 | |
|   bool HasAVX512BW = false;
 | |
|   bool HasAVX512VL = false;
 | |
|   bool HasAVX512VBMI = false;
 | |
|   bool HasAVX512VBMI2 = false;
 | |
|   bool HasAVX512IFMA = false;
 | |
|   bool HasAVX512VP2INTERSECT = false;
 | |
|   bool HasSHA = false;
 | |
|   bool HasSHSTK = false;
 | |
|   bool HasSGX = false;
 | |
|   bool HasCX8 = false;
 | |
|   bool HasCX16 = false;
 | |
|   bool HasFXSR = false;
 | |
|   bool HasXSAVE = false;
 | |
|   bool HasXSAVEOPT = false;
 | |
|   bool HasXSAVEC = false;
 | |
|   bool HasXSAVES = false;
 | |
|   bool HasMWAITX = false;
 | |
|   bool HasCLZERO = false;
 | |
|   bool HasCLDEMOTE = false;
 | |
|   bool HasPCONFIG = false;
 | |
|   bool HasPKU = false;
 | |
|   bool HasCLFLUSHOPT = false;
 | |
|   bool HasCLWB = false;
 | |
|   bool HasMOVBE = false;
 | |
|   bool HasPREFETCHWT1 = false;
 | |
|   bool HasRDPID = false;
 | |
|   bool HasRetpolineExternalThunk = false;
 | |
|   bool HasLAHFSAHF = false;
 | |
|   bool HasWBNOINVD = false;
 | |
|   bool HasWAITPKG = false;
 | |
|   bool HasMOVDIRI = false;
 | |
|   bool HasMOVDIR64B = false;
 | |
|   bool HasPTWRITE = false;
 | |
|   bool HasINVPCID = false;
 | |
|   bool HasENQCMD = false;
 | |
| 
 | |
| protected:
 | |
|   /// Enumeration of all of the X86 CPUs supported by Clang.
 | |
|   ///
 | |
|   /// Each enumeration represents a particular CPU supported by Clang. These
 | |
|   /// loosely correspond to the options passed to '-march' or '-mtune' flags.
 | |
|   enum CPUKind {
 | |
|     CK_Generic,
 | |
| #define PROC(ENUM, STRING, IS64BIT) CK_##ENUM,
 | |
| #include "clang/Basic/X86Target.def"
 | |
|   } CPU = CK_Generic;
 | |
| 
 | |
|   bool checkCPUKind(CPUKind Kind) const;
 | |
| 
 | |
|   CPUKind getCPUKind(StringRef CPU) const;
 | |
| 
 | |
|   enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
 | |
| 
 | |
| public:
 | |
|   X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
 | |
|       : TargetInfo(Triple) {
 | |
|     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
 | |
|     AddrSpaceMap = &X86AddrSpaceMap;
 | |
|   }
 | |
| 
 | |
|   const char *getLongDoubleMangling() const override {
 | |
|     return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
 | |
|   }
 | |
| 
 | |
|   unsigned getFloatEvalMethod() const override {
 | |
|     // X87 evaluates with 80 bits "long double" precision.
 | |
|     return SSELevel == NoSSE ? 2 : 0;
 | |
|   }
 | |
| 
 | |
|   ArrayRef<const char *> getGCCRegNames() const override;
 | |
| 
 | |
|   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
 | |
|     return None;
 | |
|   }
 | |
| 
 | |
|   ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
 | |
| 
 | |
|   bool isSPRegName(StringRef RegName) const override {
 | |
|     return RegName.equals("esp") || RegName.equals("rsp");
 | |
|   }
 | |
| 
 | |
|   bool validateCpuSupports(StringRef Name) const override;
 | |
| 
 | |
|   bool validateCpuIs(StringRef Name) const override;
 | |
| 
 | |
|   bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
 | |
| 
 | |
|   char CPUSpecificManglingCharacter(StringRef Name) const override;
 | |
| 
 | |
|   void getCPUSpecificCPUDispatchFeatures(
 | |
|       StringRef Name,
 | |
|       llvm::SmallVectorImpl<StringRef> &Features) const override;
 | |
| 
 | |
|   bool validateAsmConstraint(const char *&Name,
 | |
|                              TargetInfo::ConstraintInfo &info) const override;
 | |
| 
 | |
|   bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
 | |
|                                       bool &HasSizeMismatch) const override {
 | |
|     // esp and ebp are the only 32-bit registers the x86 backend can currently
 | |
|     // handle.
 | |
|     if (RegName.equals("esp") || RegName.equals("ebp")) {
 | |
|       // Check that the register size is 32-bit.
 | |
|       HasSizeMismatch = RegSize != 32;
 | |
|       return true;
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
 | |
|                           StringRef Constraint, unsigned Size) const override;
 | |
| 
 | |
|   bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
 | |
|                          StringRef Constraint, unsigned Size) const override;
 | |
| 
 | |
|   virtual bool
 | |
|   checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
 | |
|     return true;
 | |
|   };
 | |
| 
 | |
|   virtual bool
 | |
|   checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
 | |
|     return true;
 | |
|   };
 | |
| 
 | |
|   virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
 | |
|                                    StringRef Constraint, unsigned Size) const;
 | |
| 
 | |
|   std::string convertConstraint(const char *&Constraint) const override;
 | |
|   const char *getClobbers() const override {
 | |
|     return "~{dirflag},~{fpsr},~{flags}";
 | |
|   }
 | |
| 
 | |
|   StringRef getConstraintRegister(StringRef Constraint,
 | |
|                                   StringRef Expression) const override {
 | |
|     StringRef::iterator I, E;
 | |
|     for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
 | |
|       if (isalpha(*I) || *I == '@')
 | |
|         break;
 | |
|     }
 | |
|     if (I == E)
 | |
|       return "";
 | |
|     switch (*I) {
 | |
|     // For the register constraints, return the matching register name
 | |
|     case 'a':
 | |
|       return "ax";
 | |
|     case 'b':
 | |
|       return "bx";
 | |
|     case 'c':
 | |
|       return "cx";
 | |
|     case 'd':
 | |
|       return "dx";
 | |
|     case 'S':
 | |
|       return "si";
 | |
|     case 'D':
 | |
|       return "di";
 | |
|     // In case the constraint is 'r' we need to return Expression
 | |
|     case 'r':
 | |
|       return Expression;
 | |
|     // Double letters Y<x> constraints
 | |
|     case 'Y':
 | |
|       if ((++I != E) && ((*I == '0') || (*I == 'z')))
 | |
|         return "xmm0";
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|     }
 | |
|     return "";
 | |
|   }
 | |
| 
 | |
|   bool useFP16ConversionIntrinsics() const override {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override;
 | |
| 
 | |
|   static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level,
 | |
|                           bool Enabled);
 | |
| 
 | |
|   static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level,
 | |
|                           bool Enabled);
 | |
| 
 | |
|   static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
 | |
|                           bool Enabled);
 | |
| 
 | |
|   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
 | |
|                          bool Enabled) const override {
 | |
|     setFeatureEnabledImpl(Features, Name, Enabled);
 | |
|   }
 | |
| 
 | |
|   // This exists purely to cut down on the number of virtual calls in
 | |
|   // initFeatureMap which calls this repeatedly.
 | |
|   static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
 | |
|                                     StringRef Name, bool Enabled);
 | |
| 
 | |
|   bool
 | |
|   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
 | |
|                  StringRef CPU,
 | |
|                  const std::vector<std::string> &FeaturesVec) const override;
 | |
| 
 | |
|   bool isValidFeatureName(StringRef Name) const override;
 | |
| 
 | |
|   bool hasFeature(StringRef Feature) const override;
 | |
| 
 | |
|   bool handleTargetFeatures(std::vector<std::string> &Features,
 | |
|                             DiagnosticsEngine &Diags) override;
 | |
| 
 | |
|   StringRef getABI() const override {
 | |
|     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
 | |
|       return "avx512";
 | |
|     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
 | |
|       return "avx";
 | |
|     if (getTriple().getArch() == llvm::Triple::x86 &&
 | |
|         MMX3DNowLevel == NoMMX3DNow)
 | |
|       return "no-mmx";
 | |
|     return "";
 | |
|   }
 | |
| 
 | |
|   bool isValidCPUName(StringRef Name) const override {
 | |
|     return checkCPUKind(getCPUKind(Name));
 | |
|   }
 | |
| 
 | |
|   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
 | |
| 
 | |
|   bool setCPU(const std::string &Name) override {
 | |
|     return checkCPUKind(CPU = getCPUKind(Name));
 | |
|   }
 | |
| 
 | |
|   unsigned multiVersionSortPriority(StringRef Name) const override;
 | |
| 
 | |
|   bool setFPMath(StringRef Name) override;
 | |
| 
 | |
|   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
 | |
|     // Most of the non-ARM calling conventions are i386 conventions.
 | |
|     switch (CC) {
 | |
|     case CC_X86ThisCall:
 | |
|     case CC_X86FastCall:
 | |
|     case CC_X86StdCall:
 | |
|     case CC_X86VectorCall:
 | |
|     case CC_X86RegCall:
 | |
|     case CC_C:
 | |
|     case CC_PreserveMost:
 | |
|     case CC_Swift:
 | |
|     case CC_X86Pascal:
 | |
|     case CC_IntelOclBicc:
 | |
|     case CC_OpenCLKernel:
 | |
|       return CCCR_OK;
 | |
|     default:
 | |
|       return CCCR_Warning;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   CallingConv getDefaultCallingConv() const override {
 | |
|     return CC_C;
 | |
|   }
 | |
| 
 | |
|   bool hasSjLjLowering() const override { return true; }
 | |
| 
 | |
|   void setSupportedOpenCLOpts() override {
 | |
|     getSupportedOpenCLOpts().supportAll();
 | |
|   }
 | |
| 
 | |
|   uint64_t getPointerWidthV(unsigned AddrSpace) const override {
 | |
|     if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr)
 | |
|       return 32;
 | |
|     if (AddrSpace == ptr64)
 | |
|       return 64;
 | |
|     return PointerWidth;
 | |
|   }
 | |
| 
 | |
|   uint64_t getPointerAlignV(unsigned AddrSpace) const override {
 | |
|     return getPointerWidthV(AddrSpace);
 | |
|   }
 | |
| };
 | |
| 
 | |
| // X86-32 generic target
 | |
| class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {
 | |
| public:
 | |
|   X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : X86TargetInfo(Triple, Opts) {
 | |
|     DoubleAlign = LongLongAlign = 32;
 | |
|     LongDoubleWidth = 96;
 | |
|     LongDoubleAlign = 32;
 | |
|     SuitableAlign = 128;
 | |
|     resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
 | |
|                     "f80:32-n8:16:32-S128");
 | |
|     SizeType = UnsignedInt;
 | |
|     PtrDiffType = SignedInt;
 | |
|     IntPtrType = SignedInt;
 | |
|     RegParmMax = 3;
 | |
| 
 | |
|     // Use fpret for all types.
 | |
|     RealTypeUsesObjCFPRet =
 | |
|         ((1 << TargetInfo::Float) | (1 << TargetInfo::Double) |
 | |
|          (1 << TargetInfo::LongDouble));
 | |
| 
 | |
|     // x86-32 has atomics up to 8 bytes
 | |
|     MaxAtomicPromoteWidth = 64;
 | |
|     MaxAtomicInlineWidth = 32;
 | |
|   }
 | |
| 
 | |
|   BuiltinVaListKind getBuiltinVaListKind() const override {
 | |
|     return TargetInfo::CharPtrBuiltinVaList;
 | |
|   }
 | |
| 
 | |
|   int getEHDataRegisterNumber(unsigned RegNo) const override {
 | |
|     if (RegNo == 0)
 | |
|       return 0;
 | |
|     if (RegNo == 1)
 | |
|       return 2;
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
 | |
|                            StringRef Constraint, unsigned Size) const override {
 | |
|     switch (Constraint[0]) {
 | |
|     default:
 | |
|       break;
 | |
|     case 'R':
 | |
|     case 'q':
 | |
|     case 'Q':
 | |
|     case 'a':
 | |
|     case 'b':
 | |
|     case 'c':
 | |
|     case 'd':
 | |
|     case 'S':
 | |
|     case 'D':
 | |
|       return Size <= 32;
 | |
|     case 'A':
 | |
|       return Size <= 64;
 | |
|     }
 | |
| 
 | |
|     return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);
 | |
|   }
 | |
| 
 | |
|   void setMaxAtomicWidth() override {
 | |
|     if (hasFeature("cx8"))
 | |
|       MaxAtomicInlineWidth = 64;
 | |
|   }
 | |
| 
 | |
|   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
 | |
| };
 | |
| 
 | |
| class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
 | |
|     : public NetBSDTargetInfo<X86_32TargetInfo> {
 | |
| public:
 | |
|   NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
 | |
| 
 | |
|   unsigned getFloatEvalMethod() const override {
 | |
|     unsigned Major, Minor, Micro;
 | |
|     getTriple().getOSVersion(Major, Minor, Micro);
 | |
|     // New NetBSD uses the default rounding mode.
 | |
|     if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0)
 | |
|       return X86_32TargetInfo::getFloatEvalMethod();
 | |
|     // NetBSD before 6.99.26 defaults to "double" rounding.
 | |
|     return 1;
 | |
|   }
 | |
| };
 | |
| 
 | |
| class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
 | |
|     : public OpenBSDTargetInfo<X86_32TargetInfo> {
 | |
| public:
 | |
|   OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
 | |
|     SizeType = UnsignedLong;
 | |
|     IntPtrType = SignedLong;
 | |
|     PtrDiffType = SignedLong;
 | |
|   }
 | |
| };
 | |
| 
 | |
| class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
 | |
|     : public DarwinTargetInfo<X86_32TargetInfo> {
 | |
| public:
 | |
|   DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
 | |
|     LongDoubleWidth = 128;
 | |
|     LongDoubleAlign = 128;
 | |
|     SuitableAlign = 128;
 | |
|     MaxVectorAlign = 256;
 | |
|     // The watchOS simulator uses the builtin bool type for Objective-C.
 | |
|     llvm::Triple T = llvm::Triple(Triple);
 | |
|     if (T.isWatchOS())
 | |
|       UseSignedCharForObjCBool = false;
 | |
|     SizeType = UnsignedLong;
 | |
|     IntPtrType = SignedLong;
 | |
|     resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
 | |
|                     "f80:128-n8:16:32-S128");
 | |
|     HasAlignMac68kSupport = true;
 | |
|   }
 | |
| 
 | |
|   bool handleTargetFeatures(std::vector<std::string> &Features,
 | |
|                             DiagnosticsEngine &Diags) override {
 | |
|     if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
 | |
|                                                                   Diags))
 | |
|       return false;
 | |
|     // We now know the features we have: we can decide how to align vectors.
 | |
|     MaxVectorAlign =
 | |
|         hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
 | |
|     return true;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-32 Windows target
 | |
| class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
 | |
|     : public WindowsTargetInfo<X86_32TargetInfo> {
 | |
| public:
 | |
|   WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
 | |
|     DoubleAlign = LongLongAlign = 64;
 | |
|     bool IsWinCOFF =
 | |
|         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
 | |
|     resetDataLayout(IsWinCOFF ? "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:"
 | |
|                                 "64-i64:64-f80:32-n8:16:32-a:0:32-S32"
 | |
|                               : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:"
 | |
|                                 "64-i64:64-f80:32-n8:16:32-a:0:32-S32");
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-32 Windows Visual Studio target
 | |
| class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
 | |
|     : public WindowsX86_32TargetInfo {
 | |
| public:
 | |
|   MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
 | |
|                             const TargetOptions &Opts)
 | |
|       : WindowsX86_32TargetInfo(Triple, Opts) {
 | |
|     LongDoubleWidth = LongDoubleAlign = 64;
 | |
|     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
 | |
|   }
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override {
 | |
|     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
 | |
|     // The value of the following reflects processor type.
 | |
|     // 300=386, 400=486, 500=Pentium, 600=Blend (default)
 | |
|     // We lost the original triple, so we use the default.
 | |
|     Builder.defineMacro("_M_IX86", "600");
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-32 MinGW target
 | |
| class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
 | |
|     : public WindowsX86_32TargetInfo {
 | |
| public:
 | |
|   MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : WindowsX86_32TargetInfo(Triple, Opts) {
 | |
|     HasFloat128 = true;
 | |
|   }
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override {
 | |
|     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
 | |
|     Builder.defineMacro("_X86_");
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-32 Cygwin target
 | |
| class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {
 | |
| public:
 | |
|   CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : X86_32TargetInfo(Triple, Opts) {
 | |
|     this->WCharType = TargetInfo::UnsignedShort;
 | |
|     DoubleAlign = LongLongAlign = 64;
 | |
|     resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:"
 | |
|                     "32-n8:16:32-a:0:32-S32");
 | |
|   }
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override {
 | |
|     X86_32TargetInfo::getTargetDefines(Opts, Builder);
 | |
|     Builder.defineMacro("_X86_");
 | |
|     Builder.defineMacro("__CYGWIN__");
 | |
|     Builder.defineMacro("__CYGWIN32__");
 | |
|     addCygMingDefines(Opts, Builder);
 | |
|     DefineStd(Builder, "unix", Opts);
 | |
|     if (Opts.CPlusPlus)
 | |
|       Builder.defineMacro("_GNU_SOURCE");
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-32 Haiku target
 | |
| class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
 | |
|     : public HaikuTargetInfo<X86_32TargetInfo> {
 | |
| public:
 | |
|   HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override {
 | |
|     HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
 | |
|     Builder.defineMacro("__INTEL__");
 | |
|   }
 | |
| };
 | |
| 
 | |
| // X86-32 MCU target
 | |
| class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {
 | |
| public:
 | |
|   MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : X86_32TargetInfo(Triple, Opts) {
 | |
|     LongDoubleWidth = 64;
 | |
|     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
 | |
|     resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:"
 | |
|                     "32-f128:32-n8:16:32-a:0:32-S32");
 | |
|     WIntType = UnsignedInt;
 | |
|   }
 | |
| 
 | |
|   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
 | |
|     // On MCU we support only C calling convention.
 | |
|     return CC == CC_C ? CCCR_OK : CCCR_Warning;
 | |
|   }
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override {
 | |
|     X86_32TargetInfo::getTargetDefines(Opts, Builder);
 | |
|     Builder.defineMacro("__iamcu");
 | |
|     Builder.defineMacro("__iamcu__");
 | |
|   }
 | |
| 
 | |
|   bool allowsLargerPreferedTypeAlignment() const override { return false; }
 | |
| };
 | |
| 
 | |
| // x86-32 RTEMS target
 | |
| class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {
 | |
| public:
 | |
|   RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : X86_32TargetInfo(Triple, Opts) {
 | |
|     SizeType = UnsignedLong;
 | |
|     IntPtrType = SignedLong;
 | |
|     PtrDiffType = SignedLong;
 | |
|   }
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override {
 | |
|     X86_32TargetInfo::getTargetDefines(Opts, Builder);
 | |
|     Builder.defineMacro("__INTEL__");
 | |
|     Builder.defineMacro("__rtems__");
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-64 generic target
 | |
| class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
 | |
| public:
 | |
|   X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : X86TargetInfo(Triple, Opts) {
 | |
|     const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32;
 | |
|     bool IsWinCOFF =
 | |
|         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
 | |
|     LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
 | |
|     LongDoubleWidth = 128;
 | |
|     LongDoubleAlign = 128;
 | |
|     LargeArrayMinWidth = 128;
 | |
|     LargeArrayAlign = 128;
 | |
|     SuitableAlign = 128;
 | |
|     SizeType = IsX32 ? UnsignedInt : UnsignedLong;
 | |
|     PtrDiffType = IsX32 ? SignedInt : SignedLong;
 | |
|     IntPtrType = IsX32 ? SignedInt : SignedLong;
 | |
|     IntMaxType = IsX32 ? SignedLongLong : SignedLong;
 | |
|     Int64Type = IsX32 ? SignedLongLong : SignedLong;
 | |
|     RegParmMax = 6;
 | |
| 
 | |
|     // Pointers are 32-bit in x32.
 | |
|     resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
 | |
|                             "i64:64-f80:128-n8:16:32:64-S128"
 | |
|                           : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:"
 | |
|                                         "64-i64:64-f80:128-n8:16:32:64-S128"
 | |
|                                       : "e-m:e-p270:32:32-p271:32:32-p272:64:"
 | |
|                                         "64-i64:64-f80:128-n8:16:32:64-S128");
 | |
| 
 | |
|     // Use fpret only for long double.
 | |
|     RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
 | |
| 
 | |
|     // Use fp2ret for _Complex long double.
 | |
|     ComplexLongDoubleUsesFP2Ret = true;
 | |
| 
 | |
|     // Make __builtin_ms_va_list available.
 | |
|     HasBuiltinMSVaList = true;
 | |
| 
 | |
|     // x86-64 has atomics up to 16 bytes.
 | |
|     MaxAtomicPromoteWidth = 128;
 | |
|     MaxAtomicInlineWidth = 64;
 | |
|   }
 | |
| 
 | |
|   BuiltinVaListKind getBuiltinVaListKind() const override {
 | |
|     return TargetInfo::X86_64ABIBuiltinVaList;
 | |
|   }
 | |
| 
 | |
|   int getEHDataRegisterNumber(unsigned RegNo) const override {
 | |
|     if (RegNo == 0)
 | |
|       return 0;
 | |
|     if (RegNo == 1)
 | |
|       return 1;
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
 | |
|     switch (CC) {
 | |
|     case CC_C:
 | |
|     case CC_Swift:
 | |
|     case CC_X86VectorCall:
 | |
|     case CC_IntelOclBicc:
 | |
|     case CC_Win64:
 | |
|     case CC_PreserveMost:
 | |
|     case CC_PreserveAll:
 | |
|     case CC_X86RegCall:
 | |
|     case CC_OpenCLKernel:
 | |
|       return CCCR_OK;
 | |
|     default:
 | |
|       return CCCR_Warning;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   CallingConv getDefaultCallingConv() const override {
 | |
|     return CC_C;
 | |
|   }
 | |
| 
 | |
|   // for x32 we need it here explicitly
 | |
|   bool hasInt128Type() const override { return true; }
 | |
| 
 | |
|   unsigned getUnwindWordWidth() const override { return 64; }
 | |
| 
 | |
|   unsigned getRegisterWidth() const override { return 64; }
 | |
| 
 | |
|   bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
 | |
|                                       bool &HasSizeMismatch) const override {
 | |
|     // rsp and rbp are the only 64-bit registers the x86 backend can currently
 | |
|     // handle.
 | |
|     if (RegName.equals("rsp") || RegName.equals("rbp")) {
 | |
|       // Check that the register size is 64-bit.
 | |
|       HasSizeMismatch = RegSize != 64;
 | |
|       return true;
 | |
|     }
 | |
| 
 | |
|     // Check if the register is a 32-bit register the backend can handle.
 | |
|     return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
 | |
|                                                          HasSizeMismatch);
 | |
|   }
 | |
| 
 | |
|   void setMaxAtomicWidth() override {
 | |
|     if (hasFeature("cx16"))
 | |
|       MaxAtomicInlineWidth = 128;
 | |
|   }
 | |
| 
 | |
|   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
 | |
| };
 | |
| 
 | |
| // x86-64 Windows target
 | |
| class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
 | |
|     : public WindowsTargetInfo<X86_64TargetInfo> {
 | |
| public:
 | |
|   WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
 | |
|     LongWidth = LongAlign = 32;
 | |
|     DoubleAlign = LongLongAlign = 64;
 | |
|     IntMaxType = SignedLongLong;
 | |
|     Int64Type = SignedLongLong;
 | |
|     SizeType = UnsignedLongLong;
 | |
|     PtrDiffType = SignedLongLong;
 | |
|     IntPtrType = SignedLongLong;
 | |
|   }
 | |
| 
 | |
|   BuiltinVaListKind getBuiltinVaListKind() const override {
 | |
|     return TargetInfo::CharPtrBuiltinVaList;
 | |
|   }
 | |
| 
 | |
|   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
 | |
|     switch (CC) {
 | |
|     case CC_X86StdCall:
 | |
|     case CC_X86ThisCall:
 | |
|     case CC_X86FastCall:
 | |
|       return CCCR_Ignore;
 | |
|     case CC_C:
 | |
|     case CC_X86VectorCall:
 | |
|     case CC_IntelOclBicc:
 | |
|     case CC_PreserveMost:
 | |
|     case CC_PreserveAll:
 | |
|     case CC_X86_64SysV:
 | |
|     case CC_Swift:
 | |
|     case CC_X86RegCall:
 | |
|     case CC_OpenCLKernel:
 | |
|       return CCCR_OK;
 | |
|     default:
 | |
|       return CCCR_Warning;
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-64 Windows Visual Studio target
 | |
| class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
 | |
|     : public WindowsX86_64TargetInfo {
 | |
| public:
 | |
|   MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
 | |
|                             const TargetOptions &Opts)
 | |
|       : WindowsX86_64TargetInfo(Triple, Opts) {
 | |
|     LongDoubleWidth = LongDoubleAlign = 64;
 | |
|     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
 | |
|   }
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override {
 | |
|     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
 | |
|     Builder.defineMacro("_M_X64", "100");
 | |
|     Builder.defineMacro("_M_AMD64", "100");
 | |
|   }
 | |
| 
 | |
|   TargetInfo::CallingConvKind
 | |
|   getCallingConvKind(bool ClangABICompat4) const override {
 | |
|     return CCK_MicrosoftWin64;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-64 MinGW target
 | |
| class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
 | |
|     : public WindowsX86_64TargetInfo {
 | |
| public:
 | |
|   MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : WindowsX86_64TargetInfo(Triple, Opts) {
 | |
|     // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
 | |
|     // with x86 FP ops. Weird.
 | |
|     LongDoubleWidth = LongDoubleAlign = 128;
 | |
|     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
 | |
|     HasFloat128 = true;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86-64 Cygwin target
 | |
| class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {
 | |
| public:
 | |
|   CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : X86_64TargetInfo(Triple, Opts) {
 | |
|     this->WCharType = TargetInfo::UnsignedShort;
 | |
|     TLSSupported = false;
 | |
|   }
 | |
| 
 | |
|   void getTargetDefines(const LangOptions &Opts,
 | |
|                         MacroBuilder &Builder) const override {
 | |
|     X86_64TargetInfo::getTargetDefines(Opts, Builder);
 | |
|     Builder.defineMacro("__x86_64__");
 | |
|     Builder.defineMacro("__CYGWIN__");
 | |
|     Builder.defineMacro("__CYGWIN64__");
 | |
|     addCygMingDefines(Opts, Builder);
 | |
|     DefineStd(Builder, "unix", Opts);
 | |
|     if (Opts.CPlusPlus)
 | |
|       Builder.defineMacro("_GNU_SOURCE");
 | |
|   }
 | |
| };
 | |
| 
 | |
| class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
 | |
|     : public DarwinTargetInfo<X86_64TargetInfo> {
 | |
| public:
 | |
|   DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
 | |
|     Int64Type = SignedLongLong;
 | |
|     // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
 | |
|     llvm::Triple T = llvm::Triple(Triple);
 | |
|     if (T.isiOS())
 | |
|       UseSignedCharForObjCBool = false;
 | |
|     resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:"
 | |
|                     "16:32:64-S128");
 | |
|   }
 | |
| 
 | |
|   bool handleTargetFeatures(std::vector<std::string> &Features,
 | |
|                             DiagnosticsEngine &Diags) override {
 | |
|     if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
 | |
|                                                                   Diags))
 | |
|       return false;
 | |
|     // We now know the features we have: we can decide how to align vectors.
 | |
|     MaxVectorAlign =
 | |
|         hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
 | |
|     return true;
 | |
|   }
 | |
| };
 | |
| 
 | |
| class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
 | |
|     : public OpenBSDTargetInfo<X86_64TargetInfo> {
 | |
| public:
 | |
|   OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
 | |
|     IntMaxType = SignedLongLong;
 | |
|     Int64Type = SignedLongLong;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86_32 Android target
 | |
| class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
 | |
|     : public LinuxTargetInfo<X86_32TargetInfo> {
 | |
| public:
 | |
|   AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
 | |
|     SuitableAlign = 32;
 | |
|     LongDoubleWidth = 64;
 | |
|     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // x86_64 Android target
 | |
| class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
 | |
|     : public LinuxTargetInfo<X86_64TargetInfo> {
 | |
| public:
 | |
|   AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
 | |
|       : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
 | |
|     LongDoubleFormat = &llvm::APFloat::IEEEquad();
 | |
|   }
 | |
| };
 | |
| } // namespace targets
 | |
| } // namespace clang
 | |
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
 |