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