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