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