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