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