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