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