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