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