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