xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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"
19*06c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace clang {
220b57cec5SDimitry Andric namespace targets {
230b57cec5SDimitry Andric 
24*06c3fb27SDimitry Andric static const unsigned WebAssemblyAddrSpaceMap[] = {
25*06c3fb27SDimitry Andric     0, // Default
26*06c3fb27SDimitry Andric     0, // opencl_global
27*06c3fb27SDimitry Andric     0, // opencl_local
28*06c3fb27SDimitry Andric     0, // opencl_constant
29*06c3fb27SDimitry Andric     0, // opencl_private
30*06c3fb27SDimitry Andric     0, // opencl_generic
31*06c3fb27SDimitry Andric     0, // opencl_global_device
32*06c3fb27SDimitry Andric     0, // opencl_global_host
33*06c3fb27SDimitry Andric     0, // cuda_device
34*06c3fb27SDimitry Andric     0, // cuda_constant
35*06c3fb27SDimitry Andric     0, // cuda_shared
36*06c3fb27SDimitry Andric     0, // sycl_global
37*06c3fb27SDimitry Andric     0, // sycl_global_device
38*06c3fb27SDimitry Andric     0, // sycl_global_host
39*06c3fb27SDimitry Andric     0, // sycl_local
40*06c3fb27SDimitry Andric     0, // sycl_private
41*06c3fb27SDimitry Andric     0, // ptr32_sptr
42*06c3fb27SDimitry Andric     0, // ptr32_uptr
43*06c3fb27SDimitry Andric     0, // ptr64
44*06c3fb27SDimitry Andric     0, // hlsl_groupshared
45*06c3fb27SDimitry Andric     20, // wasm_funcref
46*06c3fb27SDimitry Andric };
47*06c3fb27SDimitry 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 HasNontrappingFPToInt = false;
570b57cec5SDimitry Andric   bool HasSignExt = false;
580b57cec5SDimitry Andric   bool HasExceptionHandling = false;
590b57cec5SDimitry Andric   bool HasBulkMemory = false;
600b57cec5SDimitry Andric   bool HasAtomics = false;
610b57cec5SDimitry Andric   bool HasMutableGlobals = false;
620b57cec5SDimitry Andric   bool HasMultivalue = false;
630b57cec5SDimitry Andric   bool HasTailCall = false;
645ffd83dbSDimitry Andric   bool HasReferenceTypes = false;
6581ad6265SDimitry Andric   bool HasExtendedConst = false;
665ffd83dbSDimitry Andric 
675ffd83dbSDimitry Andric   std::string ABI;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric public:
700b57cec5SDimitry Andric   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
710b57cec5SDimitry Andric       : TargetInfo(T) {
72*06c3fb27SDimitry Andric     AddrSpaceMap = &WebAssemblyAddrSpaceMap;
730b57cec5SDimitry Andric     NoAsmVariants = true;
740b57cec5SDimitry Andric     SuitableAlign = 128;
750b57cec5SDimitry Andric     LargeArrayMinWidth = 128;
760b57cec5SDimitry Andric     LargeArrayAlign = 128;
770b57cec5SDimitry Andric     SigAtomicType = SignedLong;
780b57cec5SDimitry Andric     LongDoubleWidth = LongDoubleAlign = 128;
790b57cec5SDimitry Andric     LongDoubleFormat = &llvm::APFloat::IEEEquad();
800b57cec5SDimitry Andric     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
810b57cec5SDimitry Andric     // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
820b57cec5SDimitry Andric     // more consistent between the two.
830b57cec5SDimitry Andric     SizeType = UnsignedLong;
840b57cec5SDimitry Andric     PtrDiffType = SignedLong;
850b57cec5SDimitry Andric     IntPtrType = SignedLong;
860b57cec5SDimitry Andric   }
870b57cec5SDimitry Andric 
885ffd83dbSDimitry Andric   StringRef getABI() const override;
895ffd83dbSDimitry Andric   bool setABI(const std::string &Name) override;
905ffd83dbSDimitry Andric 
910b57cec5SDimitry Andric protected:
920b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
930b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric private:
9675b4d546SDimitry Andric   static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level,
9775b4d546SDimitry Andric                            bool Enabled);
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   bool
1000b57cec5SDimitry Andric   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
1010b57cec5SDimitry Andric                  StringRef CPU,
1020b57cec5SDimitry Andric                  const std::vector<std::string> &FeaturesVec) const override;
1030b57cec5SDimitry Andric   bool hasFeature(StringRef Feature) const final;
1040b57cec5SDimitry Andric 
10575b4d546SDimitry Andric   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
10675b4d546SDimitry Andric                          bool Enabled) const final;
10775b4d546SDimitry Andric 
1080b57cec5SDimitry Andric   bool handleTargetFeatures(std::vector<std::string> &Features,
1090b57cec5SDimitry Andric                             DiagnosticsEngine &Diags) final;
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   bool isValidCPUName(StringRef Name) const final;
1120b57cec5SDimitry Andric   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   ArrayRef<Builtin::Info> getTargetBuiltins() const final;
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   BuiltinVaListKind getBuiltinVaListKind() const final {
1190b57cec5SDimitry Andric     return VoidPtrBuiltinVaList;
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric 
122bdd1243dSDimitry Andric   ArrayRef<const char *> getGCCRegNames() const final { return std::nullopt; }
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
125bdd1243dSDimitry Andric     return std::nullopt;
1260b57cec5SDimitry Andric   }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   bool validateAsmConstraint(const char *&Name,
1290b57cec5SDimitry Andric                              TargetInfo::ConstraintInfo &Info) const final {
1300b57cec5SDimitry Andric     return false;
1310b57cec5SDimitry Andric   }
1320b57cec5SDimitry Andric 
133*06c3fb27SDimitry Andric   std::string_view getClobbers() const final { return ""; }
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   bool isCLZForZeroUndef() const final { return false; }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   bool hasInt128Type() const final { return true; }
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1400b57cec5SDimitry Andric     // WebAssembly prefers long long for explicitly 64-bit integers.
1410b57cec5SDimitry Andric     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1420b57cec5SDimitry Andric                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
1430b57cec5SDimitry Andric   }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1460b57cec5SDimitry Andric     // WebAssembly uses long long for int_least64_t and int_fast64_t.
1470b57cec5SDimitry Andric     return BitWidth == 64
1480b57cec5SDimitry Andric                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1490b57cec5SDimitry Andric                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
1500b57cec5SDimitry Andric   }
1515ffd83dbSDimitry Andric 
1525ffd83dbSDimitry Andric   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
1535ffd83dbSDimitry Andric     switch (CC) {
1545ffd83dbSDimitry Andric     case CC_C:
1555ffd83dbSDimitry Andric     case CC_Swift:
1565ffd83dbSDimitry Andric       return CCCR_OK;
157fe6060f1SDimitry Andric     case CC_SwiftAsync:
158fe6060f1SDimitry Andric       return CCCR_Error;
1595ffd83dbSDimitry Andric     default:
1605ffd83dbSDimitry Andric       return CCCR_Warning;
1615ffd83dbSDimitry Andric     }
1625ffd83dbSDimitry Andric   }
1635ffd83dbSDimitry Andric 
1640eae32dcSDimitry Andric   bool hasBitIntType() const override { return true; }
1655ffd83dbSDimitry Andric 
1665ffd83dbSDimitry Andric   bool hasProtectedVisibility() const override { return false; }
167fe6060f1SDimitry Andric 
168fe6060f1SDimitry Andric   void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
1690b57cec5SDimitry Andric };
1705ffd83dbSDimitry Andric 
1710b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
1720b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1730b57cec5SDimitry Andric public:
1740b57cec5SDimitry Andric   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
1750b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1760b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
177fe6060f1SDimitry Andric     if (T.isOSEmscripten())
178349cc55cSDimitry Andric       resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
179349cc55cSDimitry Andric                       "S128-ni:1:10:20");
180fe6060f1SDimitry Andric     else
181349cc55cSDimitry Andric       resetDataLayout(
182349cc55cSDimitry Andric           "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
1830b57cec5SDimitry Andric   }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric protected:
1860b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
1870b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
1880b57cec5SDimitry Andric };
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
1910b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1920b57cec5SDimitry Andric public:
1930b57cec5SDimitry Andric   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
1940b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1950b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
1960b57cec5SDimitry Andric     LongAlign = LongWidth = 64;
1970b57cec5SDimitry Andric     PointerAlign = PointerWidth = 64;
1980b57cec5SDimitry Andric     SizeType = UnsignedLong;
1990b57cec5SDimitry Andric     PtrDiffType = SignedLong;
2000b57cec5SDimitry Andric     IntPtrType = SignedLong;
201fe6060f1SDimitry Andric     if (T.isOSEmscripten())
202349cc55cSDimitry Andric       resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
203349cc55cSDimitry Andric                       "S128-ni:1:10:20");
204fe6060f1SDimitry Andric     else
205349cc55cSDimitry Andric       resetDataLayout(
206349cc55cSDimitry Andric           "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
2070b57cec5SDimitry Andric   }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric protected:
2100b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
2110b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
2120b57cec5SDimitry Andric };
2130b57cec5SDimitry Andric } // namespace targets
2140b57cec5SDimitry Andric } // namespace clang
2150b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
216