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