xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Targets/X86.h (revision 7a9b00ce7716f522d49aa36666c74a71cd12203a)
1e5dd7070Spatrick //===--- X86.h - Declare X86 target feature support -------------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file declares X86 TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
14e5dd7070Spatrick #define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
15e5dd7070Spatrick 
16e5dd7070Spatrick #include "OSTargets.h"
17*7a9b00ceSrobert #include "clang/Basic/BitmaskEnum.h"
18e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
19e5dd7070Spatrick #include "clang/Basic/TargetOptions.h"
20e5dd7070Spatrick #include "llvm/ADT/Triple.h"
21e5dd7070Spatrick #include "llvm/Support/Compiler.h"
22adae0cfdSpatrick #include "llvm/Support/X86TargetParser.h"
23*7a9b00ceSrobert #include <optional>
24e5dd7070Spatrick 
25e5dd7070Spatrick namespace clang {
26e5dd7070Spatrick namespace targets {
27e5dd7070Spatrick 
28e5dd7070Spatrick static const unsigned X86AddrSpaceMap[] = {
29e5dd7070Spatrick     0,   // Default
30e5dd7070Spatrick     0,   // opencl_global
31e5dd7070Spatrick     0,   // opencl_local
32e5dd7070Spatrick     0,   // opencl_constant
33e5dd7070Spatrick     0,   // opencl_private
34e5dd7070Spatrick     0,   // opencl_generic
35a0747c9fSpatrick     0,   // opencl_global_device
36a0747c9fSpatrick     0,   // opencl_global_host
37e5dd7070Spatrick     0,   // cuda_device
38e5dd7070Spatrick     0,   // cuda_constant
39e5dd7070Spatrick     0,   // cuda_shared
40a0747c9fSpatrick     0,   // sycl_global
41a0747c9fSpatrick     0,   // sycl_global_device
42a0747c9fSpatrick     0,   // sycl_global_host
43a0747c9fSpatrick     0,   // sycl_local
44a0747c9fSpatrick     0,   // sycl_private
45e5dd7070Spatrick     270, // ptr32_sptr
46e5dd7070Spatrick     271, // ptr32_uptr
47*7a9b00ceSrobert     272, // ptr64
48*7a9b00ceSrobert     0,   // hlsl_groupshared
49e5dd7070Spatrick };
50e5dd7070Spatrick 
51e5dd7070Spatrick // X86 target abstract base class; x86-32 and x86-64 are very close, so
52e5dd7070Spatrick // most of the implementation can be shared.
53e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
54e5dd7070Spatrick 
55e5dd7070Spatrick   enum X86SSEEnum {
56e5dd7070Spatrick     NoSSE,
57e5dd7070Spatrick     SSE1,
58e5dd7070Spatrick     SSE2,
59e5dd7070Spatrick     SSE3,
60e5dd7070Spatrick     SSSE3,
61e5dd7070Spatrick     SSE41,
62e5dd7070Spatrick     SSE42,
63e5dd7070Spatrick     AVX,
64e5dd7070Spatrick     AVX2,
65e5dd7070Spatrick     AVX512F
66e5dd7070Spatrick   } SSELevel = NoSSE;
67e5dd7070Spatrick   enum MMX3DNowEnum {
68e5dd7070Spatrick     NoMMX3DNow,
69e5dd7070Spatrick     MMX,
70e5dd7070Spatrick     AMD3DNow,
71e5dd7070Spatrick     AMD3DNowAthlon
72e5dd7070Spatrick   } MMX3DNowLevel = NoMMX3DNow;
73e5dd7070Spatrick   enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;
74e5dd7070Spatrick   enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
75e5dd7070Spatrick 
76e5dd7070Spatrick   bool HasAES = false;
77e5dd7070Spatrick   bool HasVAES = false;
78e5dd7070Spatrick   bool HasPCLMUL = false;
79e5dd7070Spatrick   bool HasVPCLMULQDQ = false;
80e5dd7070Spatrick   bool HasGFNI = false;
81e5dd7070Spatrick   bool HasLZCNT = false;
82e5dd7070Spatrick   bool HasRDRND = false;
83e5dd7070Spatrick   bool HasFSGSBASE = false;
84e5dd7070Spatrick   bool HasBMI = false;
85e5dd7070Spatrick   bool HasBMI2 = false;
86e5dd7070Spatrick   bool HasPOPCNT = false;
87e5dd7070Spatrick   bool HasRTM = false;
88e5dd7070Spatrick   bool HasPRFCHW = false;
89e5dd7070Spatrick   bool HasRDSEED = false;
90e5dd7070Spatrick   bool HasADX = false;
91e5dd7070Spatrick   bool HasTBM = false;
92e5dd7070Spatrick   bool HasLWP = false;
93e5dd7070Spatrick   bool HasFMA = false;
94e5dd7070Spatrick   bool HasF16C = false;
95e5dd7070Spatrick   bool HasAVX512CD = false;
96e5dd7070Spatrick   bool HasAVX512VPOPCNTDQ = false;
97e5dd7070Spatrick   bool HasAVX512VNNI = false;
98*7a9b00ceSrobert   bool HasAVX512FP16 = false;
99e5dd7070Spatrick   bool HasAVX512BF16 = false;
100e5dd7070Spatrick   bool HasAVX512ER = false;
101e5dd7070Spatrick   bool HasAVX512PF = false;
102e5dd7070Spatrick   bool HasAVX512DQ = false;
103e5dd7070Spatrick   bool HasAVX512BITALG = false;
104e5dd7070Spatrick   bool HasAVX512BW = false;
105e5dd7070Spatrick   bool HasAVX512VL = false;
106e5dd7070Spatrick   bool HasAVX512VBMI = false;
107e5dd7070Spatrick   bool HasAVX512VBMI2 = false;
108*7a9b00ceSrobert   bool HasAVXIFMA = false;
109e5dd7070Spatrick   bool HasAVX512IFMA = false;
110e5dd7070Spatrick   bool HasAVX512VP2INTERSECT = false;
111e5dd7070Spatrick   bool HasSHA = false;
112e5dd7070Spatrick   bool HasSHSTK = false;
113e5dd7070Spatrick   bool HasSGX = false;
114e5dd7070Spatrick   bool HasCX8 = false;
115e5dd7070Spatrick   bool HasCX16 = false;
116e5dd7070Spatrick   bool HasFXSR = false;
117e5dd7070Spatrick   bool HasXSAVE = false;
118e5dd7070Spatrick   bool HasXSAVEOPT = false;
119e5dd7070Spatrick   bool HasXSAVEC = false;
120e5dd7070Spatrick   bool HasXSAVES = false;
121e5dd7070Spatrick   bool HasMWAITX = false;
122e5dd7070Spatrick   bool HasCLZERO = false;
123e5dd7070Spatrick   bool HasCLDEMOTE = false;
124e5dd7070Spatrick   bool HasPCONFIG = false;
125e5dd7070Spatrick   bool HasPKU = false;
126e5dd7070Spatrick   bool HasCLFLUSHOPT = false;
127e5dd7070Spatrick   bool HasCLWB = false;
128e5dd7070Spatrick   bool HasMOVBE = false;
129*7a9b00ceSrobert   bool HasPREFETCHI = false;
130e5dd7070Spatrick   bool HasPREFETCHWT1 = false;
131e5dd7070Spatrick   bool HasRDPID = false;
132*7a9b00ceSrobert   bool HasRDPRU = false;
133e5dd7070Spatrick   bool HasRetpolineExternalThunk = false;
134e5dd7070Spatrick   bool HasLAHFSAHF = false;
135e5dd7070Spatrick   bool HasWBNOINVD = false;
136e5dd7070Spatrick   bool HasWAITPKG = false;
137e5dd7070Spatrick   bool HasMOVDIRI = false;
138e5dd7070Spatrick   bool HasMOVDIR64B = false;
139e5dd7070Spatrick   bool HasPTWRITE = false;
140e5dd7070Spatrick   bool HasINVPCID = false;
141e5dd7070Spatrick   bool HasSaveArgs = false;
142e5dd7070Spatrick   bool HasENQCMD = false;
143*7a9b00ceSrobert   bool HasAMXFP16 = false;
144*7a9b00ceSrobert   bool HasCMPCCXADD = false;
145*7a9b00ceSrobert   bool HasRAOINT = false;
146*7a9b00ceSrobert   bool HasAVXVNNIINT8 = false;
147*7a9b00ceSrobert   bool HasAVXNECONVERT = false;
148a0747c9fSpatrick   bool HasKL = false;      // For key locker
149a0747c9fSpatrick   bool HasWIDEKL = false; // For wide key locker
150a0747c9fSpatrick   bool HasHRESET = false;
151a0747c9fSpatrick   bool HasAVXVNNI = false;
152adae0cfdSpatrick   bool HasAMXTILE = false;
153adae0cfdSpatrick   bool HasAMXINT8 = false;
154adae0cfdSpatrick   bool HasAMXBF16 = false;
155adae0cfdSpatrick   bool HasSERIALIZE = false;
156adae0cfdSpatrick   bool HasTSXLDTRK = false;
157a0747c9fSpatrick   bool HasUINTR = false;
158*7a9b00ceSrobert   bool HasCRC32 = false;
159*7a9b00ceSrobert   bool HasX87 = false;
160e5dd7070Spatrick 
161e5dd7070Spatrick protected:
162adae0cfdSpatrick   llvm::X86::CPUKind CPU = llvm::X86::CK_None;
163e5dd7070Spatrick 
164e5dd7070Spatrick   enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
165e5dd7070Spatrick 
166e5dd7070Spatrick public:
X86TargetInfo(const llvm::Triple & Triple,const TargetOptions &)167e5dd7070Spatrick   X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
168e5dd7070Spatrick       : TargetInfo(Triple) {
169*7a9b00ceSrobert     BFloat16Width = BFloat16Align = 16;
170*7a9b00ceSrobert     BFloat16Format = &llvm::APFloat::BFloat();
171e5dd7070Spatrick     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
172e5dd7070Spatrick     AddrSpaceMap = &X86AddrSpaceMap;
173c090f204Sgkoehler     HasStrictFP = true;
174a0747c9fSpatrick 
175a0747c9fSpatrick     bool IsWinCOFF =
176a0747c9fSpatrick         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
177a0747c9fSpatrick     if (IsWinCOFF)
178a0747c9fSpatrick       MaxVectorAlign = MaxTLSAlign = 8192u * getCharWidth();
179e5dd7070Spatrick   }
180e5dd7070Spatrick 
getLongDoubleMangling()181e5dd7070Spatrick   const char *getLongDoubleMangling() const override {
182e5dd7070Spatrick     return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
183e5dd7070Spatrick   }
184e5dd7070Spatrick 
getFPEvalMethod()185*7a9b00ceSrobert   LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
186e5dd7070Spatrick     // X87 evaluates with 80 bits "long double" precision.
187*7a9b00ceSrobert     return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended
188*7a9b00ceSrobert                              : LangOptions::FPEvalMethodKind::FEM_Source;
189e5dd7070Spatrick   }
190e5dd7070Spatrick 
191*7a9b00ceSrobert   // EvalMethod `source` is not supported for targets with `NoSSE` feature.
supportSourceEvalMethod()192*7a9b00ceSrobert   bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; }
193*7a9b00ceSrobert 
194e5dd7070Spatrick   ArrayRef<const char *> getGCCRegNames() const override;
195e5dd7070Spatrick 
getGCCRegAliases()196e5dd7070Spatrick   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
197*7a9b00ceSrobert     return std::nullopt;
198e5dd7070Spatrick   }
199e5dd7070Spatrick 
200e5dd7070Spatrick   ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
201e5dd7070Spatrick 
isSPRegName(StringRef RegName)202adae0cfdSpatrick   bool isSPRegName(StringRef RegName) const override {
203adae0cfdSpatrick     return RegName.equals("esp") || RegName.equals("rsp");
204adae0cfdSpatrick   }
205adae0cfdSpatrick 
206e5dd7070Spatrick   bool validateCpuSupports(StringRef Name) const override;
207e5dd7070Spatrick 
208e5dd7070Spatrick   bool validateCpuIs(StringRef Name) const override;
209e5dd7070Spatrick 
210e5dd7070Spatrick   bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
211e5dd7070Spatrick 
212e5dd7070Spatrick   char CPUSpecificManglingCharacter(StringRef Name) const override;
213e5dd7070Spatrick 
214e5dd7070Spatrick   void getCPUSpecificCPUDispatchFeatures(
215e5dd7070Spatrick       StringRef Name,
216e5dd7070Spatrick       llvm::SmallVectorImpl<StringRef> &Features) const override;
217e5dd7070Spatrick 
218*7a9b00ceSrobert   StringRef getCPUSpecificTuneName(StringRef Name) const override;
219*7a9b00ceSrobert 
220*7a9b00ceSrobert   std::optional<unsigned> getCPUCacheLineSize() const override;
221adae0cfdSpatrick 
222e5dd7070Spatrick   bool validateAsmConstraint(const char *&Name,
223e5dd7070Spatrick                              TargetInfo::ConstraintInfo &info) const override;
224e5dd7070Spatrick 
validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch)225e5dd7070Spatrick   bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
226e5dd7070Spatrick                                       bool &HasSizeMismatch) const override {
227e5dd7070Spatrick     // esp and ebp are the only 32-bit registers the x86 backend can currently
228e5dd7070Spatrick     // handle.
229e5dd7070Spatrick     if (RegName.equals("esp") || RegName.equals("ebp")) {
230e5dd7070Spatrick       // Check that the register size is 32-bit.
231e5dd7070Spatrick       HasSizeMismatch = RegSize != 32;
232e5dd7070Spatrick       return true;
233e5dd7070Spatrick     }
234e5dd7070Spatrick 
235e5dd7070Spatrick     return false;
236e5dd7070Spatrick   }
237e5dd7070Spatrick 
238e5dd7070Spatrick   bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
239e5dd7070Spatrick                           StringRef Constraint, unsigned Size) const override;
240e5dd7070Spatrick 
241e5dd7070Spatrick   bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
242e5dd7070Spatrick                          StringRef Constraint, unsigned Size) const override;
243e5dd7070Spatrick 
244*7a9b00ceSrobert   bool
checkCFProtectionReturnSupported(DiagnosticsEngine & Diags)245e5dd7070Spatrick   checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
246*7a9b00ceSrobert     if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
247e5dd7070Spatrick       return true;
248*7a9b00ceSrobert     return TargetInfo::checkCFProtectionReturnSupported(Diags);
249e5dd7070Spatrick   };
250e5dd7070Spatrick 
251*7a9b00ceSrobert   bool
checkCFProtectionBranchSupported(DiagnosticsEngine & Diags)252e5dd7070Spatrick   checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
253*7a9b00ceSrobert     if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
254e5dd7070Spatrick       return true;
255*7a9b00ceSrobert     return TargetInfo::checkCFProtectionBranchSupported(Diags);
256e5dd7070Spatrick   };
257e5dd7070Spatrick 
258e5dd7070Spatrick   virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
259e5dd7070Spatrick                                    StringRef Constraint, unsigned Size) const;
260e5dd7070Spatrick 
261e5dd7070Spatrick   std::string convertConstraint(const char *&Constraint) const override;
getClobbers()262e5dd7070Spatrick   const char *getClobbers() const override {
263e5dd7070Spatrick     return "~{dirflag},~{fpsr},~{flags}";
264e5dd7070Spatrick   }
265e5dd7070Spatrick 
getConstraintRegister(StringRef Constraint,StringRef Expression)266e5dd7070Spatrick   StringRef getConstraintRegister(StringRef Constraint,
267e5dd7070Spatrick                                   StringRef Expression) const override {
268e5dd7070Spatrick     StringRef::iterator I, E;
269e5dd7070Spatrick     for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
270e5dd7070Spatrick       if (isalpha(*I) || *I == '@')
271e5dd7070Spatrick         break;
272e5dd7070Spatrick     }
273e5dd7070Spatrick     if (I == E)
274e5dd7070Spatrick       return "";
275e5dd7070Spatrick     switch (*I) {
276e5dd7070Spatrick     // For the register constraints, return the matching register name
277e5dd7070Spatrick     case 'a':
278e5dd7070Spatrick       return "ax";
279e5dd7070Spatrick     case 'b':
280e5dd7070Spatrick       return "bx";
281e5dd7070Spatrick     case 'c':
282e5dd7070Spatrick       return "cx";
283e5dd7070Spatrick     case 'd':
284e5dd7070Spatrick       return "dx";
285e5dd7070Spatrick     case 'S':
286e5dd7070Spatrick       return "si";
287e5dd7070Spatrick     case 'D':
288e5dd7070Spatrick       return "di";
289e5dd7070Spatrick     // In case the constraint is 'r' we need to return Expression
290e5dd7070Spatrick     case 'r':
291e5dd7070Spatrick       return Expression;
292e5dd7070Spatrick     // Double letters Y<x> constraints
293e5dd7070Spatrick     case 'Y':
294e5dd7070Spatrick       if ((++I != E) && ((*I == '0') || (*I == 'z')))
295e5dd7070Spatrick         return "xmm0";
296e5dd7070Spatrick       break;
297e5dd7070Spatrick     default:
298e5dd7070Spatrick       break;
299e5dd7070Spatrick     }
300e5dd7070Spatrick     return "";
301e5dd7070Spatrick   }
302e5dd7070Spatrick 
useFP16ConversionIntrinsics()303e5dd7070Spatrick   bool useFP16ConversionIntrinsics() const override {
304e5dd7070Spatrick     return false;
305e5dd7070Spatrick   }
306e5dd7070Spatrick 
307e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
308e5dd7070Spatrick                         MacroBuilder &Builder) const override;
309e5dd7070Spatrick 
310e5dd7070Spatrick   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
311adae0cfdSpatrick                          bool Enabled) const final;
312e5dd7070Spatrick 
313e5dd7070Spatrick   bool
314e5dd7070Spatrick   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
315e5dd7070Spatrick                  StringRef CPU,
316e5dd7070Spatrick                  const std::vector<std::string> &FeaturesVec) const override;
317e5dd7070Spatrick 
318e5dd7070Spatrick   bool isValidFeatureName(StringRef Name) const override;
319e5dd7070Spatrick 
320adae0cfdSpatrick   bool hasFeature(StringRef Feature) const final;
321e5dd7070Spatrick 
322e5dd7070Spatrick   bool handleTargetFeatures(std::vector<std::string> &Features,
323e5dd7070Spatrick                             DiagnosticsEngine &Diags) override;
324e5dd7070Spatrick 
getABI()325e5dd7070Spatrick   StringRef getABI() const override {
326e5dd7070Spatrick     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
327e5dd7070Spatrick       return "avx512";
328e5dd7070Spatrick     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
329e5dd7070Spatrick       return "avx";
330e5dd7070Spatrick     if (getTriple().getArch() == llvm::Triple::x86 &&
331e5dd7070Spatrick         MMX3DNowLevel == NoMMX3DNow)
332e5dd7070Spatrick       return "no-mmx";
333e5dd7070Spatrick     return "";
334e5dd7070Spatrick   }
335e5dd7070Spatrick 
supportsTargetAttributeTune()336a0747c9fSpatrick   bool supportsTargetAttributeTune() const override {
337a0747c9fSpatrick     return true;
338a0747c9fSpatrick   }
339a0747c9fSpatrick 
isValidCPUName(StringRef Name)340e5dd7070Spatrick   bool isValidCPUName(StringRef Name) const override {
341adae0cfdSpatrick     bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
342adae0cfdSpatrick     return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None;
343e5dd7070Spatrick   }
344e5dd7070Spatrick 
isValidTuneCPUName(StringRef Name)345a0747c9fSpatrick   bool isValidTuneCPUName(StringRef Name) const override {
346a0747c9fSpatrick     if (Name == "generic")
347a0747c9fSpatrick       return true;
348a0747c9fSpatrick 
349a0747c9fSpatrick     // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
350a0747c9fSpatrick     // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
351a0747c9fSpatrick     // since mtune was ignored by clang for so long.
352a0747c9fSpatrick     return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None;
353a0747c9fSpatrick   }
354a0747c9fSpatrick 
355e5dd7070Spatrick   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
356a0747c9fSpatrick   void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
357e5dd7070Spatrick 
setCPU(const std::string & Name)358e5dd7070Spatrick   bool setCPU(const std::string &Name) override {
359adae0cfdSpatrick     bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
360adae0cfdSpatrick     CPU = llvm::X86::parseArchX86(Name, Only64Bit);
361adae0cfdSpatrick     return CPU != llvm::X86::CK_None;
362e5dd7070Spatrick   }
363e5dd7070Spatrick 
364e5dd7070Spatrick   unsigned multiVersionSortPriority(StringRef Name) const override;
365e5dd7070Spatrick 
366e5dd7070Spatrick   bool setFPMath(StringRef Name) override;
367e5dd7070Spatrick 
supportsExtendIntArgs()368a0747c9fSpatrick   bool supportsExtendIntArgs() const override {
369a0747c9fSpatrick     return getTriple().getArch() != llvm::Triple::x86;
370a0747c9fSpatrick   }
371a0747c9fSpatrick 
checkCallingConvention(CallingConv CC)372e5dd7070Spatrick   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
373e5dd7070Spatrick     // Most of the non-ARM calling conventions are i386 conventions.
374e5dd7070Spatrick     switch (CC) {
375e5dd7070Spatrick     case CC_X86ThisCall:
376e5dd7070Spatrick     case CC_X86FastCall:
377e5dd7070Spatrick     case CC_X86StdCall:
378e5dd7070Spatrick     case CC_X86VectorCall:
379e5dd7070Spatrick     case CC_X86RegCall:
380e5dd7070Spatrick     case CC_C:
381e5dd7070Spatrick     case CC_PreserveMost:
382e5dd7070Spatrick     case CC_Swift:
383e5dd7070Spatrick     case CC_X86Pascal:
384e5dd7070Spatrick     case CC_IntelOclBicc:
385e5dd7070Spatrick     case CC_OpenCLKernel:
386e5dd7070Spatrick       return CCCR_OK;
387a0747c9fSpatrick     case CC_SwiftAsync:
388a0747c9fSpatrick       return CCCR_Error;
389e5dd7070Spatrick     default:
390e5dd7070Spatrick       return CCCR_Warning;
391e5dd7070Spatrick     }
392e5dd7070Spatrick   }
393e5dd7070Spatrick 
checkArithmeticFenceSupported()394a0747c9fSpatrick   bool checkArithmeticFenceSupported() const override { return true; }
395a0747c9fSpatrick 
getDefaultCallingConv()396e5dd7070Spatrick   CallingConv getDefaultCallingConv() const override {
397e5dd7070Spatrick     return CC_C;
398e5dd7070Spatrick   }
399e5dd7070Spatrick 
hasSjLjLowering()400e5dd7070Spatrick   bool hasSjLjLowering() const override { return true; }
401e5dd7070Spatrick 
setSupportedOpenCLOpts()402a0747c9fSpatrick   void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
403e5dd7070Spatrick 
getPointerWidthV(LangAS AS)404*7a9b00ceSrobert   uint64_t getPointerWidthV(LangAS AS) const override {
405*7a9b00ceSrobert     unsigned TargetAddrSpace = getTargetAddressSpace(AS);
406*7a9b00ceSrobert     if (TargetAddrSpace == ptr32_sptr || TargetAddrSpace == ptr32_uptr)
407e5dd7070Spatrick       return 32;
408*7a9b00ceSrobert     if (TargetAddrSpace == ptr64)
409e5dd7070Spatrick       return 64;
410e5dd7070Spatrick     return PointerWidth;
411e5dd7070Spatrick   }
412e5dd7070Spatrick 
getPointerAlignV(LangAS AddrSpace)413*7a9b00ceSrobert   uint64_t getPointerAlignV(LangAS AddrSpace) const override {
414e5dd7070Spatrick     return getPointerWidthV(AddrSpace);
415e5dd7070Spatrick   }
416*7a9b00ceSrobert 
getBFloat16Mangling()417*7a9b00ceSrobert   const char *getBFloat16Mangling() const override { return "u6__bf16"; };
418e5dd7070Spatrick };
419e5dd7070Spatrick 
420e5dd7070Spatrick // X86-32 generic target
421e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {
422e5dd7070Spatrick public:
X86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)423e5dd7070Spatrick   X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
424e5dd7070Spatrick       : X86TargetInfo(Triple, Opts) {
425e5dd7070Spatrick     DoubleAlign = LongLongAlign = 32;
426e5dd7070Spatrick     LongDoubleWidth = 96;
427e5dd7070Spatrick     LongDoubleAlign = 32;
428e5dd7070Spatrick     SuitableAlign = 128;
429a0747c9fSpatrick     resetDataLayout(
430a0747c9fSpatrick         Triple.isOSBinFormatMachO()
431a0747c9fSpatrick             ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
432a0747c9fSpatrick               "f80:32-n8:16:32-S128"
433a0747c9fSpatrick             : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
434a0747c9fSpatrick               "f80:32-n8:16:32-S128",
435a0747c9fSpatrick         Triple.isOSBinFormatMachO() ? "_" : "");
436e5dd7070Spatrick     SizeType = UnsignedInt;
437e5dd7070Spatrick     PtrDiffType = SignedInt;
438e5dd7070Spatrick     IntPtrType = SignedInt;
439e5dd7070Spatrick     RegParmMax = 3;
440e5dd7070Spatrick 
441e5dd7070Spatrick     // Use fpret for all types.
442*7a9b00ceSrobert     RealTypeUsesObjCFPRetMask =
443*7a9b00ceSrobert         (unsigned)(FloatModeKind::Float | FloatModeKind::Double |
444*7a9b00ceSrobert                    FloatModeKind::LongDouble);
445e5dd7070Spatrick 
446e5dd7070Spatrick     // x86-32 has atomics up to 8 bytes
447e5dd7070Spatrick     MaxAtomicPromoteWidth = 64;
448e5dd7070Spatrick     MaxAtomicInlineWidth = 32;
449e5dd7070Spatrick   }
450e5dd7070Spatrick 
getBuiltinVaListKind()451e5dd7070Spatrick   BuiltinVaListKind getBuiltinVaListKind() const override {
452e5dd7070Spatrick     return TargetInfo::CharPtrBuiltinVaList;
453e5dd7070Spatrick   }
454e5dd7070Spatrick 
getEHDataRegisterNumber(unsigned RegNo)455e5dd7070Spatrick   int getEHDataRegisterNumber(unsigned RegNo) const override {
456e5dd7070Spatrick     if (RegNo == 0)
457e5dd7070Spatrick       return 0;
458e5dd7070Spatrick     if (RegNo == 1)
459e5dd7070Spatrick       return 2;
460e5dd7070Spatrick     return -1;
461e5dd7070Spatrick   }
462e5dd7070Spatrick 
validateOperandSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size)463e5dd7070Spatrick   bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
464e5dd7070Spatrick                            StringRef Constraint, unsigned Size) const override {
465e5dd7070Spatrick     switch (Constraint[0]) {
466e5dd7070Spatrick     default:
467e5dd7070Spatrick       break;
468e5dd7070Spatrick     case 'R':
469e5dd7070Spatrick     case 'q':
470e5dd7070Spatrick     case 'Q':
471e5dd7070Spatrick     case 'a':
472e5dd7070Spatrick     case 'b':
473e5dd7070Spatrick     case 'c':
474e5dd7070Spatrick     case 'd':
475e5dd7070Spatrick     case 'S':
476e5dd7070Spatrick     case 'D':
477e5dd7070Spatrick       return Size <= 32;
478e5dd7070Spatrick     case 'A':
479e5dd7070Spatrick       return Size <= 64;
480e5dd7070Spatrick     }
481e5dd7070Spatrick 
482e5dd7070Spatrick     return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);
483e5dd7070Spatrick   }
484e5dd7070Spatrick 
setMaxAtomicWidth()485e5dd7070Spatrick   void setMaxAtomicWidth() override {
486e5dd7070Spatrick     if (hasFeature("cx8"))
487e5dd7070Spatrick       MaxAtomicInlineWidth = 64;
488e5dd7070Spatrick   }
489e5dd7070Spatrick 
490e5dd7070Spatrick   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
491adae0cfdSpatrick 
hasBitIntType()492*7a9b00ceSrobert   bool hasBitIntType() const override { return true; }
getMaxBitIntWidth()493*7a9b00ceSrobert   size_t getMaxBitIntWidth() const override {
494*7a9b00ceSrobert     return llvm::IntegerType::MAX_INT_BITS;
495*7a9b00ceSrobert   }
496e5dd7070Spatrick };
497e5dd7070Spatrick 
498e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
499e5dd7070Spatrick     : public NetBSDTargetInfo<X86_32TargetInfo> {
500e5dd7070Spatrick public:
NetBSDI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)501e5dd7070Spatrick   NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
502e5dd7070Spatrick       : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
503e5dd7070Spatrick 
getFPEvalMethod()504*7a9b00ceSrobert   LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
505*7a9b00ceSrobert     VersionTuple OsVersion = getTriple().getOSVersion();
506e5dd7070Spatrick     // New NetBSD uses the default rounding mode.
507*7a9b00ceSrobert     if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0)
508*7a9b00ceSrobert       return X86_32TargetInfo::getFPEvalMethod();
509e5dd7070Spatrick     // NetBSD before 6.99.26 defaults to "double" rounding.
510*7a9b00ceSrobert     return LangOptions::FPEvalMethodKind::FEM_Double;
511e5dd7070Spatrick   }
512e5dd7070Spatrick };
513e5dd7070Spatrick 
514e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
515e5dd7070Spatrick     : public OpenBSDTargetInfo<X86_32TargetInfo> {
516e5dd7070Spatrick public:
OpenBSDI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)517e5dd7070Spatrick   OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
518e5dd7070Spatrick       : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
519e5dd7070Spatrick     SizeType = UnsignedLong;
520e5dd7070Spatrick     IntPtrType = SignedLong;
521e5dd7070Spatrick     PtrDiffType = SignedLong;
522e5dd7070Spatrick   }
523e5dd7070Spatrick };
524e5dd7070Spatrick 
525e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
526e5dd7070Spatrick     : public DarwinTargetInfo<X86_32TargetInfo> {
527e5dd7070Spatrick public:
DarwinI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)528e5dd7070Spatrick   DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
529e5dd7070Spatrick       : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
530e5dd7070Spatrick     LongDoubleWidth = 128;
531e5dd7070Spatrick     LongDoubleAlign = 128;
532e5dd7070Spatrick     SuitableAlign = 128;
533e5dd7070Spatrick     MaxVectorAlign = 256;
534e5dd7070Spatrick     // The watchOS simulator uses the builtin bool type for Objective-C.
535e5dd7070Spatrick     llvm::Triple T = llvm::Triple(Triple);
536e5dd7070Spatrick     if (T.isWatchOS())
537e5dd7070Spatrick       UseSignedCharForObjCBool = false;
538e5dd7070Spatrick     SizeType = UnsignedLong;
539e5dd7070Spatrick     IntPtrType = SignedLong;
540e5dd7070Spatrick     resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
541a0747c9fSpatrick                     "f80:128-n8:16:32-S128", "_");
542e5dd7070Spatrick     HasAlignMac68kSupport = true;
543e5dd7070Spatrick   }
544e5dd7070Spatrick 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)545e5dd7070Spatrick   bool handleTargetFeatures(std::vector<std::string> &Features,
546e5dd7070Spatrick                             DiagnosticsEngine &Diags) override {
547e5dd7070Spatrick     if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
548e5dd7070Spatrick                                                                   Diags))
549e5dd7070Spatrick       return false;
550e5dd7070Spatrick     // We now know the features we have: we can decide how to align vectors.
551e5dd7070Spatrick     MaxVectorAlign =
552e5dd7070Spatrick         hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
553e5dd7070Spatrick     return true;
554e5dd7070Spatrick   }
555e5dd7070Spatrick };
556e5dd7070Spatrick 
557e5dd7070Spatrick // x86-32 Windows target
558e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
559e5dd7070Spatrick     : public WindowsTargetInfo<X86_32TargetInfo> {
560e5dd7070Spatrick public:
WindowsX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)561e5dd7070Spatrick   WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
562e5dd7070Spatrick       : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
563e5dd7070Spatrick     DoubleAlign = LongLongAlign = 64;
564e5dd7070Spatrick     bool IsWinCOFF =
565e5dd7070Spatrick         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
566*7a9b00ceSrobert     bool IsMSVC = getTriple().isWindowsMSVCEnvironment();
567*7a9b00ceSrobert     std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e";
568*7a9b00ceSrobert     Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-";
569*7a9b00ceSrobert     Layout += IsMSVC ? "f80:128" : "f80:32";
570*7a9b00ceSrobert     Layout += "-n8:16:32-a:0:32-S32";
571*7a9b00ceSrobert     resetDataLayout(Layout, IsWinCOFF ? "_" : "");
572e5dd7070Spatrick   }
573e5dd7070Spatrick };
574e5dd7070Spatrick 
575e5dd7070Spatrick // x86-32 Windows Visual Studio target
576e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
577e5dd7070Spatrick     : public WindowsX86_32TargetInfo {
578e5dd7070Spatrick public:
MicrosoftX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)579e5dd7070Spatrick   MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
580e5dd7070Spatrick                             const TargetOptions &Opts)
581e5dd7070Spatrick       : WindowsX86_32TargetInfo(Triple, Opts) {
582e5dd7070Spatrick     LongDoubleWidth = LongDoubleAlign = 64;
583e5dd7070Spatrick     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
584e5dd7070Spatrick   }
585e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)586e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
587e5dd7070Spatrick                         MacroBuilder &Builder) const override {
588e5dd7070Spatrick     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
589e5dd7070Spatrick     // The value of the following reflects processor type.
590e5dd7070Spatrick     // 300=386, 400=486, 500=Pentium, 600=Blend (default)
591e5dd7070Spatrick     // We lost the original triple, so we use the default.
592e5dd7070Spatrick     Builder.defineMacro("_M_IX86", "600");
593e5dd7070Spatrick   }
594e5dd7070Spatrick };
595e5dd7070Spatrick 
596e5dd7070Spatrick // x86-32 MinGW target
597e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
598e5dd7070Spatrick     : public WindowsX86_32TargetInfo {
599e5dd7070Spatrick public:
MinGWX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)600e5dd7070Spatrick   MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
601e5dd7070Spatrick       : WindowsX86_32TargetInfo(Triple, Opts) {
602e5dd7070Spatrick     HasFloat128 = true;
603e5dd7070Spatrick   }
604e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)605e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
606e5dd7070Spatrick                         MacroBuilder &Builder) const override {
607e5dd7070Spatrick     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
608e5dd7070Spatrick     Builder.defineMacro("_X86_");
609e5dd7070Spatrick   }
610e5dd7070Spatrick };
611e5dd7070Spatrick 
612e5dd7070Spatrick // x86-32 Cygwin target
613e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {
614e5dd7070Spatrick public:
CygwinX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)615e5dd7070Spatrick   CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
616e5dd7070Spatrick       : X86_32TargetInfo(Triple, Opts) {
617e5dd7070Spatrick     this->WCharType = TargetInfo::UnsignedShort;
618e5dd7070Spatrick     DoubleAlign = LongLongAlign = 64;
619e5dd7070Spatrick     resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:"
620a0747c9fSpatrick                     "32-n8:16:32-a:0:32-S32",
621a0747c9fSpatrick                     "_");
622e5dd7070Spatrick   }
623e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)624e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
625e5dd7070Spatrick                         MacroBuilder &Builder) const override {
626e5dd7070Spatrick     X86_32TargetInfo::getTargetDefines(Opts, Builder);
627e5dd7070Spatrick     Builder.defineMacro("_X86_");
628e5dd7070Spatrick     Builder.defineMacro("__CYGWIN__");
629e5dd7070Spatrick     Builder.defineMacro("__CYGWIN32__");
630e5dd7070Spatrick     addCygMingDefines(Opts, Builder);
631e5dd7070Spatrick     DefineStd(Builder, "unix", Opts);
632e5dd7070Spatrick     if (Opts.CPlusPlus)
633e5dd7070Spatrick       Builder.defineMacro("_GNU_SOURCE");
634e5dd7070Spatrick   }
635e5dd7070Spatrick };
636e5dd7070Spatrick 
637e5dd7070Spatrick // x86-32 Haiku target
638e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
639e5dd7070Spatrick     : public HaikuTargetInfo<X86_32TargetInfo> {
640e5dd7070Spatrick public:
HaikuX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)641e5dd7070Spatrick   HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
642e5dd7070Spatrick       : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
643e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)644e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
645e5dd7070Spatrick                         MacroBuilder &Builder) const override {
646e5dd7070Spatrick     HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
647e5dd7070Spatrick     Builder.defineMacro("__INTEL__");
648e5dd7070Spatrick   }
649e5dd7070Spatrick };
650e5dd7070Spatrick 
651e5dd7070Spatrick // X86-32 MCU target
652e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {
653e5dd7070Spatrick public:
MCUX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)654e5dd7070Spatrick   MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
655e5dd7070Spatrick       : X86_32TargetInfo(Triple, Opts) {
656e5dd7070Spatrick     LongDoubleWidth = 64;
657e5dd7070Spatrick     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
658e5dd7070Spatrick     resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:"
659e5dd7070Spatrick                     "32-f128:32-n8:16:32-a:0:32-S32");
660e5dd7070Spatrick     WIntType = UnsignedInt;
661e5dd7070Spatrick   }
662e5dd7070Spatrick 
checkCallingConvention(CallingConv CC)663e5dd7070Spatrick   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
664e5dd7070Spatrick     // On MCU we support only C calling convention.
665e5dd7070Spatrick     return CC == CC_C ? CCCR_OK : CCCR_Warning;
666e5dd7070Spatrick   }
667e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)668e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
669e5dd7070Spatrick                         MacroBuilder &Builder) const override {
670e5dd7070Spatrick     X86_32TargetInfo::getTargetDefines(Opts, Builder);
671e5dd7070Spatrick     Builder.defineMacro("__iamcu");
672e5dd7070Spatrick     Builder.defineMacro("__iamcu__");
673e5dd7070Spatrick   }
674e5dd7070Spatrick 
allowsLargerPreferedTypeAlignment()675e5dd7070Spatrick   bool allowsLargerPreferedTypeAlignment() const override { return false; }
676e5dd7070Spatrick };
677e5dd7070Spatrick 
678e5dd7070Spatrick // x86-32 RTEMS target
679e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {
680e5dd7070Spatrick public:
RTEMSX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)681e5dd7070Spatrick   RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
682e5dd7070Spatrick       : X86_32TargetInfo(Triple, Opts) {
683e5dd7070Spatrick     SizeType = UnsignedLong;
684e5dd7070Spatrick     IntPtrType = SignedLong;
685e5dd7070Spatrick     PtrDiffType = SignedLong;
686e5dd7070Spatrick   }
687e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)688e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
689e5dd7070Spatrick                         MacroBuilder &Builder) const override {
690e5dd7070Spatrick     X86_32TargetInfo::getTargetDefines(Opts, Builder);
691e5dd7070Spatrick     Builder.defineMacro("__INTEL__");
692e5dd7070Spatrick     Builder.defineMacro("__rtems__");
693e5dd7070Spatrick   }
694e5dd7070Spatrick };
695e5dd7070Spatrick 
696e5dd7070Spatrick // x86-64 generic target
697e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
698e5dd7070Spatrick public:
X86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)699e5dd7070Spatrick   X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
700e5dd7070Spatrick       : X86TargetInfo(Triple, Opts) {
701a0747c9fSpatrick     const bool IsX32 = getTriple().isX32();
702e5dd7070Spatrick     bool IsWinCOFF =
703e5dd7070Spatrick         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
704e5dd7070Spatrick     LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
705e5dd7070Spatrick     LongDoubleWidth = 128;
706e5dd7070Spatrick     LongDoubleAlign = 128;
707e5dd7070Spatrick     LargeArrayMinWidth = 128;
708e5dd7070Spatrick     LargeArrayAlign = 128;
709e5dd7070Spatrick     SuitableAlign = 128;
710e5dd7070Spatrick     SizeType = IsX32 ? UnsignedInt : UnsignedLong;
711e5dd7070Spatrick     PtrDiffType = IsX32 ? SignedInt : SignedLong;
712e5dd7070Spatrick     IntPtrType = IsX32 ? SignedInt : SignedLong;
713e5dd7070Spatrick     IntMaxType = IsX32 ? SignedLongLong : SignedLong;
714e5dd7070Spatrick     Int64Type = IsX32 ? SignedLongLong : SignedLong;
715e5dd7070Spatrick     RegParmMax = 6;
716e5dd7070Spatrick 
717e5dd7070Spatrick     // Pointers are 32-bit in x32.
718e5dd7070Spatrick     resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
719e5dd7070Spatrick                             "i64:64-f80:128-n8:16:32:64-S128"
720e5dd7070Spatrick                           : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:"
721e5dd7070Spatrick                                         "64-i64:64-f80:128-n8:16:32:64-S128"
722e5dd7070Spatrick                                       : "e-m:e-p270:32:32-p271:32:32-p272:64:"
723e5dd7070Spatrick                                         "64-i64:64-f80:128-n8:16:32:64-S128");
724e5dd7070Spatrick 
725e5dd7070Spatrick     // Use fpret only for long double.
726*7a9b00ceSrobert     RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;
727e5dd7070Spatrick 
728e5dd7070Spatrick     // Use fp2ret for _Complex long double.
729e5dd7070Spatrick     ComplexLongDoubleUsesFP2Ret = true;
730e5dd7070Spatrick 
731e5dd7070Spatrick     // Make __builtin_ms_va_list available.
732e5dd7070Spatrick     HasBuiltinMSVaList = true;
733e5dd7070Spatrick 
734e5dd7070Spatrick     // x86-64 has atomics up to 16 bytes.
735e5dd7070Spatrick     MaxAtomicPromoteWidth = 128;
736e5dd7070Spatrick     MaxAtomicInlineWidth = 64;
737e5dd7070Spatrick   }
738e5dd7070Spatrick 
getBuiltinVaListKind()739e5dd7070Spatrick   BuiltinVaListKind getBuiltinVaListKind() const override {
740e5dd7070Spatrick     return TargetInfo::X86_64ABIBuiltinVaList;
741e5dd7070Spatrick   }
742e5dd7070Spatrick 
getEHDataRegisterNumber(unsigned RegNo)743e5dd7070Spatrick   int getEHDataRegisterNumber(unsigned RegNo) const override {
744e5dd7070Spatrick     if (RegNo == 0)
745e5dd7070Spatrick       return 0;
746e5dd7070Spatrick     if (RegNo == 1)
747e5dd7070Spatrick       return 1;
748e5dd7070Spatrick     return -1;
749e5dd7070Spatrick   }
750e5dd7070Spatrick 
checkCallingConvention(CallingConv CC)751e5dd7070Spatrick   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
752e5dd7070Spatrick     switch (CC) {
753e5dd7070Spatrick     case CC_C:
754e5dd7070Spatrick     case CC_Swift:
755a0747c9fSpatrick     case CC_SwiftAsync:
756e5dd7070Spatrick     case CC_X86VectorCall:
757e5dd7070Spatrick     case CC_IntelOclBicc:
758e5dd7070Spatrick     case CC_Win64:
759e5dd7070Spatrick     case CC_PreserveMost:
760e5dd7070Spatrick     case CC_PreserveAll:
761e5dd7070Spatrick     case CC_X86RegCall:
762e5dd7070Spatrick     case CC_OpenCLKernel:
763e5dd7070Spatrick       return CCCR_OK;
764e5dd7070Spatrick     default:
765e5dd7070Spatrick       return CCCR_Warning;
766e5dd7070Spatrick     }
767e5dd7070Spatrick   }
768e5dd7070Spatrick 
getDefaultCallingConv()769e5dd7070Spatrick   CallingConv getDefaultCallingConv() const override {
770e5dd7070Spatrick     return CC_C;
771e5dd7070Spatrick   }
772e5dd7070Spatrick 
773e5dd7070Spatrick   // for x32 we need it here explicitly
hasInt128Type()774e5dd7070Spatrick   bool hasInt128Type() const override { return true; }
775e5dd7070Spatrick 
getUnwindWordWidth()776e5dd7070Spatrick   unsigned getUnwindWordWidth() const override { return 64; }
777e5dd7070Spatrick 
getRegisterWidth()778e5dd7070Spatrick   unsigned getRegisterWidth() const override { return 64; }
779e5dd7070Spatrick 
validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch)780e5dd7070Spatrick   bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
781e5dd7070Spatrick                                       bool &HasSizeMismatch) const override {
782e5dd7070Spatrick     // rsp and rbp are the only 64-bit registers the x86 backend can currently
783e5dd7070Spatrick     // handle.
784e5dd7070Spatrick     if (RegName.equals("rsp") || RegName.equals("rbp")) {
785e5dd7070Spatrick       // Check that the register size is 64-bit.
786e5dd7070Spatrick       HasSizeMismatch = RegSize != 64;
787e5dd7070Spatrick       return true;
788e5dd7070Spatrick     }
789e5dd7070Spatrick 
790e5dd7070Spatrick     // Check if the register is a 32-bit register the backend can handle.
791e5dd7070Spatrick     return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
792e5dd7070Spatrick                                                          HasSizeMismatch);
793e5dd7070Spatrick   }
794e5dd7070Spatrick 
setMaxAtomicWidth()795e5dd7070Spatrick   void setMaxAtomicWidth() override {
796e5dd7070Spatrick     if (hasFeature("cx16"))
797e5dd7070Spatrick       MaxAtomicInlineWidth = 128;
798e5dd7070Spatrick   }
799e5dd7070Spatrick 
800e5dd7070Spatrick   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
801adae0cfdSpatrick 
hasBitIntType()802*7a9b00ceSrobert   bool hasBitIntType() const override { return true; }
getMaxBitIntWidth()803*7a9b00ceSrobert   size_t getMaxBitIntWidth() const override {
804*7a9b00ceSrobert     return llvm::IntegerType::MAX_INT_BITS;
805*7a9b00ceSrobert   }
806e5dd7070Spatrick };
807e5dd7070Spatrick 
808e5dd7070Spatrick // x86-64 Windows target
809e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
810e5dd7070Spatrick     : public WindowsTargetInfo<X86_64TargetInfo> {
811e5dd7070Spatrick public:
WindowsX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)812e5dd7070Spatrick   WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
813e5dd7070Spatrick       : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
814e5dd7070Spatrick     LongWidth = LongAlign = 32;
815e5dd7070Spatrick     DoubleAlign = LongLongAlign = 64;
816e5dd7070Spatrick     IntMaxType = SignedLongLong;
817e5dd7070Spatrick     Int64Type = SignedLongLong;
818e5dd7070Spatrick     SizeType = UnsignedLongLong;
819e5dd7070Spatrick     PtrDiffType = SignedLongLong;
820e5dd7070Spatrick     IntPtrType = SignedLongLong;
821e5dd7070Spatrick   }
822e5dd7070Spatrick 
getBuiltinVaListKind()823e5dd7070Spatrick   BuiltinVaListKind getBuiltinVaListKind() const override {
824e5dd7070Spatrick     return TargetInfo::CharPtrBuiltinVaList;
825e5dd7070Spatrick   }
826e5dd7070Spatrick 
checkCallingConvention(CallingConv CC)827e5dd7070Spatrick   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
828e5dd7070Spatrick     switch (CC) {
829e5dd7070Spatrick     case CC_X86StdCall:
830e5dd7070Spatrick     case CC_X86ThisCall:
831e5dd7070Spatrick     case CC_X86FastCall:
832e5dd7070Spatrick       return CCCR_Ignore;
833e5dd7070Spatrick     case CC_C:
834e5dd7070Spatrick     case CC_X86VectorCall:
835e5dd7070Spatrick     case CC_IntelOclBicc:
836e5dd7070Spatrick     case CC_PreserveMost:
837e5dd7070Spatrick     case CC_PreserveAll:
838e5dd7070Spatrick     case CC_X86_64SysV:
839e5dd7070Spatrick     case CC_Swift:
840a0747c9fSpatrick     case CC_SwiftAsync:
841e5dd7070Spatrick     case CC_X86RegCall:
842e5dd7070Spatrick     case CC_OpenCLKernel:
843e5dd7070Spatrick       return CCCR_OK;
844e5dd7070Spatrick     default:
845e5dd7070Spatrick       return CCCR_Warning;
846e5dd7070Spatrick     }
847e5dd7070Spatrick   }
848e5dd7070Spatrick };
849e5dd7070Spatrick 
850e5dd7070Spatrick // x86-64 Windows Visual Studio target
851e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
852e5dd7070Spatrick     : public WindowsX86_64TargetInfo {
853e5dd7070Spatrick public:
MicrosoftX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)854e5dd7070Spatrick   MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
855e5dd7070Spatrick                             const TargetOptions &Opts)
856e5dd7070Spatrick       : WindowsX86_64TargetInfo(Triple, Opts) {
857e5dd7070Spatrick     LongDoubleWidth = LongDoubleAlign = 64;
858e5dd7070Spatrick     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
859e5dd7070Spatrick   }
860e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)861e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
862e5dd7070Spatrick                         MacroBuilder &Builder) const override {
863e5dd7070Spatrick     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
864e5dd7070Spatrick     Builder.defineMacro("_M_X64", "100");
865e5dd7070Spatrick     Builder.defineMacro("_M_AMD64", "100");
866e5dd7070Spatrick   }
867e5dd7070Spatrick 
868e5dd7070Spatrick   TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4)869e5dd7070Spatrick   getCallingConvKind(bool ClangABICompat4) const override {
870e5dd7070Spatrick     return CCK_MicrosoftWin64;
871e5dd7070Spatrick   }
872e5dd7070Spatrick };
873e5dd7070Spatrick 
874e5dd7070Spatrick // x86-64 MinGW target
875e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
876e5dd7070Spatrick     : public WindowsX86_64TargetInfo {
877e5dd7070Spatrick public:
MinGWX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)878e5dd7070Spatrick   MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
879e5dd7070Spatrick       : WindowsX86_64TargetInfo(Triple, Opts) {
880e5dd7070Spatrick     // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
881e5dd7070Spatrick     // with x86 FP ops. Weird.
882e5dd7070Spatrick     LongDoubleWidth = LongDoubleAlign = 128;
883e5dd7070Spatrick     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
884e5dd7070Spatrick     HasFloat128 = true;
885e5dd7070Spatrick   }
886e5dd7070Spatrick };
887e5dd7070Spatrick 
888e5dd7070Spatrick // x86-64 Cygwin target
889e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {
890e5dd7070Spatrick public:
CygwinX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)891e5dd7070Spatrick   CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
892e5dd7070Spatrick       : X86_64TargetInfo(Triple, Opts) {
893e5dd7070Spatrick     this->WCharType = TargetInfo::UnsignedShort;
894e5dd7070Spatrick     TLSSupported = false;
895e5dd7070Spatrick   }
896e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)897e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
898e5dd7070Spatrick                         MacroBuilder &Builder) const override {
899e5dd7070Spatrick     X86_64TargetInfo::getTargetDefines(Opts, Builder);
900e5dd7070Spatrick     Builder.defineMacro("__x86_64__");
901e5dd7070Spatrick     Builder.defineMacro("__CYGWIN__");
902e5dd7070Spatrick     Builder.defineMacro("__CYGWIN64__");
903e5dd7070Spatrick     addCygMingDefines(Opts, Builder);
904e5dd7070Spatrick     DefineStd(Builder, "unix", Opts);
905e5dd7070Spatrick     if (Opts.CPlusPlus)
906e5dd7070Spatrick       Builder.defineMacro("_GNU_SOURCE");
907e5dd7070Spatrick   }
908e5dd7070Spatrick };
909e5dd7070Spatrick 
910e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
911e5dd7070Spatrick     : public DarwinTargetInfo<X86_64TargetInfo> {
912e5dd7070Spatrick public:
DarwinX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)913e5dd7070Spatrick   DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
914e5dd7070Spatrick       : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
915e5dd7070Spatrick     Int64Type = SignedLongLong;
916e5dd7070Spatrick     // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
917e5dd7070Spatrick     llvm::Triple T = llvm::Triple(Triple);
918e5dd7070Spatrick     if (T.isiOS())
919e5dd7070Spatrick       UseSignedCharForObjCBool = false;
920e5dd7070Spatrick     resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:"
921a0747c9fSpatrick                     "16:32:64-S128", "_");
922e5dd7070Spatrick   }
923e5dd7070Spatrick 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)924e5dd7070Spatrick   bool handleTargetFeatures(std::vector<std::string> &Features,
925e5dd7070Spatrick                             DiagnosticsEngine &Diags) override {
926e5dd7070Spatrick     if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
927e5dd7070Spatrick                                                                   Diags))
928e5dd7070Spatrick       return false;
929e5dd7070Spatrick     // We now know the features we have: we can decide how to align vectors.
930e5dd7070Spatrick     MaxVectorAlign =
931e5dd7070Spatrick         hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
932e5dd7070Spatrick     return true;
933e5dd7070Spatrick   }
934e5dd7070Spatrick };
935e5dd7070Spatrick 
936e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
937e5dd7070Spatrick     : public OpenBSDTargetInfo<X86_64TargetInfo> {
938e5dd7070Spatrick public:
OpenBSDX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)939e5dd7070Spatrick   OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
940e5dd7070Spatrick       : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
941e5dd7070Spatrick     IntMaxType = SignedLongLong;
942e5dd7070Spatrick     Int64Type = SignedLongLong;
943e5dd7070Spatrick   }
944e5dd7070Spatrick };
945e5dd7070Spatrick 
946e5dd7070Spatrick // x86_32 Android target
947e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
948e5dd7070Spatrick     : public LinuxTargetInfo<X86_32TargetInfo> {
949e5dd7070Spatrick public:
AndroidX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)950e5dd7070Spatrick   AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
951e5dd7070Spatrick       : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
952e5dd7070Spatrick     SuitableAlign = 32;
953e5dd7070Spatrick     LongDoubleWidth = 64;
954e5dd7070Spatrick     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
955e5dd7070Spatrick   }
956e5dd7070Spatrick };
957e5dd7070Spatrick 
958e5dd7070Spatrick // x86_64 Android target
959e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
960e5dd7070Spatrick     : public LinuxTargetInfo<X86_64TargetInfo> {
961e5dd7070Spatrick public:
AndroidX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)962e5dd7070Spatrick   AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
963e5dd7070Spatrick       : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
964e5dd7070Spatrick     LongDoubleFormat = &llvm::APFloat::IEEEquad();
965e5dd7070Spatrick   }
966e5dd7070Spatrick };
967e5dd7070Spatrick } // namespace targets
968e5dd7070Spatrick } // namespace clang
969e5dd7070Spatrick #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
970