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