Clang Project

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