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