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