WebAssembly.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //=== WebAssembly.h - Declare WebAssembly 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 WebAssembly TargetInfo objects.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
  13. #define LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
  14. #include "clang/Basic/TargetInfo.h"
  15. #include "clang/Basic/TargetOptions.h"
  16. #include "llvm/ADT/Triple.h"
  17. #include "llvm/Support/Compiler.h"
  18. namespace clang {
  19. namespace targets {
  20. class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
  21. enum SIMDEnum {
  22. NoSIMD,
  23. SIMD128,
  24. RelaxedSIMD,
  25. } SIMDLevel = NoSIMD;
  26. bool HasNontrappingFPToInt = false;
  27. bool HasSignExt = false;
  28. bool HasExceptionHandling = false;
  29. bool HasBulkMemory = false;
  30. bool HasAtomics = false;
  31. bool HasMutableGlobals = false;
  32. bool HasMultivalue = false;
  33. bool HasTailCall = false;
  34. bool HasReferenceTypes = false;
  35. bool HasExtendedConst = false;
  36. std::string ABI;
  37. public:
  38. explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
  39. : TargetInfo(T) {
  40. NoAsmVariants = true;
  41. SuitableAlign = 128;
  42. LargeArrayMinWidth = 128;
  43. LargeArrayAlign = 128;
  44. SimdDefaultAlign = 128;
  45. SigAtomicType = SignedLong;
  46. LongDoubleWidth = LongDoubleAlign = 128;
  47. LongDoubleFormat = &llvm::APFloat::IEEEquad();
  48. MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
  49. // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
  50. // more consistent between the two.
  51. SizeType = UnsignedLong;
  52. PtrDiffType = SignedLong;
  53. IntPtrType = SignedLong;
  54. }
  55. StringRef getABI() const override;
  56. bool setABI(const std::string &Name) override;
  57. protected:
  58. void getTargetDefines(const LangOptions &Opts,
  59. MacroBuilder &Builder) const override;
  60. private:
  61. static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level,
  62. bool Enabled);
  63. bool
  64. initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
  65. StringRef CPU,
  66. const std::vector<std::string> &FeaturesVec) const override;
  67. bool hasFeature(StringRef Feature) const final;
  68. void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
  69. bool Enabled) const final;
  70. bool handleTargetFeatures(std::vector<std::string> &Features,
  71. DiagnosticsEngine &Diags) final;
  72. bool isValidCPUName(StringRef Name) const final;
  73. void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
  74. bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
  75. ArrayRef<Builtin::Info> getTargetBuiltins() const final;
  76. BuiltinVaListKind getBuiltinVaListKind() const final {
  77. return VoidPtrBuiltinVaList;
  78. }
  79. ArrayRef<const char *> getGCCRegNames() const final { return std::nullopt; }
  80. ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
  81. return std::nullopt;
  82. }
  83. bool validateAsmConstraint(const char *&Name,
  84. TargetInfo::ConstraintInfo &Info) const final {
  85. return false;
  86. }
  87. const char *getClobbers() const final { return ""; }
  88. bool isCLZForZeroUndef() const final { return false; }
  89. bool hasInt128Type() const final { return true; }
  90. IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
  91. // WebAssembly prefers long long for explicitly 64-bit integers.
  92. return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
  93. : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
  94. }
  95. IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
  96. // WebAssembly uses long long for int_least64_t and int_fast64_t.
  97. return BitWidth == 64
  98. ? (IsSigned ? SignedLongLong : UnsignedLongLong)
  99. : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
  100. }
  101. CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
  102. switch (CC) {
  103. case CC_C:
  104. case CC_Swift:
  105. return CCCR_OK;
  106. case CC_SwiftAsync:
  107. return CCCR_Error;
  108. default:
  109. return CCCR_Warning;
  110. }
  111. }
  112. bool hasBitIntType() const override { return true; }
  113. bool hasProtectedVisibility() const override { return false; }
  114. void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
  115. };
  116. class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
  117. : public WebAssemblyTargetInfo {
  118. public:
  119. explicit WebAssembly32TargetInfo(const llvm::Triple &T,
  120. const TargetOptions &Opts)
  121. : WebAssemblyTargetInfo(T, Opts) {
  122. if (T.isOSEmscripten())
  123. resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
  124. "S128-ni:1:10:20");
  125. else
  126. resetDataLayout(
  127. "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
  128. }
  129. protected:
  130. void getTargetDefines(const LangOptions &Opts,
  131. MacroBuilder &Builder) const override;
  132. };
  133. class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
  134. : public WebAssemblyTargetInfo {
  135. public:
  136. explicit WebAssembly64TargetInfo(const llvm::Triple &T,
  137. const TargetOptions &Opts)
  138. : WebAssemblyTargetInfo(T, Opts) {
  139. LongAlign = LongWidth = 64;
  140. PointerAlign = PointerWidth = 64;
  141. SizeType = UnsignedLong;
  142. PtrDiffType = SignedLong;
  143. IntPtrType = SignedLong;
  144. if (T.isOSEmscripten())
  145. resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
  146. "S128-ni:1:10:20");
  147. else
  148. resetDataLayout(
  149. "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
  150. }
  151. protected:
  152. void getTargetDefines(const LangOptions &Opts,
  153. MacroBuilder &Builder) const override;
  154. };
  155. } // namespace targets
  156. } // namespace clang
  157. #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H