xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Basic/Targets/X86.h (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- X86.h - Declare X86 target feature support -------------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file declares X86 TargetInfo objects.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
147330f729Sjoerg #define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
157330f729Sjoerg 
167330f729Sjoerg #include "OSTargets.h"
177330f729Sjoerg #include "clang/Basic/TargetInfo.h"
187330f729Sjoerg #include "clang/Basic/TargetOptions.h"
197330f729Sjoerg #include "llvm/ADT/Triple.h"
207330f729Sjoerg #include "llvm/Support/Compiler.h"
21*e038c9c4Sjoerg #include "llvm/Support/X86TargetParser.h"
227330f729Sjoerg 
237330f729Sjoerg namespace clang {
247330f729Sjoerg namespace targets {
257330f729Sjoerg 
26*e038c9c4Sjoerg static const unsigned X86AddrSpaceMap[] = {
27*e038c9c4Sjoerg     0,   // Default
28*e038c9c4Sjoerg     0,   // opencl_global
29*e038c9c4Sjoerg     0,   // opencl_local
30*e038c9c4Sjoerg     0,   // opencl_constant
31*e038c9c4Sjoerg     0,   // opencl_private
32*e038c9c4Sjoerg     0,   // opencl_generic
33*e038c9c4Sjoerg     0,   // opencl_global_device
34*e038c9c4Sjoerg     0,   // opencl_global_host
35*e038c9c4Sjoerg     0,   // cuda_device
36*e038c9c4Sjoerg     0,   // cuda_constant
37*e038c9c4Sjoerg     0,   // cuda_shared
38*e038c9c4Sjoerg     0,   // sycl_global
39*e038c9c4Sjoerg     0,   // sycl_global_device
40*e038c9c4Sjoerg     0,   // sycl_global_host
41*e038c9c4Sjoerg     0,   // sycl_local
42*e038c9c4Sjoerg     0,   // sycl_private
43*e038c9c4Sjoerg     270, // ptr32_sptr
44*e038c9c4Sjoerg     271, // ptr32_uptr
45*e038c9c4Sjoerg     272  // ptr64
46*e038c9c4Sjoerg };
47*e038c9c4Sjoerg 
487330f729Sjoerg // X86 target abstract base class; x86-32 and x86-64 are very close, so
497330f729Sjoerg // most of the implementation can be shared.
507330f729Sjoerg class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
517330f729Sjoerg 
527330f729Sjoerg   enum X86SSEEnum {
537330f729Sjoerg     NoSSE,
547330f729Sjoerg     SSE1,
557330f729Sjoerg     SSE2,
567330f729Sjoerg     SSE3,
577330f729Sjoerg     SSSE3,
587330f729Sjoerg     SSE41,
597330f729Sjoerg     SSE42,
607330f729Sjoerg     AVX,
617330f729Sjoerg     AVX2,
627330f729Sjoerg     AVX512F
637330f729Sjoerg   } SSELevel = NoSSE;
647330f729Sjoerg   enum MMX3DNowEnum {
657330f729Sjoerg     NoMMX3DNow,
667330f729Sjoerg     MMX,
677330f729Sjoerg     AMD3DNow,
687330f729Sjoerg     AMD3DNowAthlon
697330f729Sjoerg   } MMX3DNowLevel = NoMMX3DNow;
707330f729Sjoerg   enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;
71*e038c9c4Sjoerg   enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
727330f729Sjoerg 
737330f729Sjoerg   bool HasAES = false;
747330f729Sjoerg   bool HasVAES = false;
757330f729Sjoerg   bool HasPCLMUL = false;
767330f729Sjoerg   bool HasVPCLMULQDQ = false;
777330f729Sjoerg   bool HasGFNI = false;
787330f729Sjoerg   bool HasLZCNT = false;
797330f729Sjoerg   bool HasRDRND = false;
807330f729Sjoerg   bool HasFSGSBASE = false;
817330f729Sjoerg   bool HasBMI = false;
827330f729Sjoerg   bool HasBMI2 = false;
837330f729Sjoerg   bool HasPOPCNT = false;
847330f729Sjoerg   bool HasRTM = false;
857330f729Sjoerg   bool HasPRFCHW = false;
867330f729Sjoerg   bool HasRDSEED = false;
877330f729Sjoerg   bool HasADX = false;
887330f729Sjoerg   bool HasTBM = false;
897330f729Sjoerg   bool HasLWP = false;
907330f729Sjoerg   bool HasFMA = false;
917330f729Sjoerg   bool HasF16C = false;
927330f729Sjoerg   bool HasAVX512CD = false;
937330f729Sjoerg   bool HasAVX512VPOPCNTDQ = false;
947330f729Sjoerg   bool HasAVX512VNNI = false;
957330f729Sjoerg   bool HasAVX512BF16 = false;
967330f729Sjoerg   bool HasAVX512ER = false;
977330f729Sjoerg   bool HasAVX512PF = false;
987330f729Sjoerg   bool HasAVX512DQ = false;
997330f729Sjoerg   bool HasAVX512BITALG = false;
1007330f729Sjoerg   bool HasAVX512BW = false;
1017330f729Sjoerg   bool HasAVX512VL = false;
1027330f729Sjoerg   bool HasAVX512VBMI = false;
1037330f729Sjoerg   bool HasAVX512VBMI2 = false;
1047330f729Sjoerg   bool HasAVX512IFMA = false;
1057330f729Sjoerg   bool HasAVX512VP2INTERSECT = false;
1067330f729Sjoerg   bool HasSHA = false;
1077330f729Sjoerg   bool HasSHSTK = false;
1087330f729Sjoerg   bool HasSGX = false;
1097330f729Sjoerg   bool HasCX8 = false;
1107330f729Sjoerg   bool HasCX16 = false;
1117330f729Sjoerg   bool HasFXSR = false;
1127330f729Sjoerg   bool HasXSAVE = false;
1137330f729Sjoerg   bool HasXSAVEOPT = false;
1147330f729Sjoerg   bool HasXSAVEC = false;
1157330f729Sjoerg   bool HasXSAVES = false;
1167330f729Sjoerg   bool HasMWAITX = false;
1177330f729Sjoerg   bool HasCLZERO = false;
1187330f729Sjoerg   bool HasCLDEMOTE = false;
1197330f729Sjoerg   bool HasPCONFIG = false;
1207330f729Sjoerg   bool HasPKU = false;
1217330f729Sjoerg   bool HasCLFLUSHOPT = false;
1227330f729Sjoerg   bool HasCLWB = false;
1237330f729Sjoerg   bool HasMOVBE = false;
1247330f729Sjoerg   bool HasPREFETCHWT1 = false;
1257330f729Sjoerg   bool HasRDPID = false;
1267330f729Sjoerg   bool HasRetpolineExternalThunk = false;
1277330f729Sjoerg   bool HasLAHFSAHF = false;
1287330f729Sjoerg   bool HasWBNOINVD = false;
1297330f729Sjoerg   bool HasWAITPKG = false;
1307330f729Sjoerg   bool HasMOVDIRI = false;
1317330f729Sjoerg   bool HasMOVDIR64B = false;
1327330f729Sjoerg   bool HasPTWRITE = false;
1337330f729Sjoerg   bool HasINVPCID = false;
1347330f729Sjoerg   bool HasENQCMD = false;
135*e038c9c4Sjoerg   bool HasKL = false;      // For key locker
136*e038c9c4Sjoerg   bool HasWIDEKL = false; // For wide key locker
137*e038c9c4Sjoerg   bool HasHRESET = false;
138*e038c9c4Sjoerg   bool HasAVXVNNI = false;
139*e038c9c4Sjoerg   bool HasAMXTILE = false;
140*e038c9c4Sjoerg   bool HasAMXINT8 = false;
141*e038c9c4Sjoerg   bool HasAMXBF16 = false;
142*e038c9c4Sjoerg   bool HasSERIALIZE = false;
143*e038c9c4Sjoerg   bool HasTSXLDTRK = false;
144*e038c9c4Sjoerg   bool HasUINTR = false;
1457330f729Sjoerg 
1467330f729Sjoerg protected:
147*e038c9c4Sjoerg   llvm::X86::CPUKind CPU = llvm::X86::CK_None;
1487330f729Sjoerg 
1497330f729Sjoerg   enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
1507330f729Sjoerg 
1517330f729Sjoerg public:
X86TargetInfo(const llvm::Triple & Triple,const TargetOptions &)1527330f729Sjoerg   X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
1537330f729Sjoerg       : TargetInfo(Triple) {
1547330f729Sjoerg     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
155*e038c9c4Sjoerg     AddrSpaceMap = &X86AddrSpaceMap;
156*e038c9c4Sjoerg     HasStrictFP = true;
157*e038c9c4Sjoerg 
158*e038c9c4Sjoerg     bool IsWinCOFF =
159*e038c9c4Sjoerg         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
160*e038c9c4Sjoerg     if (IsWinCOFF)
161*e038c9c4Sjoerg       MaxVectorAlign = MaxTLSAlign = 8192u * getCharWidth();
1627330f729Sjoerg   }
1637330f729Sjoerg 
getLongDoubleMangling()1647330f729Sjoerg   const char *getLongDoubleMangling() const override {
1657330f729Sjoerg     return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
1667330f729Sjoerg   }
1677330f729Sjoerg 
getFloatEvalMethod()1687330f729Sjoerg   unsigned getFloatEvalMethod() const override {
1697330f729Sjoerg     // X87 evaluates with 80 bits "long double" precision.
1707330f729Sjoerg     return SSELevel == NoSSE ? 2 : 0;
1717330f729Sjoerg   }
1727330f729Sjoerg 
1737330f729Sjoerg   ArrayRef<const char *> getGCCRegNames() const override;
1747330f729Sjoerg 
getGCCRegAliases()1757330f729Sjoerg   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
1767330f729Sjoerg     return None;
1777330f729Sjoerg   }
1787330f729Sjoerg 
1797330f729Sjoerg   ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
1807330f729Sjoerg 
isSPRegName(StringRef RegName)181*e038c9c4Sjoerg   bool isSPRegName(StringRef RegName) const override {
182*e038c9c4Sjoerg     return RegName.equals("esp") || RegName.equals("rsp");
183*e038c9c4Sjoerg   }
184*e038c9c4Sjoerg 
1857330f729Sjoerg   bool validateCpuSupports(StringRef Name) const override;
1867330f729Sjoerg 
1877330f729Sjoerg   bool validateCpuIs(StringRef Name) const override;
1887330f729Sjoerg 
1897330f729Sjoerg   bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
1907330f729Sjoerg 
1917330f729Sjoerg   char CPUSpecificManglingCharacter(StringRef Name) const override;
1927330f729Sjoerg 
1937330f729Sjoerg   void getCPUSpecificCPUDispatchFeatures(
1947330f729Sjoerg       StringRef Name,
1957330f729Sjoerg       llvm::SmallVectorImpl<StringRef> &Features) const override;
1967330f729Sjoerg 
197*e038c9c4Sjoerg   Optional<unsigned> getCPUCacheLineSize() const override;
198*e038c9c4Sjoerg 
1997330f729Sjoerg   bool validateAsmConstraint(const char *&Name,
2007330f729Sjoerg                              TargetInfo::ConstraintInfo &info) const override;
2017330f729Sjoerg 
validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch)2027330f729Sjoerg   bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
2037330f729Sjoerg                                       bool &HasSizeMismatch) const override {
2047330f729Sjoerg     // esp and ebp are the only 32-bit registers the x86 backend can currently
2057330f729Sjoerg     // handle.
2067330f729Sjoerg     if (RegName.equals("esp") || RegName.equals("ebp")) {
2077330f729Sjoerg       // Check that the register size is 32-bit.
2087330f729Sjoerg       HasSizeMismatch = RegSize != 32;
2097330f729Sjoerg       return true;
2107330f729Sjoerg     }
2117330f729Sjoerg 
2127330f729Sjoerg     return false;
2137330f729Sjoerg   }
2147330f729Sjoerg 
215*e038c9c4Sjoerg   bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
216*e038c9c4Sjoerg                           StringRef Constraint, unsigned Size) const override;
2177330f729Sjoerg 
218*e038c9c4Sjoerg   bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
219*e038c9c4Sjoerg                          StringRef Constraint, unsigned Size) const override;
2207330f729Sjoerg 
2217330f729Sjoerg   virtual bool
checkCFProtectionReturnSupported(DiagnosticsEngine & Diags)2227330f729Sjoerg   checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
2237330f729Sjoerg     return true;
2247330f729Sjoerg   };
2257330f729Sjoerg 
2267330f729Sjoerg   virtual bool
checkCFProtectionBranchSupported(DiagnosticsEngine & Diags)2277330f729Sjoerg   checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
2287330f729Sjoerg     return true;
2297330f729Sjoerg   };
2307330f729Sjoerg 
231*e038c9c4Sjoerg   virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
232*e038c9c4Sjoerg                                    StringRef Constraint, unsigned Size) const;
2337330f729Sjoerg 
2347330f729Sjoerg   std::string convertConstraint(const char *&Constraint) const override;
getClobbers()2357330f729Sjoerg   const char *getClobbers() const override {
2367330f729Sjoerg     return "~{dirflag},~{fpsr},~{flags}";
2377330f729Sjoerg   }
2387330f729Sjoerg 
getConstraintRegister(StringRef Constraint,StringRef Expression)2397330f729Sjoerg   StringRef getConstraintRegister(StringRef Constraint,
2407330f729Sjoerg                                   StringRef Expression) const override {
2417330f729Sjoerg     StringRef::iterator I, E;
2427330f729Sjoerg     for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
2437330f729Sjoerg       if (isalpha(*I) || *I == '@')
2447330f729Sjoerg         break;
2457330f729Sjoerg     }
2467330f729Sjoerg     if (I == E)
2477330f729Sjoerg       return "";
2487330f729Sjoerg     switch (*I) {
2497330f729Sjoerg     // For the register constraints, return the matching register name
2507330f729Sjoerg     case 'a':
2517330f729Sjoerg       return "ax";
2527330f729Sjoerg     case 'b':
2537330f729Sjoerg       return "bx";
2547330f729Sjoerg     case 'c':
2557330f729Sjoerg       return "cx";
2567330f729Sjoerg     case 'd':
2577330f729Sjoerg       return "dx";
2587330f729Sjoerg     case 'S':
2597330f729Sjoerg       return "si";
2607330f729Sjoerg     case 'D':
2617330f729Sjoerg       return "di";
2627330f729Sjoerg     // In case the constraint is 'r' we need to return Expression
2637330f729Sjoerg     case 'r':
2647330f729Sjoerg       return Expression;
2657330f729Sjoerg     // Double letters Y<x> constraints
2667330f729Sjoerg     case 'Y':
2677330f729Sjoerg       if ((++I != E) && ((*I == '0') || (*I == 'z')))
2687330f729Sjoerg         return "xmm0";
2697330f729Sjoerg       break;
2707330f729Sjoerg     default:
2717330f729Sjoerg       break;
2727330f729Sjoerg     }
2737330f729Sjoerg     return "";
2747330f729Sjoerg   }
2757330f729Sjoerg 
useFP16ConversionIntrinsics()2767330f729Sjoerg   bool useFP16ConversionIntrinsics() const override {
2777330f729Sjoerg     return false;
2787330f729Sjoerg   }
2797330f729Sjoerg 
2807330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
2817330f729Sjoerg                         MacroBuilder &Builder) const override;
2827330f729Sjoerg 
2837330f729Sjoerg   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
284*e038c9c4Sjoerg                          bool Enabled) const final;
2857330f729Sjoerg 
2867330f729Sjoerg   bool
2877330f729Sjoerg   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
2887330f729Sjoerg                  StringRef CPU,
2897330f729Sjoerg                  const std::vector<std::string> &FeaturesVec) const override;
2907330f729Sjoerg 
2917330f729Sjoerg   bool isValidFeatureName(StringRef Name) const override;
2927330f729Sjoerg 
293*e038c9c4Sjoerg   bool hasFeature(StringRef Feature) const final;
2947330f729Sjoerg 
2957330f729Sjoerg   bool handleTargetFeatures(std::vector<std::string> &Features,
2967330f729Sjoerg                             DiagnosticsEngine &Diags) override;
2977330f729Sjoerg 
getABI()2987330f729Sjoerg   StringRef getABI() const override {
2997330f729Sjoerg     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
3007330f729Sjoerg       return "avx512";
3017330f729Sjoerg     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
3027330f729Sjoerg       return "avx";
3037330f729Sjoerg     if (getTriple().getArch() == llvm::Triple::x86 &&
3047330f729Sjoerg         MMX3DNowLevel == NoMMX3DNow)
3057330f729Sjoerg       return "no-mmx";
3067330f729Sjoerg     return "";
3077330f729Sjoerg   }
3087330f729Sjoerg 
supportsTargetAttributeTune()309*e038c9c4Sjoerg   bool supportsTargetAttributeTune() const override {
310*e038c9c4Sjoerg     return true;
311*e038c9c4Sjoerg   }
312*e038c9c4Sjoerg 
isValidCPUName(StringRef Name)3137330f729Sjoerg   bool isValidCPUName(StringRef Name) const override {
314*e038c9c4Sjoerg     bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
315*e038c9c4Sjoerg     return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None;
316*e038c9c4Sjoerg   }
317*e038c9c4Sjoerg 
isValidTuneCPUName(StringRef Name)318*e038c9c4Sjoerg   bool isValidTuneCPUName(StringRef Name) const override {
319*e038c9c4Sjoerg     if (Name == "generic")
320*e038c9c4Sjoerg       return true;
321*e038c9c4Sjoerg 
322*e038c9c4Sjoerg     // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
323*e038c9c4Sjoerg     // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
324*e038c9c4Sjoerg     // since mtune was ignored by clang for so long.
325*e038c9c4Sjoerg     return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None;
3267330f729Sjoerg   }
3277330f729Sjoerg 
3287330f729Sjoerg   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
329*e038c9c4Sjoerg   void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
3307330f729Sjoerg 
setCPU(const std::string & Name)3317330f729Sjoerg   bool setCPU(const std::string &Name) override {
332*e038c9c4Sjoerg     bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
333*e038c9c4Sjoerg     CPU = llvm::X86::parseArchX86(Name, Only64Bit);
334*e038c9c4Sjoerg     return CPU != llvm::X86::CK_None;
3357330f729Sjoerg   }
3367330f729Sjoerg 
3377330f729Sjoerg   unsigned multiVersionSortPriority(StringRef Name) const override;
3387330f729Sjoerg 
3397330f729Sjoerg   bool setFPMath(StringRef Name) override;
3407330f729Sjoerg 
supportsExtendIntArgs()341*e038c9c4Sjoerg   bool supportsExtendIntArgs() const override {
342*e038c9c4Sjoerg     return getTriple().getArch() != llvm::Triple::x86;
343*e038c9c4Sjoerg   }
344*e038c9c4Sjoerg 
checkCallingConvention(CallingConv CC)3457330f729Sjoerg   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
3467330f729Sjoerg     // Most of the non-ARM calling conventions are i386 conventions.
3477330f729Sjoerg     switch (CC) {
3487330f729Sjoerg     case CC_X86ThisCall:
3497330f729Sjoerg     case CC_X86FastCall:
3507330f729Sjoerg     case CC_X86StdCall:
3517330f729Sjoerg     case CC_X86VectorCall:
3527330f729Sjoerg     case CC_X86RegCall:
3537330f729Sjoerg     case CC_C:
3547330f729Sjoerg     case CC_PreserveMost:
3557330f729Sjoerg     case CC_Swift:
3567330f729Sjoerg     case CC_X86Pascal:
3577330f729Sjoerg     case CC_IntelOclBicc:
3587330f729Sjoerg     case CC_OpenCLKernel:
3597330f729Sjoerg       return CCCR_OK;
3607330f729Sjoerg     default:
3617330f729Sjoerg       return CCCR_Warning;
3627330f729Sjoerg     }
3637330f729Sjoerg   }
3647330f729Sjoerg 
getDefaultCallingConv()3657330f729Sjoerg   CallingConv getDefaultCallingConv() const override {
3667330f729Sjoerg     return CC_C;
3677330f729Sjoerg   }
3687330f729Sjoerg 
hasSjLjLowering()3697330f729Sjoerg   bool hasSjLjLowering() const override { return true; }
3707330f729Sjoerg 
setSupportedOpenCLOpts()371*e038c9c4Sjoerg   void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
372*e038c9c4Sjoerg 
getPointerWidthV(unsigned AddrSpace)373*e038c9c4Sjoerg   uint64_t getPointerWidthV(unsigned AddrSpace) const override {
374*e038c9c4Sjoerg     if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr)
375*e038c9c4Sjoerg       return 32;
376*e038c9c4Sjoerg     if (AddrSpace == ptr64)
377*e038c9c4Sjoerg       return 64;
378*e038c9c4Sjoerg     return PointerWidth;
379*e038c9c4Sjoerg   }
380*e038c9c4Sjoerg 
getPointerAlignV(unsigned AddrSpace)381*e038c9c4Sjoerg   uint64_t getPointerAlignV(unsigned AddrSpace) const override {
382*e038c9c4Sjoerg     return getPointerWidthV(AddrSpace);
3837330f729Sjoerg   }
3847330f729Sjoerg };
3857330f729Sjoerg 
3867330f729Sjoerg // X86-32 generic target
3877330f729Sjoerg class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {
3887330f729Sjoerg public:
X86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)3897330f729Sjoerg   X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
3907330f729Sjoerg       : X86TargetInfo(Triple, Opts) {
3917330f729Sjoerg     DoubleAlign = LongLongAlign = 32;
3927330f729Sjoerg     LongDoubleWidth = 96;
3937330f729Sjoerg     LongDoubleAlign = 32;
3947330f729Sjoerg     SuitableAlign = 128;
395*e038c9c4Sjoerg     resetDataLayout(
396*e038c9c4Sjoerg         Triple.isOSBinFormatMachO()
397*e038c9c4Sjoerg             ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
398*e038c9c4Sjoerg               "f80:32-n8:16:32-S128"
399*e038c9c4Sjoerg             : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
400*e038c9c4Sjoerg               "f80:32-n8:16:32-S128",
401*e038c9c4Sjoerg         Triple.isOSBinFormatMachO() ? "_" : "");
4027330f729Sjoerg     SizeType = UnsignedInt;
4037330f729Sjoerg     PtrDiffType = SignedInt;
4047330f729Sjoerg     IntPtrType = SignedInt;
4057330f729Sjoerg     RegParmMax = 3;
4067330f729Sjoerg 
4077330f729Sjoerg     // Use fpret for all types.
4087330f729Sjoerg     RealTypeUsesObjCFPRet =
4097330f729Sjoerg         ((1 << TargetInfo::Float) | (1 << TargetInfo::Double) |
4107330f729Sjoerg          (1 << TargetInfo::LongDouble));
4117330f729Sjoerg 
4127330f729Sjoerg     // x86-32 has atomics up to 8 bytes
4137330f729Sjoerg     MaxAtomicPromoteWidth = 64;
4147330f729Sjoerg     MaxAtomicInlineWidth = 32;
4157330f729Sjoerg   }
4167330f729Sjoerg 
getBuiltinVaListKind()4177330f729Sjoerg   BuiltinVaListKind getBuiltinVaListKind() const override {
4187330f729Sjoerg     return TargetInfo::CharPtrBuiltinVaList;
4197330f729Sjoerg   }
4207330f729Sjoerg 
getEHDataRegisterNumber(unsigned RegNo)4217330f729Sjoerg   int getEHDataRegisterNumber(unsigned RegNo) const override {
4227330f729Sjoerg     if (RegNo == 0)
4237330f729Sjoerg       return 0;
4247330f729Sjoerg     if (RegNo == 1)
4257330f729Sjoerg       return 2;
4267330f729Sjoerg     return -1;
4277330f729Sjoerg   }
4287330f729Sjoerg 
validateOperandSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size)429*e038c9c4Sjoerg   bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
430*e038c9c4Sjoerg                            StringRef Constraint, unsigned Size) const override {
4317330f729Sjoerg     switch (Constraint[0]) {
4327330f729Sjoerg     default:
4337330f729Sjoerg       break;
4347330f729Sjoerg     case 'R':
4357330f729Sjoerg     case 'q':
4367330f729Sjoerg     case 'Q':
4377330f729Sjoerg     case 'a':
4387330f729Sjoerg     case 'b':
4397330f729Sjoerg     case 'c':
4407330f729Sjoerg     case 'd':
4417330f729Sjoerg     case 'S':
4427330f729Sjoerg     case 'D':
4437330f729Sjoerg       return Size <= 32;
4447330f729Sjoerg     case 'A':
4457330f729Sjoerg       return Size <= 64;
4467330f729Sjoerg     }
4477330f729Sjoerg 
448*e038c9c4Sjoerg     return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);
4497330f729Sjoerg   }
4507330f729Sjoerg 
setMaxAtomicWidth()4517330f729Sjoerg   void setMaxAtomicWidth() override {
4527330f729Sjoerg     if (hasFeature("cx8"))
4537330f729Sjoerg       MaxAtomicInlineWidth = 64;
4547330f729Sjoerg   }
4557330f729Sjoerg 
4567330f729Sjoerg   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
457*e038c9c4Sjoerg 
hasExtIntType()458*e038c9c4Sjoerg   bool hasExtIntType() const override { return true; }
4597330f729Sjoerg };
4607330f729Sjoerg 
4617330f729Sjoerg class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
4627330f729Sjoerg     : public NetBSDTargetInfo<X86_32TargetInfo> {
4637330f729Sjoerg public:
NetBSDI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4647330f729Sjoerg   NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4657330f729Sjoerg       : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
4667330f729Sjoerg 
getFloatEvalMethod()4677330f729Sjoerg   unsigned getFloatEvalMethod() const override {
4687330f729Sjoerg     unsigned Major, Minor, Micro;
4697330f729Sjoerg     getTriple().getOSVersion(Major, Minor, Micro);
4707330f729Sjoerg     // New NetBSD uses the default rounding mode.
4717330f729Sjoerg     if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0)
4727330f729Sjoerg       return X86_32TargetInfo::getFloatEvalMethod();
4737330f729Sjoerg     // NetBSD before 6.99.26 defaults to "double" rounding.
4747330f729Sjoerg     return 1;
4757330f729Sjoerg   }
4767330f729Sjoerg };
4777330f729Sjoerg 
4787330f729Sjoerg class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
4797330f729Sjoerg     : public OpenBSDTargetInfo<X86_32TargetInfo> {
4807330f729Sjoerg public:
OpenBSDI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4817330f729Sjoerg   OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4827330f729Sjoerg       : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
4837330f729Sjoerg     SizeType = UnsignedLong;
4847330f729Sjoerg     IntPtrType = SignedLong;
4857330f729Sjoerg     PtrDiffType = SignedLong;
4867330f729Sjoerg   }
4877330f729Sjoerg };
4887330f729Sjoerg 
4897330f729Sjoerg class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
4907330f729Sjoerg     : public DarwinTargetInfo<X86_32TargetInfo> {
4917330f729Sjoerg public:
DarwinI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4927330f729Sjoerg   DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4937330f729Sjoerg       : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
4947330f729Sjoerg     LongDoubleWidth = 128;
4957330f729Sjoerg     LongDoubleAlign = 128;
4967330f729Sjoerg     SuitableAlign = 128;
4977330f729Sjoerg     MaxVectorAlign = 256;
4987330f729Sjoerg     // The watchOS simulator uses the builtin bool type for Objective-C.
4997330f729Sjoerg     llvm::Triple T = llvm::Triple(Triple);
5007330f729Sjoerg     if (T.isWatchOS())
5017330f729Sjoerg       UseSignedCharForObjCBool = false;
5027330f729Sjoerg     SizeType = UnsignedLong;
5037330f729Sjoerg     IntPtrType = SignedLong;
5047330f729Sjoerg     resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
505*e038c9c4Sjoerg                     "f80:128-n8:16:32-S128", "_");
5067330f729Sjoerg     HasAlignMac68kSupport = true;
5077330f729Sjoerg   }
5087330f729Sjoerg 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)5097330f729Sjoerg   bool handleTargetFeatures(std::vector<std::string> &Features,
5107330f729Sjoerg                             DiagnosticsEngine &Diags) override {
5117330f729Sjoerg     if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
5127330f729Sjoerg                                                                   Diags))
5137330f729Sjoerg       return false;
5147330f729Sjoerg     // We now know the features we have: we can decide how to align vectors.
5157330f729Sjoerg     MaxVectorAlign =
5167330f729Sjoerg         hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
5177330f729Sjoerg     return true;
5187330f729Sjoerg   }
5197330f729Sjoerg };
5207330f729Sjoerg 
5217330f729Sjoerg // x86-32 Windows target
5227330f729Sjoerg class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
5237330f729Sjoerg     : public WindowsTargetInfo<X86_32TargetInfo> {
5247330f729Sjoerg public:
WindowsX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5257330f729Sjoerg   WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5267330f729Sjoerg       : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
5277330f729Sjoerg     DoubleAlign = LongLongAlign = 64;
5287330f729Sjoerg     bool IsWinCOFF =
5297330f729Sjoerg         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
5307330f729Sjoerg     resetDataLayout(IsWinCOFF ? "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:"
5317330f729Sjoerg                                 "64-i64:64-f80:32-n8:16:32-a:0:32-S32"
5327330f729Sjoerg                               : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:"
533*e038c9c4Sjoerg                                 "64-i64:64-f80:32-n8:16:32-a:0:32-S32",
534*e038c9c4Sjoerg                     IsWinCOFF ? "_" : "");
5357330f729Sjoerg   }
5367330f729Sjoerg };
5377330f729Sjoerg 
5387330f729Sjoerg // x86-32 Windows Visual Studio target
5397330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
5407330f729Sjoerg     : public WindowsX86_32TargetInfo {
5417330f729Sjoerg public:
MicrosoftX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5427330f729Sjoerg   MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
5437330f729Sjoerg                             const TargetOptions &Opts)
5447330f729Sjoerg       : WindowsX86_32TargetInfo(Triple, Opts) {
5457330f729Sjoerg     LongDoubleWidth = LongDoubleAlign = 64;
5467330f729Sjoerg     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
5477330f729Sjoerg   }
5487330f729Sjoerg 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)5497330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
5507330f729Sjoerg                         MacroBuilder &Builder) const override {
5517330f729Sjoerg     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
5527330f729Sjoerg     // The value of the following reflects processor type.
5537330f729Sjoerg     // 300=386, 400=486, 500=Pentium, 600=Blend (default)
5547330f729Sjoerg     // We lost the original triple, so we use the default.
5557330f729Sjoerg     Builder.defineMacro("_M_IX86", "600");
5567330f729Sjoerg   }
5577330f729Sjoerg };
5587330f729Sjoerg 
5597330f729Sjoerg // x86-32 MinGW target
5607330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
5617330f729Sjoerg     : public WindowsX86_32TargetInfo {
5627330f729Sjoerg public:
MinGWX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5637330f729Sjoerg   MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5647330f729Sjoerg       : WindowsX86_32TargetInfo(Triple, Opts) {
5657330f729Sjoerg     HasFloat128 = true;
5667330f729Sjoerg   }
5677330f729Sjoerg 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)5687330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
5697330f729Sjoerg                         MacroBuilder &Builder) const override {
5707330f729Sjoerg     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
5717330f729Sjoerg     Builder.defineMacro("_X86_");
5727330f729Sjoerg   }
5737330f729Sjoerg };
5747330f729Sjoerg 
5757330f729Sjoerg // x86-32 Cygwin target
5767330f729Sjoerg class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {
5777330f729Sjoerg public:
CygwinX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5787330f729Sjoerg   CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5797330f729Sjoerg       : X86_32TargetInfo(Triple, Opts) {
5807330f729Sjoerg     this->WCharType = TargetInfo::UnsignedShort;
5817330f729Sjoerg     DoubleAlign = LongLongAlign = 64;
5827330f729Sjoerg     resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:"
583*e038c9c4Sjoerg                     "32-n8:16:32-a:0:32-S32",
584*e038c9c4Sjoerg                     "_");
5857330f729Sjoerg   }
5867330f729Sjoerg 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)5877330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
5887330f729Sjoerg                         MacroBuilder &Builder) const override {
5897330f729Sjoerg     X86_32TargetInfo::getTargetDefines(Opts, Builder);
5907330f729Sjoerg     Builder.defineMacro("_X86_");
5917330f729Sjoerg     Builder.defineMacro("__CYGWIN__");
5927330f729Sjoerg     Builder.defineMacro("__CYGWIN32__");
5937330f729Sjoerg     addCygMingDefines(Opts, Builder);
5947330f729Sjoerg     DefineStd(Builder, "unix", Opts);
5957330f729Sjoerg     if (Opts.CPlusPlus)
5967330f729Sjoerg       Builder.defineMacro("_GNU_SOURCE");
5977330f729Sjoerg   }
5987330f729Sjoerg };
5997330f729Sjoerg 
6007330f729Sjoerg // x86-32 Haiku target
6017330f729Sjoerg class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
6027330f729Sjoerg     : public HaikuTargetInfo<X86_32TargetInfo> {
6037330f729Sjoerg public:
HaikuX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6047330f729Sjoerg   HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6057330f729Sjoerg       : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
6067330f729Sjoerg 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)6077330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
6087330f729Sjoerg                         MacroBuilder &Builder) const override {
6097330f729Sjoerg     HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
6107330f729Sjoerg     Builder.defineMacro("__INTEL__");
6117330f729Sjoerg   }
6127330f729Sjoerg };
6137330f729Sjoerg 
6147330f729Sjoerg // X86-32 MCU target
6157330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {
6167330f729Sjoerg public:
MCUX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6177330f729Sjoerg   MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6187330f729Sjoerg       : X86_32TargetInfo(Triple, Opts) {
6197330f729Sjoerg     LongDoubleWidth = 64;
6207330f729Sjoerg     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
6217330f729Sjoerg     resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:"
6227330f729Sjoerg                     "32-f128:32-n8:16:32-a:0:32-S32");
6237330f729Sjoerg     WIntType = UnsignedInt;
6247330f729Sjoerg   }
6257330f729Sjoerg 
checkCallingConvention(CallingConv CC)6267330f729Sjoerg   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
6277330f729Sjoerg     // On MCU we support only C calling convention.
6287330f729Sjoerg     return CC == CC_C ? CCCR_OK : CCCR_Warning;
6297330f729Sjoerg   }
6307330f729Sjoerg 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)6317330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
6327330f729Sjoerg                         MacroBuilder &Builder) const override {
6337330f729Sjoerg     X86_32TargetInfo::getTargetDefines(Opts, Builder);
6347330f729Sjoerg     Builder.defineMacro("__iamcu");
6357330f729Sjoerg     Builder.defineMacro("__iamcu__");
6367330f729Sjoerg   }
6377330f729Sjoerg 
allowsLargerPreferedTypeAlignment()6387330f729Sjoerg   bool allowsLargerPreferedTypeAlignment() const override { return false; }
6397330f729Sjoerg };
6407330f729Sjoerg 
6417330f729Sjoerg // x86-32 RTEMS target
6427330f729Sjoerg class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {
6437330f729Sjoerg public:
RTEMSX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6447330f729Sjoerg   RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6457330f729Sjoerg       : X86_32TargetInfo(Triple, Opts) {
6467330f729Sjoerg     SizeType = UnsignedLong;
6477330f729Sjoerg     IntPtrType = SignedLong;
6487330f729Sjoerg     PtrDiffType = SignedLong;
6497330f729Sjoerg   }
6507330f729Sjoerg 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)6517330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
6527330f729Sjoerg                         MacroBuilder &Builder) const override {
6537330f729Sjoerg     X86_32TargetInfo::getTargetDefines(Opts, Builder);
6547330f729Sjoerg     Builder.defineMacro("__INTEL__");
6557330f729Sjoerg     Builder.defineMacro("__rtems__");
6567330f729Sjoerg   }
6577330f729Sjoerg };
6587330f729Sjoerg 
6597330f729Sjoerg // x86-64 generic target
6607330f729Sjoerg class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
6617330f729Sjoerg public:
X86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6627330f729Sjoerg   X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6637330f729Sjoerg       : X86TargetInfo(Triple, Opts) {
6647330f729Sjoerg     const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32;
6657330f729Sjoerg     bool IsWinCOFF =
6667330f729Sjoerg         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
6677330f729Sjoerg     LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
6687330f729Sjoerg     LongDoubleWidth = 128;
6697330f729Sjoerg     LongDoubleAlign = 128;
6707330f729Sjoerg     LargeArrayMinWidth = 128;
6717330f729Sjoerg     LargeArrayAlign = 128;
6727330f729Sjoerg     SuitableAlign = 128;
6737330f729Sjoerg     SizeType = IsX32 ? UnsignedInt : UnsignedLong;
6747330f729Sjoerg     PtrDiffType = IsX32 ? SignedInt : SignedLong;
6757330f729Sjoerg     IntPtrType = IsX32 ? SignedInt : SignedLong;
6767330f729Sjoerg     IntMaxType = IsX32 ? SignedLongLong : SignedLong;
6777330f729Sjoerg     Int64Type = IsX32 ? SignedLongLong : SignedLong;
6787330f729Sjoerg     RegParmMax = 6;
6797330f729Sjoerg 
6807330f729Sjoerg     // Pointers are 32-bit in x32.
6817330f729Sjoerg     resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
6827330f729Sjoerg                             "i64:64-f80:128-n8:16:32:64-S128"
6837330f729Sjoerg                           : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:"
6847330f729Sjoerg                                         "64-i64:64-f80:128-n8:16:32:64-S128"
6857330f729Sjoerg                                       : "e-m:e-p270:32:32-p271:32:32-p272:64:"
6867330f729Sjoerg                                         "64-i64:64-f80:128-n8:16:32:64-S128");
6877330f729Sjoerg 
6887330f729Sjoerg     // Use fpret only for long double.
6897330f729Sjoerg     RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
6907330f729Sjoerg 
6917330f729Sjoerg     // Use fp2ret for _Complex long double.
6927330f729Sjoerg     ComplexLongDoubleUsesFP2Ret = true;
6937330f729Sjoerg 
6947330f729Sjoerg     // Make __builtin_ms_va_list available.
6957330f729Sjoerg     HasBuiltinMSVaList = true;
6967330f729Sjoerg 
6977330f729Sjoerg     // x86-64 has atomics up to 16 bytes.
6987330f729Sjoerg     MaxAtomicPromoteWidth = 128;
6997330f729Sjoerg     MaxAtomicInlineWidth = 64;
7007330f729Sjoerg   }
7017330f729Sjoerg 
getBuiltinVaListKind()7027330f729Sjoerg   BuiltinVaListKind getBuiltinVaListKind() const override {
7037330f729Sjoerg     return TargetInfo::X86_64ABIBuiltinVaList;
7047330f729Sjoerg   }
7057330f729Sjoerg 
getEHDataRegisterNumber(unsigned RegNo)7067330f729Sjoerg   int getEHDataRegisterNumber(unsigned RegNo) const override {
7077330f729Sjoerg     if (RegNo == 0)
7087330f729Sjoerg       return 0;
7097330f729Sjoerg     if (RegNo == 1)
7107330f729Sjoerg       return 1;
7117330f729Sjoerg     return -1;
7127330f729Sjoerg   }
7137330f729Sjoerg 
checkCallingConvention(CallingConv CC)7147330f729Sjoerg   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
7157330f729Sjoerg     switch (CC) {
7167330f729Sjoerg     case CC_C:
7177330f729Sjoerg     case CC_Swift:
7187330f729Sjoerg     case CC_X86VectorCall:
7197330f729Sjoerg     case CC_IntelOclBicc:
7207330f729Sjoerg     case CC_Win64:
7217330f729Sjoerg     case CC_PreserveMost:
7227330f729Sjoerg     case CC_PreserveAll:
7237330f729Sjoerg     case CC_X86RegCall:
7247330f729Sjoerg     case CC_OpenCLKernel:
7257330f729Sjoerg       return CCCR_OK;
7267330f729Sjoerg     default:
7277330f729Sjoerg       return CCCR_Warning;
7287330f729Sjoerg     }
7297330f729Sjoerg   }
7307330f729Sjoerg 
getDefaultCallingConv()7317330f729Sjoerg   CallingConv getDefaultCallingConv() const override {
7327330f729Sjoerg     return CC_C;
7337330f729Sjoerg   }
7347330f729Sjoerg 
7357330f729Sjoerg   // for x32 we need it here explicitly
hasInt128Type()7367330f729Sjoerg   bool hasInt128Type() const override { return true; }
7377330f729Sjoerg 
getUnwindWordWidth()7387330f729Sjoerg   unsigned getUnwindWordWidth() const override { return 64; }
7397330f729Sjoerg 
getRegisterWidth()7407330f729Sjoerg   unsigned getRegisterWidth() const override { return 64; }
7417330f729Sjoerg 
validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch)7427330f729Sjoerg   bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
7437330f729Sjoerg                                       bool &HasSizeMismatch) const override {
7447330f729Sjoerg     // rsp and rbp are the only 64-bit registers the x86 backend can currently
7457330f729Sjoerg     // handle.
7467330f729Sjoerg     if (RegName.equals("rsp") || RegName.equals("rbp")) {
7477330f729Sjoerg       // Check that the register size is 64-bit.
7487330f729Sjoerg       HasSizeMismatch = RegSize != 64;
7497330f729Sjoerg       return true;
7507330f729Sjoerg     }
7517330f729Sjoerg 
7527330f729Sjoerg     // Check if the register is a 32-bit register the backend can handle.
7537330f729Sjoerg     return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
7547330f729Sjoerg                                                          HasSizeMismatch);
7557330f729Sjoerg   }
7567330f729Sjoerg 
setMaxAtomicWidth()7577330f729Sjoerg   void setMaxAtomicWidth() override {
7587330f729Sjoerg     if (hasFeature("cx16"))
7597330f729Sjoerg       MaxAtomicInlineWidth = 128;
7607330f729Sjoerg   }
7617330f729Sjoerg 
7627330f729Sjoerg   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
763*e038c9c4Sjoerg 
hasExtIntType()764*e038c9c4Sjoerg   bool hasExtIntType() const override { return true; }
7657330f729Sjoerg };
7667330f729Sjoerg 
7677330f729Sjoerg // x86-64 Windows target
7687330f729Sjoerg class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
7697330f729Sjoerg     : public WindowsTargetInfo<X86_64TargetInfo> {
7707330f729Sjoerg public:
WindowsX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)7717330f729Sjoerg   WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
7727330f729Sjoerg       : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
7737330f729Sjoerg     LongWidth = LongAlign = 32;
7747330f729Sjoerg     DoubleAlign = LongLongAlign = 64;
7757330f729Sjoerg     IntMaxType = SignedLongLong;
7767330f729Sjoerg     Int64Type = SignedLongLong;
7777330f729Sjoerg     SizeType = UnsignedLongLong;
7787330f729Sjoerg     PtrDiffType = SignedLongLong;
7797330f729Sjoerg     IntPtrType = SignedLongLong;
7807330f729Sjoerg   }
7817330f729Sjoerg 
getBuiltinVaListKind()7827330f729Sjoerg   BuiltinVaListKind getBuiltinVaListKind() const override {
7837330f729Sjoerg     return TargetInfo::CharPtrBuiltinVaList;
7847330f729Sjoerg   }
7857330f729Sjoerg 
checkCallingConvention(CallingConv CC)7867330f729Sjoerg   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
7877330f729Sjoerg     switch (CC) {
7887330f729Sjoerg     case CC_X86StdCall:
7897330f729Sjoerg     case CC_X86ThisCall:
7907330f729Sjoerg     case CC_X86FastCall:
7917330f729Sjoerg       return CCCR_Ignore;
7927330f729Sjoerg     case CC_C:
7937330f729Sjoerg     case CC_X86VectorCall:
7947330f729Sjoerg     case CC_IntelOclBicc:
7957330f729Sjoerg     case CC_PreserveMost:
7967330f729Sjoerg     case CC_PreserveAll:
7977330f729Sjoerg     case CC_X86_64SysV:
7987330f729Sjoerg     case CC_Swift:
7997330f729Sjoerg     case CC_X86RegCall:
8007330f729Sjoerg     case CC_OpenCLKernel:
8017330f729Sjoerg       return CCCR_OK;
8027330f729Sjoerg     default:
8037330f729Sjoerg       return CCCR_Warning;
8047330f729Sjoerg     }
8057330f729Sjoerg   }
8067330f729Sjoerg };
8077330f729Sjoerg 
8087330f729Sjoerg // x86-64 Windows Visual Studio target
8097330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
8107330f729Sjoerg     : public WindowsX86_64TargetInfo {
8117330f729Sjoerg public:
MicrosoftX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8127330f729Sjoerg   MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
8137330f729Sjoerg                             const TargetOptions &Opts)
8147330f729Sjoerg       : WindowsX86_64TargetInfo(Triple, Opts) {
8157330f729Sjoerg     LongDoubleWidth = LongDoubleAlign = 64;
8167330f729Sjoerg     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
8177330f729Sjoerg   }
8187330f729Sjoerg 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)8197330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
8207330f729Sjoerg                         MacroBuilder &Builder) const override {
8217330f729Sjoerg     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
8227330f729Sjoerg     Builder.defineMacro("_M_X64", "100");
8237330f729Sjoerg     Builder.defineMacro("_M_AMD64", "100");
8247330f729Sjoerg   }
8257330f729Sjoerg 
8267330f729Sjoerg   TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4)8277330f729Sjoerg   getCallingConvKind(bool ClangABICompat4) const override {
8287330f729Sjoerg     return CCK_MicrosoftWin64;
8297330f729Sjoerg   }
8307330f729Sjoerg };
8317330f729Sjoerg 
8327330f729Sjoerg // x86-64 MinGW target
8337330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
8347330f729Sjoerg     : public WindowsX86_64TargetInfo {
8357330f729Sjoerg public:
MinGWX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8367330f729Sjoerg   MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
8377330f729Sjoerg       : WindowsX86_64TargetInfo(Triple, Opts) {
8387330f729Sjoerg     // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
8397330f729Sjoerg     // with x86 FP ops. Weird.
8407330f729Sjoerg     LongDoubleWidth = LongDoubleAlign = 128;
8417330f729Sjoerg     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
8427330f729Sjoerg     HasFloat128 = true;
8437330f729Sjoerg   }
8447330f729Sjoerg };
8457330f729Sjoerg 
8467330f729Sjoerg // x86-64 Cygwin target
8477330f729Sjoerg class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {
8487330f729Sjoerg public:
CygwinX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8497330f729Sjoerg   CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
8507330f729Sjoerg       : X86_64TargetInfo(Triple, Opts) {
8517330f729Sjoerg     this->WCharType = TargetInfo::UnsignedShort;
8527330f729Sjoerg     TLSSupported = false;
8537330f729Sjoerg   }
8547330f729Sjoerg 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)8557330f729Sjoerg   void getTargetDefines(const LangOptions &Opts,
8567330f729Sjoerg                         MacroBuilder &Builder) const override {
8577330f729Sjoerg     X86_64TargetInfo::getTargetDefines(Opts, Builder);
8587330f729Sjoerg     Builder.defineMacro("__x86_64__");
8597330f729Sjoerg     Builder.defineMacro("__CYGWIN__");
8607330f729Sjoerg     Builder.defineMacro("__CYGWIN64__");
8617330f729Sjoerg     addCygMingDefines(Opts, Builder);
8627330f729Sjoerg     DefineStd(Builder, "unix", Opts);
8637330f729Sjoerg     if (Opts.CPlusPlus)
8647330f729Sjoerg       Builder.defineMacro("_GNU_SOURCE");
8657330f729Sjoerg   }
8667330f729Sjoerg };
8677330f729Sjoerg 
8687330f729Sjoerg class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
8697330f729Sjoerg     : public DarwinTargetInfo<X86_64TargetInfo> {
8707330f729Sjoerg public:
DarwinX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8717330f729Sjoerg   DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
8727330f729Sjoerg       : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
8737330f729Sjoerg     Int64Type = SignedLongLong;
8747330f729Sjoerg     // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
8757330f729Sjoerg     llvm::Triple T = llvm::Triple(Triple);
8767330f729Sjoerg     if (T.isiOS())
8777330f729Sjoerg       UseSignedCharForObjCBool = false;
8787330f729Sjoerg     resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:"
879*e038c9c4Sjoerg                     "16:32:64-S128", "_");
8807330f729Sjoerg   }
8817330f729Sjoerg 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)8827330f729Sjoerg   bool handleTargetFeatures(std::vector<std::string> &Features,
8837330f729Sjoerg                             DiagnosticsEngine &Diags) override {
8847330f729Sjoerg     if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
8857330f729Sjoerg                                                                   Diags))
8867330f729Sjoerg       return false;
8877330f729Sjoerg     // We now know the features we have: we can decide how to align vectors.
8887330f729Sjoerg     MaxVectorAlign =
8897330f729Sjoerg         hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
8907330f729Sjoerg     return true;
8917330f729Sjoerg   }
8927330f729Sjoerg };
8937330f729Sjoerg 
8947330f729Sjoerg class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
8957330f729Sjoerg     : public OpenBSDTargetInfo<X86_64TargetInfo> {
8967330f729Sjoerg public:
OpenBSDX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8977330f729Sjoerg   OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
8987330f729Sjoerg       : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
8997330f729Sjoerg     IntMaxType = SignedLongLong;
9007330f729Sjoerg     Int64Type = SignedLongLong;
9017330f729Sjoerg   }
9027330f729Sjoerg };
9037330f729Sjoerg 
9047330f729Sjoerg // x86_32 Android target
9057330f729Sjoerg class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
9067330f729Sjoerg     : public LinuxTargetInfo<X86_32TargetInfo> {
9077330f729Sjoerg public:
AndroidX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)9087330f729Sjoerg   AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
9097330f729Sjoerg       : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
9107330f729Sjoerg     SuitableAlign = 32;
9117330f729Sjoerg     LongDoubleWidth = 64;
9127330f729Sjoerg     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
9137330f729Sjoerg   }
9147330f729Sjoerg };
9157330f729Sjoerg 
9167330f729Sjoerg // x86_64 Android target
9177330f729Sjoerg class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
9187330f729Sjoerg     : public LinuxTargetInfo<X86_64TargetInfo> {
9197330f729Sjoerg public:
AndroidX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)9207330f729Sjoerg   AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
9217330f729Sjoerg       : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
9227330f729Sjoerg     LongDoubleFormat = &llvm::APFloat::IEEEquad();
9237330f729Sjoerg   }
9247330f729Sjoerg };
9257330f729Sjoerg } // namespace targets
9267330f729Sjoerg } // namespace clang
9277330f729Sjoerg #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
928