xref: /freebsd-src/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //=== WebAssembly.h - Declare WebAssembly target feature support *- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares WebAssembly TargetInfo objects.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
170b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h"
180b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
1906c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace clang {
220b57cec5SDimitry Andric namespace targets {
230b57cec5SDimitry Andric 
2406c3fb27SDimitry Andric static const unsigned WebAssemblyAddrSpaceMap[] = {
2506c3fb27SDimitry Andric     0, // Default
2606c3fb27SDimitry Andric     0, // opencl_global
2706c3fb27SDimitry Andric     0, // opencl_local
2806c3fb27SDimitry Andric     0, // opencl_constant
2906c3fb27SDimitry Andric     0, // opencl_private
3006c3fb27SDimitry Andric     0, // opencl_generic
3106c3fb27SDimitry Andric     0, // opencl_global_device
3206c3fb27SDimitry Andric     0, // opencl_global_host
3306c3fb27SDimitry Andric     0, // cuda_device
3406c3fb27SDimitry Andric     0, // cuda_constant
3506c3fb27SDimitry Andric     0, // cuda_shared
3606c3fb27SDimitry Andric     0, // sycl_global
3706c3fb27SDimitry Andric     0, // sycl_global_device
3806c3fb27SDimitry Andric     0, // sycl_global_host
3906c3fb27SDimitry Andric     0, // sycl_local
4006c3fb27SDimitry Andric     0, // sycl_private
4106c3fb27SDimitry Andric     0, // ptr32_sptr
4206c3fb27SDimitry Andric     0, // ptr32_uptr
4306c3fb27SDimitry Andric     0, // ptr64
4406c3fb27SDimitry Andric     0, // hlsl_groupshared
4506c3fb27SDimitry Andric     20, // wasm_funcref
4606c3fb27SDimitry Andric };
4706c3fb27SDimitry Andric 
480b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   enum SIMDEnum {
510b57cec5SDimitry Andric     NoSIMD,
520b57cec5SDimitry Andric     SIMD128,
53349cc55cSDimitry Andric     RelaxedSIMD,
540b57cec5SDimitry Andric   } SIMDLevel = NoSIMD;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   bool HasAtomics = false;
57*0fca6ea1SDimitry Andric   bool HasBulkMemory = false;
58*0fca6ea1SDimitry Andric   bool HasExceptionHandling = false;
5981ad6265SDimitry Andric   bool HasExtendedConst = false;
60*0fca6ea1SDimitry Andric   bool HasHalfPrecision = false;
615f757f3fSDimitry Andric   bool HasMultiMemory = false;
62*0fca6ea1SDimitry Andric   bool HasMultivalue = false;
63*0fca6ea1SDimitry Andric   bool HasMutableGlobals = false;
64*0fca6ea1SDimitry Andric   bool HasNontrappingFPToInt = false;
65*0fca6ea1SDimitry Andric   bool HasReferenceTypes = false;
66*0fca6ea1SDimitry Andric   bool HasSignExt = false;
67*0fca6ea1SDimitry Andric   bool HasTailCall = false;
685ffd83dbSDimitry Andric 
695ffd83dbSDimitry Andric   std::string ABI;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric public:
720b57cec5SDimitry Andric   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
730b57cec5SDimitry Andric       : TargetInfo(T) {
7406c3fb27SDimitry Andric     AddrSpaceMap = &WebAssemblyAddrSpaceMap;
750b57cec5SDimitry Andric     NoAsmVariants = true;
760b57cec5SDimitry Andric     SuitableAlign = 128;
770b57cec5SDimitry Andric     LargeArrayMinWidth = 128;
780b57cec5SDimitry Andric     LargeArrayAlign = 128;
790b57cec5SDimitry Andric     SigAtomicType = SignedLong;
800b57cec5SDimitry Andric     LongDoubleWidth = LongDoubleAlign = 128;
810b57cec5SDimitry Andric     LongDoubleFormat = &llvm::APFloat::IEEEquad();
820b57cec5SDimitry Andric     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
830b57cec5SDimitry Andric     // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
840b57cec5SDimitry Andric     // more consistent between the two.
850b57cec5SDimitry Andric     SizeType = UnsignedLong;
860b57cec5SDimitry Andric     PtrDiffType = SignedLong;
870b57cec5SDimitry Andric     IntPtrType = SignedLong;
88*0fca6ea1SDimitry Andric     HasUnalignedAccess = true;
890b57cec5SDimitry Andric   }
900b57cec5SDimitry Andric 
915ffd83dbSDimitry Andric   StringRef getABI() const override;
925ffd83dbSDimitry Andric   bool setABI(const std::string &Name) override;
93*0fca6ea1SDimitry Andric   bool useFP16ConversionIntrinsics() const override {
94*0fca6ea1SDimitry Andric     return !HasHalfPrecision;
95*0fca6ea1SDimitry Andric   }
965ffd83dbSDimitry Andric 
970b57cec5SDimitry Andric protected:
980b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
990b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric private:
10275b4d546SDimitry Andric   static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level,
10375b4d546SDimitry Andric                            bool Enabled);
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   bool
1060b57cec5SDimitry Andric   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
1070b57cec5SDimitry Andric                  StringRef CPU,
1080b57cec5SDimitry Andric                  const std::vector<std::string> &FeaturesVec) const override;
1090b57cec5SDimitry Andric   bool hasFeature(StringRef Feature) const final;
1100b57cec5SDimitry Andric 
11175b4d546SDimitry Andric   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
11275b4d546SDimitry Andric                          bool Enabled) const final;
11375b4d546SDimitry Andric 
1140b57cec5SDimitry Andric   bool handleTargetFeatures(std::vector<std::string> &Features,
1150b57cec5SDimitry Andric                             DiagnosticsEngine &Diags) final;
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   bool isValidCPUName(StringRef Name) const final;
1180b57cec5SDimitry Andric   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   ArrayRef<Builtin::Info> getTargetBuiltins() const final;
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   BuiltinVaListKind getBuiltinVaListKind() const final {
1250b57cec5SDimitry Andric     return VoidPtrBuiltinVaList;
1260b57cec5SDimitry Andric   }
1270b57cec5SDimitry Andric 
128bdd1243dSDimitry Andric   ArrayRef<const char *> getGCCRegNames() const final { return std::nullopt; }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
131bdd1243dSDimitry Andric     return std::nullopt;
1320b57cec5SDimitry Andric   }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   bool validateAsmConstraint(const char *&Name,
1350b57cec5SDimitry Andric                              TargetInfo::ConstraintInfo &Info) const final {
1360b57cec5SDimitry Andric     return false;
1370b57cec5SDimitry Andric   }
1380b57cec5SDimitry Andric 
13906c3fb27SDimitry Andric   std::string_view getClobbers() const final { return ""; }
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric   bool isCLZForZeroUndef() const final { return false; }
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   bool hasInt128Type() const final { return true; }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1460b57cec5SDimitry Andric     // WebAssembly prefers long long for explicitly 64-bit integers.
1470b57cec5SDimitry Andric     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1480b57cec5SDimitry Andric                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
1490b57cec5SDimitry Andric   }
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1520b57cec5SDimitry Andric     // WebAssembly uses long long for int_least64_t and int_fast64_t.
1530b57cec5SDimitry Andric     return BitWidth == 64
1540b57cec5SDimitry Andric                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1550b57cec5SDimitry Andric                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
1560b57cec5SDimitry Andric   }
1575ffd83dbSDimitry Andric 
1585ffd83dbSDimitry Andric   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
1595ffd83dbSDimitry Andric     switch (CC) {
1605ffd83dbSDimitry Andric     case CC_C:
1615ffd83dbSDimitry Andric     case CC_Swift:
1625ffd83dbSDimitry Andric       return CCCR_OK;
163fe6060f1SDimitry Andric     case CC_SwiftAsync:
164fe6060f1SDimitry Andric       return CCCR_Error;
1655ffd83dbSDimitry Andric     default:
1665ffd83dbSDimitry Andric       return CCCR_Warning;
1675ffd83dbSDimitry Andric     }
1685ffd83dbSDimitry Andric   }
1695ffd83dbSDimitry Andric 
1700eae32dcSDimitry Andric   bool hasBitIntType() const override { return true; }
1715ffd83dbSDimitry Andric 
1725ffd83dbSDimitry Andric   bool hasProtectedVisibility() const override { return false; }
173fe6060f1SDimitry Andric 
174fe6060f1SDimitry Andric   void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
1750b57cec5SDimitry Andric };
1765ffd83dbSDimitry Andric 
1770b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
1780b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1790b57cec5SDimitry Andric public:
1800b57cec5SDimitry Andric   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
1810b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1820b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
183fe6060f1SDimitry Andric     if (T.isOSEmscripten())
184349cc55cSDimitry Andric       resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
185349cc55cSDimitry Andric                       "S128-ni:1:10:20");
186fe6060f1SDimitry Andric     else
187349cc55cSDimitry Andric       resetDataLayout(
188349cc55cSDimitry Andric           "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
1890b57cec5SDimitry Andric   }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric protected:
1920b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
1930b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
1940b57cec5SDimitry Andric };
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
1970b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1980b57cec5SDimitry Andric public:
1990b57cec5SDimitry Andric   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
2000b57cec5SDimitry Andric                                    const TargetOptions &Opts)
2010b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
2020b57cec5SDimitry Andric     LongAlign = LongWidth = 64;
2030b57cec5SDimitry Andric     PointerAlign = PointerWidth = 64;
2040b57cec5SDimitry Andric     SizeType = UnsignedLong;
2050b57cec5SDimitry Andric     PtrDiffType = SignedLong;
2060b57cec5SDimitry Andric     IntPtrType = SignedLong;
207fe6060f1SDimitry Andric     if (T.isOSEmscripten())
208349cc55cSDimitry Andric       resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
209349cc55cSDimitry Andric                       "S128-ni:1:10:20");
210fe6060f1SDimitry Andric     else
211349cc55cSDimitry Andric       resetDataLayout(
212349cc55cSDimitry Andric           "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
2130b57cec5SDimitry Andric   }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric protected:
2160b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
2170b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
2180b57cec5SDimitry Andric };
2190b57cec5SDimitry Andric } // namespace targets
2200b57cec5SDimitry Andric } // namespace clang
2210b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
222