X86.h 30 KB

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