Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Basic/Targets/X86.h
Line
Count
Source (jump to first uncovered line)
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/BitmaskEnum.h"
18
#include "clang/Basic/TargetInfo.h"
19
#include "clang/Basic/TargetOptions.h"
20
#include "llvm/Support/Compiler.h"
21
#include "llvm/TargetParser/Triple.h"
22
#include "llvm/TargetParser/X86TargetParser.h"
23
#include <optional>
24
25
namespace clang {
26
namespace targets {
27
28
static const unsigned X86AddrSpaceMap[] = {
29
    0,   // Default
30
    0,   // opencl_global
31
    0,   // opencl_local
32
    0,   // opencl_constant
33
    0,   // opencl_private
34
    0,   // opencl_generic
35
    0,   // opencl_global_device
36
    0,   // opencl_global_host
37
    0,   // cuda_device
38
    0,   // cuda_constant
39
    0,   // cuda_shared
40
    0,   // sycl_global
41
    0,   // sycl_global_device
42
    0,   // sycl_global_host
43
    0,   // sycl_local
44
    0,   // sycl_private
45
    270, // ptr32_sptr
46
    271, // ptr32_uptr
47
    272, // ptr64
48
    0,   // hlsl_groupshared
49
    // Wasm address space values for this target are dummy values,
50
    // as it is only enabled for Wasm targets.
51
    20, // wasm_funcref
52
};
53
54
// X86 target abstract base class; x86-32 and x86-64 are very close, so
55
// most of the implementation can be shared.
56
class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
57
58
  enum X86SSEEnum {
59
    NoSSE,
60
    SSE1,
61
    SSE2,
62
    SSE3,
63
    SSSE3,
64
    SSE41,
65
    SSE42,
66
    AVX,
67
    AVX2,
68
    AVX512F
69
  } SSELevel = NoSSE;
70
  enum MMX3DNowEnum {
71
    NoMMX3DNow,
72
    MMX,
73
    AMD3DNow,
74
    AMD3DNowAthlon
75
  } MMX3DNowLevel = NoMMX3DNow;
76
  enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;
77
  enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
78
79
  bool HasAES = false;
80
  bool HasVAES = false;
81
  bool HasPCLMUL = false;
82
  bool HasVPCLMULQDQ = false;
83
  bool HasGFNI = false;
84
  bool HasLZCNT = false;
85
  bool HasRDRND = false;
86
  bool HasFSGSBASE = false;
87
  bool HasBMI = false;
88
  bool HasBMI2 = false;
89
  bool HasPOPCNT = false;
90
  bool HasRTM = false;
91
  bool HasPRFCHW = false;
92
  bool HasRDSEED = false;
93
  bool HasADX = false;
94
  bool HasTBM = false;
95
  bool HasLWP = false;
96
  bool HasFMA = false;
97
  bool HasF16C = false;
98
  bool HasAVX10_1 = false;
99
  bool HasAVX10_1_512 = false;
100
  bool HasEVEX512 = false;
101
  bool HasAVX512CD = false;
102
  bool HasAVX512VPOPCNTDQ = false;
103
  bool HasAVX512VNNI = false;
104
  bool HasAVX512FP16 = false;
105
  bool HasAVX512BF16 = false;
106
  bool HasAVX512ER = false;
107
  bool HasAVX512PF = false;
108
  bool HasAVX512DQ = false;
109
  bool HasAVX512BITALG = false;
110
  bool HasAVX512BW = false;
111
  bool HasAVX512VL = false;
112
  bool HasAVX512VBMI = false;
113
  bool HasAVX512VBMI2 = false;
114
  bool HasAVXIFMA = false;
115
  bool HasAVX512IFMA = false;
116
  bool HasAVX512VP2INTERSECT = false;
117
  bool HasSHA = false;
118
  bool HasSHA512 = false;
119
  bool HasSHSTK = false;
120
  bool HasSM3 = false;
121
  bool HasSGX = false;
122
  bool HasSM4 = false;
123
  bool HasCX8 = false;
124
  bool HasCX16 = false;
125
  bool HasFXSR = false;
126
  bool HasXSAVE = false;
127
  bool HasXSAVEOPT = false;
128
  bool HasXSAVEC = false;
129
  bool HasXSAVES = false;
130
  bool HasMWAITX = false;
131
  bool HasCLZERO = false;
132
  bool HasCLDEMOTE = false;
133
  bool HasPCONFIG = false;
134
  bool HasPKU = false;
135
  bool HasCLFLUSHOPT = false;
136
  bool HasCLWB = false;
137
  bool HasMOVBE = false;
138
  bool HasPREFETCHI = false;
139
  bool HasPREFETCHWT1 = false;
140
  bool HasRDPID = false;
141
  bool HasRDPRU = false;
142
  bool HasRetpolineExternalThunk = false;
143
  bool HasLAHFSAHF = false;
144
  bool HasWBNOINVD = false;
145
  bool HasWAITPKG = false;
146
  bool HasMOVDIRI = false;
147
  bool HasMOVDIR64B = false;
148
  bool HasPTWRITE = false;
149
  bool HasINVPCID = false;
150
  bool HasENQCMD = false;
151
  bool HasAVXVNNIINT16 = false;
152
  bool HasAMXFP16 = false;
153
  bool HasCMPCCXADD = false;
154
  bool HasRAOINT = false;
155
  bool HasAVXVNNIINT8 = false;
156
  bool HasAVXNECONVERT = false;
157
  bool HasKL = false;      // For key locker
158
  bool HasWIDEKL = false; // For wide key locker
159
  bool HasHRESET = false;
160
  bool HasAVXVNNI = false;
161
  bool HasAMXTILE = false;
162
  bool HasAMXINT8 = false;
163
  bool HasAMXBF16 = false;
164
  bool HasAMXCOMPLEX = false;
165
  bool HasSERIALIZE = false;
166
  bool HasTSXLDTRK = false;
167
  bool HasUSERMSR = false;
168
  bool HasUINTR = false;
169
  bool HasCRC32 = false;
170
  bool HasX87 = false;
171
  bool HasEGPR = false;
172
  bool HasPush2Pop2 = false;
173
  bool HasPPX = false;
174
  bool HasNDD = false;
175
  bool HasCCMP = false;
176
  bool HasCF = false;
177
178
protected:
179
  llvm::X86::CPUKind CPU = llvm::X86::CK_None;
180
181
  enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
182
183
public:
184
  X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
185
46
      : TargetInfo(Triple) {
186
46
    BFloat16Width = BFloat16Align = 16;
187
46
    BFloat16Format = &llvm::APFloat::BFloat();
188
46
    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
189
46
    AddrSpaceMap = &X86AddrSpaceMap;
190
46
    HasStrictFP = true;
191
192
46
    bool IsWinCOFF =
193
46
        getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
194
46
    if (IsWinCOFF)
195
0
      MaxVectorAlign = MaxTLSAlign = 8192u * getCharWidth();
196
46
  }
197
198
0
  const char *getLongDoubleMangling() const override {
199
0
    return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
200
0
  }
201
202
92
  LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
203
    // X87 evaluates with 80 bits "long double" precision.
204
92
    return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended
205
92
                             : LangOptions::FPEvalMethodKind::FEM_Source;
206
92
  }
207
208
  // EvalMethod `source` is not supported for targets with `NoSSE` feature.
209
1
  bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; }
210
211
  ArrayRef<const char *> getGCCRegNames() const override;
212
213
0
  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
214
0
    return std::nullopt;
215
0
  }
216
217
  ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
218
219
0
  bool isSPRegName(StringRef RegName) const override {
220
0
    return RegName.equals("esp") || RegName.equals("rsp");
221
0
  }
222
223
  bool validateCpuSupports(StringRef FeatureStr) const override;
224
225
  bool validateCpuIs(StringRef FeatureStr) const override;
226
227
  bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
228
229
  char CPUSpecificManglingCharacter(StringRef Name) const override;
230
231
  void getCPUSpecificCPUDispatchFeatures(
232
      StringRef Name,
233
      llvm::SmallVectorImpl<StringRef> &Features) const override;
234
235
  std::optional<unsigned> getCPUCacheLineSize() const override;
236
237
  bool validateAsmConstraint(const char *&Name,
238
                             TargetInfo::ConstraintInfo &info) const override;
239
240
  bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
241
0
                                      bool &HasSizeMismatch) const override {
242
    // esp and ebp are the only 32-bit registers the x86 backend can currently
243
    // handle.
244
0
    if (RegName.equals("esp") || RegName.equals("ebp")) {
245
      // Check that the register size is 32-bit.
246
0
      HasSizeMismatch = RegSize != 32;
247
0
      return true;
248
0
    }
249
250
0
    return false;
251
0
  }
252
253
  bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
254
                          StringRef Constraint, unsigned Size) const override;
255
256
  bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
257
                         StringRef Constraint, unsigned Size) const override;
258
259
  bool
260
0
  checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
261
0
    if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
262
0
      return true;
263
0
    return TargetInfo::checkCFProtectionReturnSupported(Diags);
264
0
  };
265
266
  bool
267
0
  checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
268
0
    if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
269
0
      return true;
270
0
    return TargetInfo::checkCFProtectionBranchSupported(Diags);
271
0
  };
272
273
  virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
274
                                   StringRef Constraint, unsigned Size) const;
275
276
  std::string convertConstraint(const char *&Constraint) const override;
277
0
  std::string_view getClobbers() const override {
278
0
    return "~{dirflag},~{fpsr},~{flags}";
279
0
  }
280
281
  StringRef getConstraintRegister(StringRef Constraint,
282
0
                                  StringRef Expression) const override {
283
0
    StringRef::iterator I, E;
284
0
    for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
285
0
      if (isalpha(*I) || *I == '@')
286
0
        break;
287
0
    }
288
0
    if (I == E)
289
0
      return "";
290
0
    switch (*I) {
291
    // For the register constraints, return the matching register name
292
0
    case 'a':
293
0
      return "ax";
294
0
    case 'b':
295
0
      return "bx";
296
0
    case 'c':
297
0
      return "cx";
298
0
    case 'd':
299
0
      return "dx";
300
0
    case 'S':
301
0
      return "si";
302
0
    case 'D':
303
0
      return "di";
304
    // In case the constraint is 'r' we need to return Expression
305
0
    case 'r':
306
0
      return Expression;
307
    // Double letters Y<x> constraints
308
0
    case 'Y':
309
0
      if ((++I != E) && ((*I == '0') || (*I == 'z')))
310
0
        return "xmm0";
311
0
      break;
312
0
    default:
313
0
      break;
314
0
    }
315
0
    return "";
316
0
  }
317
318
2
  bool useFP16ConversionIntrinsics() const override {
319
2
    return false;
320
2
  }
321
322
  void getTargetDefines(const LangOptions &Opts,
323
                        MacroBuilder &Builder) const override;
324
325
  void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
326
                         bool Enabled) const final;
327
328
  bool
329
  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
330
                 StringRef CPU,
331
                 const std::vector<std::string> &FeaturesVec) const override;
332
333
  bool isValidFeatureName(StringRef Name) const override;
334
335
  bool hasFeature(StringRef Feature) const final;
336
337
  bool handleTargetFeatures(std::vector<std::string> &Features,
338
                            DiagnosticsEngine &Diags) override;
339
340
92
  StringRef getABI() const override {
341
92
    if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
342
0
      return "avx512";
343
92
    if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
344
0
      return "avx";
345
92
    if (getTriple().getArch() == llvm::Triple::x86 &&
346
92
        MMX3DNowLevel == NoMMX3DNow)
347
0
      return "no-mmx";
348
92
    return "";
349
92
  }
350
351
0
  bool supportsTargetAttributeTune() const override {
352
0
    return true;
353
0
  }
354
355
0
  bool isValidCPUName(StringRef Name) const override {
356
0
    bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
357
0
    return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None;
358
0
  }
359
360
0
  bool isValidTuneCPUName(StringRef Name) const override {
361
0
    if (Name == "generic")
362
0
      return true;
363
364
    // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName.
365
    // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient
366
    // since mtune was ignored by clang for so long.
367
0
    return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None;
368
0
  }
369
370
  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
371
  void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
372
373
0
  bool setCPU(const std::string &Name) override {
374
0
    bool Only64Bit = getTriple().getArch() != llvm::Triple::x86;
375
0
    CPU = llvm::X86::parseArchX86(Name, Only64Bit);
376
0
    return CPU != llvm::X86::CK_None;
377
0
  }
378
379
  unsigned multiVersionSortPriority(StringRef Name) const override;
380
381
  bool setFPMath(StringRef Name) override;
382
383
0
  bool supportsExtendIntArgs() const override {
384
0
    return getTriple().getArch() != llvm::Triple::x86;
385
0
  }
386
387
0
  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
388
    // Most of the non-ARM calling conventions are i386 conventions.
389
0
    switch (CC) {
390
0
    case CC_X86ThisCall:
391
0
    case CC_X86FastCall:
392
0
    case CC_X86StdCall:
393
0
    case CC_X86VectorCall:
394
0
    case CC_X86RegCall:
395
0
    case CC_C:
396
0
    case CC_PreserveMost:
397
0
    case CC_Swift:
398
0
    case CC_X86Pascal:
399
0
    case CC_IntelOclBicc:
400
0
    case CC_OpenCLKernel:
401
0
      return CCCR_OK;
402
0
    case CC_SwiftAsync:
403
0
      return CCCR_Error;
404
0
    default:
405
0
      return CCCR_Warning;
406
0
    }
407
0
  }
408
409
0
  bool checkArithmeticFenceSupported() const override { return true; }
410
411
0
  CallingConv getDefaultCallingConv() const override {
412
0
    return CC_C;
413
0
  }
414
415
0
  bool hasSjLjLowering() const override { return true; }
416
417
46
  void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
418
419
0
  uint64_t getPointerWidthV(LangAS AS) const override {
420
0
    unsigned TargetAddrSpace = getTargetAddressSpace(AS);
421
0
    if (TargetAddrSpace == ptr32_sptr || TargetAddrSpace == ptr32_uptr)
422
0
      return 32;
423
0
    if (TargetAddrSpace == ptr64)
424
0
      return 64;
425
0
    return PointerWidth;
426
0
  }
427
428
0
  uint64_t getPointerAlignV(LangAS AddrSpace) const override {
429
0
    return getPointerWidthV(AddrSpace);
430
0
  }
431
432
};
433
434
// X86-32 generic target
435
class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo {
436
public:
437
  X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
438
0
      : X86TargetInfo(Triple, Opts) {
439
0
    DoubleAlign = LongLongAlign = 32;
440
0
    LongDoubleWidth = 96;
441
0
    LongDoubleAlign = 32;
442
0
    SuitableAlign = 128;
443
0
    resetDataLayout(Triple.isOSBinFormatMachO()
444
0
                        ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
445
0
                          "128-f64:32:64-f80:32-n8:16:32-S128"
446
0
                        : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
447
0
                          "128-f64:32:64-f80:32-n8:16:32-S128",
448
0
                    Triple.isOSBinFormatMachO() ? "_" : "");
449
0
    SizeType = UnsignedInt;
450
0
    PtrDiffType = SignedInt;
451
0
    IntPtrType = SignedInt;
452
0
    RegParmMax = 3;
453
454
    // Use fpret for all types.
455
0
    RealTypeUsesObjCFPRetMask =
456
0
        (unsigned)(FloatModeKind::Float | FloatModeKind::Double |
457
0
                   FloatModeKind::LongDouble);
458
459
    // x86-32 has atomics up to 8 bytes
460
0
    MaxAtomicPromoteWidth = 64;
461
0
    MaxAtomicInlineWidth = 32;
462
0
  }
463
464
0
  BuiltinVaListKind getBuiltinVaListKind() const override {
465
0
    return TargetInfo::CharPtrBuiltinVaList;
466
0
  }
467
468
0
  int getEHDataRegisterNumber(unsigned RegNo) const override {
469
0
    if (RegNo == 0)
470
0
      return 0;
471
0
    if (RegNo == 1)
472
0
      return 2;
473
0
    return -1;
474
0
  }
475
476
  bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
477
0
                           StringRef Constraint, unsigned Size) const override {
478
0
    switch (Constraint[0]) {
479
0
    default:
480
0
      break;
481
0
    case 'R':
482
0
    case 'q':
483
0
    case 'Q':
484
0
    case 'a':
485
0
    case 'b':
486
0
    case 'c':
487
0
    case 'd':
488
0
    case 'S':
489
0
    case 'D':
490
0
      return Size <= 32;
491
0
    case 'A':
492
0
      return Size <= 64;
493
0
    }
494
495
0
    return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size);
496
0
  }
497
498
0
  void setMaxAtomicWidth() override {
499
0
    if (hasFeature("cx8"))
500
0
      MaxAtomicInlineWidth = 64;
501
0
  }
502
503
  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
504
505
0
  bool hasBitIntType() const override { return true; }
506
0
  size_t getMaxBitIntWidth() const override {
507
0
    return llvm::IntegerType::MAX_INT_BITS;
508
0
  }
509
};
510
511
class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
512
    : public NetBSDTargetInfo<X86_32TargetInfo> {
513
public:
514
  NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
515
0
      : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
516
517
0
  LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
518
0
    VersionTuple OsVersion = getTriple().getOSVersion();
519
    // New NetBSD uses the default rounding mode.
520
0
    if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0)
521
0
      return X86_32TargetInfo::getFPEvalMethod();
522
    // NetBSD before 6.99.26 defaults to "double" rounding.
523
0
    return LangOptions::FPEvalMethodKind::FEM_Double;
524
0
  }
525
};
526
527
class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo
528
    : public OpenBSDTargetInfo<X86_32TargetInfo> {
529
public:
530
  OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
531
0
      : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
532
0
    SizeType = UnsignedLong;
533
0
    IntPtrType = SignedLong;
534
0
    PtrDiffType = SignedLong;
535
0
  }
536
};
537
538
class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo
539
    : public DarwinTargetInfo<X86_32TargetInfo> {
540
public:
541
  DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
542
0
      : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
543
0
    LongDoubleWidth = 128;
544
0
    LongDoubleAlign = 128;
545
0
    SuitableAlign = 128;
546
0
    MaxVectorAlign = 256;
547
    // The watchOS simulator uses the builtin bool type for Objective-C.
548
0
    llvm::Triple T = llvm::Triple(Triple);
549
0
    if (T.isWatchOS())
550
0
      UseSignedCharForObjCBool = false;
551
0
    SizeType = UnsignedLong;
552
0
    IntPtrType = SignedLong;
553
0
    resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-"
554
0
                    "f64:32:64-f80:128-n8:16:32-S128",
555
0
                    "_");
556
0
    HasAlignMac68kSupport = true;
557
0
  }
558
559
  bool handleTargetFeatures(std::vector<std::string> &Features,
560
0
                            DiagnosticsEngine &Diags) override {
561
0
    if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
562
0
                                                                  Diags))
563
0
      return false;
564
    // We now know the features we have: we can decide how to align vectors.
565
0
    MaxVectorAlign =
566
0
        hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
567
0
    return true;
568
0
  }
569
};
570
571
// x86-32 Windows target
572
class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo
573
    : public WindowsTargetInfo<X86_32TargetInfo> {
574
public:
575
  WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
576
0
      : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
577
0
    DoubleAlign = LongLongAlign = 64;
578
0
    bool IsWinCOFF =
579
0
        getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
580
0
    bool IsMSVC = getTriple().isWindowsMSVCEnvironment();
581
0
    std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e";
582
0
    Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-";
583
0
    Layout += IsMSVC ? "f80:128" : "f80:32";
584
0
    Layout += "-n8:16:32-a:0:32-S32";
585
0
    resetDataLayout(Layout, IsWinCOFF ? "_" : "");
586
0
  }
587
};
588
589
// x86-32 Windows Visual Studio target
590
class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo
591
    : public WindowsX86_32TargetInfo {
592
public:
593
  MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
594
                            const TargetOptions &Opts)
595
0
      : WindowsX86_32TargetInfo(Triple, Opts) {
596
0
    LongDoubleWidth = LongDoubleAlign = 64;
597
0
    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
598
0
  }
599
600
  void getTargetDefines(const LangOptions &Opts,
601
0
                        MacroBuilder &Builder) const override {
602
0
    WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
603
    // The value of the following reflects processor type.
604
    // 300=386, 400=486, 500=Pentium, 600=Blend (default)
605
    // We lost the original triple, so we use the default.
606
0
    Builder.defineMacro("_M_IX86", "600");
607
0
  }
608
};
609
610
// x86-32 MinGW target
611
class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo
612
    : public WindowsX86_32TargetInfo {
613
public:
614
  MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
615
0
      : WindowsX86_32TargetInfo(Triple, Opts) {
616
0
    HasFloat128 = true;
617
0
  }
618
619
  void getTargetDefines(const LangOptions &Opts,
620
0
                        MacroBuilder &Builder) const override {
621
0
    WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
622
0
    Builder.defineMacro("_X86_");
623
0
  }
624
};
625
626
// x86-32 Cygwin target
627
class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo {
628
public:
629
  CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
630
0
      : X86_32TargetInfo(Triple, Opts) {
631
0
    this->WCharType = TargetInfo::UnsignedShort;
632
0
    DoubleAlign = LongLongAlign = 64;
633
0
    resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"
634
0
                    "i128:128-f80:32-n8:16:32-a:0:32-S32",
635
0
                    "_");
636
0
  }
637
638
  void getTargetDefines(const LangOptions &Opts,
639
0
                        MacroBuilder &Builder) const override {
640
0
    X86_32TargetInfo::getTargetDefines(Opts, Builder);
641
0
    Builder.defineMacro("_X86_");
642
0
    Builder.defineMacro("__CYGWIN__");
643
0
    Builder.defineMacro("__CYGWIN32__");
644
0
    addCygMingDefines(Opts, Builder);
645
0
    DefineStd(Builder, "unix", Opts);
646
0
    if (Opts.CPlusPlus)
647
0
      Builder.defineMacro("_GNU_SOURCE");
648
0
  }
649
};
650
651
// x86-32 Haiku target
652
class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo
653
    : public HaikuTargetInfo<X86_32TargetInfo> {
654
public:
655
  HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
656
0
      : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
657
658
  void getTargetDefines(const LangOptions &Opts,
659
0
                        MacroBuilder &Builder) const override {
660
0
    HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
661
0
    Builder.defineMacro("__INTEL__");
662
0
  }
663
};
664
665
// X86-32 MCU target
666
class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo {
667
public:
668
  MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
669
0
      : X86_32TargetInfo(Triple, Opts) {
670
0
    LongDoubleWidth = 64;
671
0
    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
672
0
    resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-"
673
0
                    "f64:32-f128:32-n8:16:32-a:0:32-S32");
674
0
    WIntType = UnsignedInt;
675
0
  }
676
677
0
  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
678
    // On MCU we support only C calling convention.
679
0
    return CC == CC_C ? CCCR_OK : CCCR_Warning;
680
0
  }
681
682
  void getTargetDefines(const LangOptions &Opts,
683
0
                        MacroBuilder &Builder) const override {
684
0
    X86_32TargetInfo::getTargetDefines(Opts, Builder);
685
0
    Builder.defineMacro("__iamcu");
686
0
    Builder.defineMacro("__iamcu__");
687
0
  }
688
689
0
  bool allowsLargerPreferedTypeAlignment() const override { return false; }
690
};
691
692
// x86-32 RTEMS target
693
class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo {
694
public:
695
  RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
696
0
      : X86_32TargetInfo(Triple, Opts) {
697
0
    SizeType = UnsignedLong;
698
0
    IntPtrType = SignedLong;
699
0
    PtrDiffType = SignedLong;
700
0
  }
701
702
  void getTargetDefines(const LangOptions &Opts,
703
0
                        MacroBuilder &Builder) const override {
704
0
    X86_32TargetInfo::getTargetDefines(Opts, Builder);
705
0
    Builder.defineMacro("__INTEL__");
706
0
    Builder.defineMacro("__rtems__");
707
0
  }
708
};
709
710
// x86-64 generic target
711
class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo {
712
public:
713
  X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
714
46
      : X86TargetInfo(Triple, Opts) {
715
46
    const bool IsX32 = getTriple().isX32();
716
46
    bool IsWinCOFF =
717
46
        getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
718
46
    LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
719
46
    LongDoubleWidth = 128;
720
46
    LongDoubleAlign = 128;
721
46
    LargeArrayMinWidth = 128;
722
46
    LargeArrayAlign = 128;
723
46
    SuitableAlign = 128;
724
46
    SizeType = IsX32 ? UnsignedInt : UnsignedLong;
725
46
    PtrDiffType = IsX32 ? SignedInt : SignedLong;
726
46
    IntPtrType = IsX32 ? SignedInt : SignedLong;
727
46
    IntMaxType = IsX32 ? SignedLongLong : SignedLong;
728
46
    Int64Type = IsX32 ? SignedLongLong : SignedLong;
729
46
    RegParmMax = 6;
730
731
    // Pointers are 32-bit in x32.
732
46
    resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
733
0
                            "i64:64-i128:128-f80:128-n8:16:32:64-S128"
734
46
                    : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:"
735
0
                                  "64-i128:128-f80:128-n8:16:32:64-S128"
736
46
                                : "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:"
737
46
                                  "64-i128:128-f80:128-n8:16:32:64-S128");
738
739
    // Use fpret only for long double.
740
46
    RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;
741
742
    // Use fp2ret for _Complex long double.
743
46
    ComplexLongDoubleUsesFP2Ret = true;
744
745
    // Make __builtin_ms_va_list available.
746
46
    HasBuiltinMSVaList = true;
747
748
    // x86-64 has atomics up to 16 bytes.
749
46
    MaxAtomicPromoteWidth = 128;
750
46
    MaxAtomicInlineWidth = 64;
751
46
  }
752
753
46
  BuiltinVaListKind getBuiltinVaListKind() const override {
754
46
    return TargetInfo::X86_64ABIBuiltinVaList;
755
46
  }
756
757
0
  int getEHDataRegisterNumber(unsigned RegNo) const override {
758
0
    if (RegNo == 0)
759
0
      return 0;
760
0
    if (RegNo == 1)
761
0
      return 1;
762
0
    return -1;
763
0
  }
764
765
0
  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
766
0
    switch (CC) {
767
0
    case CC_C:
768
0
    case CC_Swift:
769
0
    case CC_SwiftAsync:
770
0
    case CC_X86VectorCall:
771
0
    case CC_IntelOclBicc:
772
0
    case CC_Win64:
773
0
    case CC_PreserveMost:
774
0
    case CC_PreserveAll:
775
0
    case CC_X86RegCall:
776
0
    case CC_OpenCLKernel:
777
0
      return CCCR_OK;
778
0
    default:
779
0
      return CCCR_Warning;
780
0
    }
781
0
  }
782
783
24
  CallingConv getDefaultCallingConv() const override {
784
24
    return CC_C;
785
24
  }
786
787
  // for x32 we need it here explicitly
788
138
  bool hasInt128Type() const override { return true; }
789
790
0
  unsigned getUnwindWordWidth() const override { return 64; }
791
792
0
  unsigned getRegisterWidth() const override { return 64; }
793
794
  bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
795
0
                                      bool &HasSizeMismatch) const override {
796
    // rsp and rbp are the only 64-bit registers the x86 backend can currently
797
    // handle.
798
0
    if (RegName.equals("rsp") || RegName.equals("rbp")) {
799
      // Check that the register size is 64-bit.
800
0
      HasSizeMismatch = RegSize != 64;
801
0
      return true;
802
0
    }
803
804
    // Check if the register is a 32-bit register the backend can handle.
805
0
    return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
806
0
                                                         HasSizeMismatch);
807
0
  }
808
809
46
  void setMaxAtomicWidth() override {
810
46
    if (hasFeature("cx16"))
811
0
      MaxAtomicInlineWidth = 128;
812
46
  }
813
814
  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
815
816
0
  bool hasBitIntType() const override { return true; }
817
46
  size_t getMaxBitIntWidth() const override {
818
46
    return llvm::IntegerType::MAX_INT_BITS;
819
46
  }
820
};
821
822
// x86-64 Windows target
823
class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
824
    : public WindowsTargetInfo<X86_64TargetInfo> {
825
public:
826
  WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
827
0
      : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
828
0
    LongWidth = LongAlign = 32;
829
0
    DoubleAlign = LongLongAlign = 64;
830
0
    IntMaxType = SignedLongLong;
831
0
    Int64Type = SignedLongLong;
832
0
    SizeType = UnsignedLongLong;
833
0
    PtrDiffType = SignedLongLong;
834
0
    IntPtrType = SignedLongLong;
835
0
  }
836
837
0
  BuiltinVaListKind getBuiltinVaListKind() const override {
838
0
    return TargetInfo::CharPtrBuiltinVaList;
839
0
  }
840
841
0
  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
842
0
    switch (CC) {
843
0
    case CC_X86StdCall:
844
0
    case CC_X86ThisCall:
845
0
    case CC_X86FastCall:
846
0
      return CCCR_Ignore;
847
0
    case CC_C:
848
0
    case CC_X86VectorCall:
849
0
    case CC_IntelOclBicc:
850
0
    case CC_PreserveMost:
851
0
    case CC_PreserveAll:
852
0
    case CC_X86_64SysV:
853
0
    case CC_Swift:
854
0
    case CC_SwiftAsync:
855
0
    case CC_X86RegCall:
856
0
    case CC_OpenCLKernel:
857
0
      return CCCR_OK;
858
0
    default:
859
0
      return CCCR_Warning;
860
0
    }
861
0
  }
862
};
863
864
// x86-64 Windows Visual Studio target
865
class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
866
    : public WindowsX86_64TargetInfo {
867
public:
868
  MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
869
                            const TargetOptions &Opts)
870
0
      : WindowsX86_64TargetInfo(Triple, Opts) {
871
0
    LongDoubleWidth = LongDoubleAlign = 64;
872
0
    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
873
0
  }
874
875
  void getTargetDefines(const LangOptions &Opts,
876
0
                        MacroBuilder &Builder) const override {
877
0
    WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
878
0
    Builder.defineMacro("_M_X64", "100");
879
0
    Builder.defineMacro("_M_AMD64", "100");
880
0
  }
881
882
  TargetInfo::CallingConvKind
883
0
  getCallingConvKind(bool ClangABICompat4) const override {
884
0
    return CCK_MicrosoftWin64;
885
0
  }
886
};
887
888
// x86-64 MinGW target
889
class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo
890
    : public WindowsX86_64TargetInfo {
891
public:
892
  MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
893
0
      : WindowsX86_64TargetInfo(Triple, Opts) {
894
    // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
895
    // with x86 FP ops. Weird.
896
0
    LongDoubleWidth = LongDoubleAlign = 128;
897
0
    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
898
0
    HasFloat128 = true;
899
0
  }
900
};
901
902
// x86-64 Cygwin target
903
class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo {
904
public:
905
  CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
906
0
      : X86_64TargetInfo(Triple, Opts) {
907
0
    this->WCharType = TargetInfo::UnsignedShort;
908
0
    TLSSupported = false;
909
0
  }
910
911
  void getTargetDefines(const LangOptions &Opts,
912
0
                        MacroBuilder &Builder) const override {
913
0
    X86_64TargetInfo::getTargetDefines(Opts, Builder);
914
0
    Builder.defineMacro("__x86_64__");
915
0
    Builder.defineMacro("__CYGWIN__");
916
0
    Builder.defineMacro("__CYGWIN64__");
917
0
    addCygMingDefines(Opts, Builder);
918
0
    DefineStd(Builder, "unix", Opts);
919
0
    if (Opts.CPlusPlus)
920
0
      Builder.defineMacro("_GNU_SOURCE");
921
0
  }
922
};
923
924
class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo
925
    : public DarwinTargetInfo<X86_64TargetInfo> {
926
public:
927
  DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
928
0
      : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
929
0
    Int64Type = SignedLongLong;
930
    // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
931
0
    llvm::Triple T = llvm::Triple(Triple);
932
0
    if (T.isiOS())
933
0
      UseSignedCharForObjCBool = false;
934
0
    resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
935
0
                    "f80:128-n8:16:32:64-S128",
936
0
                    "_");
937
0
  }
938
939
  bool handleTargetFeatures(std::vector<std::string> &Features,
940
0
                            DiagnosticsEngine &Diags) override {
941
0
    if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
942
0
                                                                  Diags))
943
0
      return false;
944
    // We now know the features we have: we can decide how to align vectors.
945
0
    MaxVectorAlign =
946
0
        hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
947
0
    return true;
948
0
  }
949
};
950
951
class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo
952
    : public OpenBSDTargetInfo<X86_64TargetInfo> {
953
public:
954
  OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
955
0
      : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
956
0
    IntMaxType = SignedLongLong;
957
0
    Int64Type = SignedLongLong;
958
0
  }
959
};
960
961
// x86_32 Android target
962
class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo
963
    : public LinuxTargetInfo<X86_32TargetInfo> {
964
public:
965
  AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
966
0
      : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
967
0
    SuitableAlign = 32;
968
0
    LongDoubleWidth = 64;
969
0
    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
970
0
  }
971
};
972
973
// x86_64 Android target
974
class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo
975
    : public LinuxTargetInfo<X86_64TargetInfo> {
976
public:
977
  AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
978
0
      : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
979
0
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
980
0
  }
981
};
982
983
// x86_32 OHOS target
984
class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo
985
    : public OHOSTargetInfo<X86_32TargetInfo> {
986
public:
987
  OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
988
0
      : OHOSTargetInfo<X86_32TargetInfo>(Triple, Opts) {
989
0
    SuitableAlign = 32;
990
0
    LongDoubleWidth = 64;
991
0
    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
992
0
  }
993
};
994
995
// x86_64 OHOS target
996
class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo
997
    : public OHOSTargetInfo<X86_64TargetInfo> {
998
public:
999
  OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1000
0
      : OHOSTargetInfo<X86_64TargetInfo>(Triple, Opts) {
1001
0
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
1002
0
  }
1003
};
1004
} // namespace targets
1005
} // namespace clang
1006
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H