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