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