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