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