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