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 856