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