xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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 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;
66*5f757f3fSDimitry Andric   bool HasMultiMemory = false;
675ffd83dbSDimitry Andric 
685ffd83dbSDimitry Andric   std::string ABI;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric public:
710b57cec5SDimitry Andric   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
720b57cec5SDimitry Andric       : TargetInfo(T) {
7306c3fb27SDimitry Andric     AddrSpaceMap = &WebAssemblyAddrSpaceMap;
740b57cec5SDimitry Andric     NoAsmVariants = true;
750b57cec5SDimitry Andric     SuitableAlign = 128;
760b57cec5SDimitry Andric     LargeArrayMinWidth = 128;
770b57cec5SDimitry Andric     LargeArrayAlign = 128;
780b57cec5SDimitry Andric     SigAtomicType = SignedLong;
790b57cec5SDimitry Andric     LongDoubleWidth = LongDoubleAlign = 128;
800b57cec5SDimitry Andric     LongDoubleFormat = &llvm::APFloat::IEEEquad();
810b57cec5SDimitry Andric     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
820b57cec5SDimitry Andric     // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
830b57cec5SDimitry Andric     // more consistent between the two.
840b57cec5SDimitry Andric     SizeType = UnsignedLong;
850b57cec5SDimitry Andric     PtrDiffType = SignedLong;
860b57cec5SDimitry Andric     IntPtrType = SignedLong;
870b57cec5SDimitry Andric   }
880b57cec5SDimitry Andric 
895ffd83dbSDimitry Andric   StringRef getABI() const override;
905ffd83dbSDimitry Andric   bool setABI(const std::string &Name) override;
915ffd83dbSDimitry Andric 
920b57cec5SDimitry Andric protected:
930b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
940b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric private:
9775b4d546SDimitry Andric   static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level,
9875b4d546SDimitry Andric                            bool Enabled);
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   bool
1010b57cec5SDimitry Andric   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
1020b57cec5SDimitry Andric                  StringRef CPU,
1030b57cec5SDimitry Andric                  const std::vector<std::string> &FeaturesVec) const override;
1040b57cec5SDimitry Andric   bool hasFeature(StringRef Feature) const final;
1050b57cec5SDimitry Andric 
10675b4d546SDimitry Andric   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
10775b4d546SDimitry Andric                          bool Enabled) const final;
10875b4d546SDimitry Andric 
1090b57cec5SDimitry Andric   bool handleTargetFeatures(std::vector<std::string> &Features,
1100b57cec5SDimitry Andric                             DiagnosticsEngine &Diags) final;
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   bool isValidCPUName(StringRef Name) const final;
1130b57cec5SDimitry Andric   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   ArrayRef<Builtin::Info> getTargetBuiltins() const final;
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   BuiltinVaListKind getBuiltinVaListKind() const final {
1200b57cec5SDimitry Andric     return VoidPtrBuiltinVaList;
1210b57cec5SDimitry Andric   }
1220b57cec5SDimitry Andric 
123bdd1243dSDimitry Andric   ArrayRef<const char *> getGCCRegNames() const final { return std::nullopt; }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
126bdd1243dSDimitry Andric     return std::nullopt;
1270b57cec5SDimitry Andric   }
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric   bool validateAsmConstraint(const char *&Name,
1300b57cec5SDimitry Andric                              TargetInfo::ConstraintInfo &Info) const final {
1310b57cec5SDimitry Andric     return false;
1320b57cec5SDimitry Andric   }
1330b57cec5SDimitry Andric 
13406c3fb27SDimitry Andric   std::string_view getClobbers() const final { return ""; }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   bool isCLZForZeroUndef() const final { return false; }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   bool hasInt128Type() const final { return true; }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1410b57cec5SDimitry Andric     // WebAssembly prefers long long for explicitly 64-bit integers.
1420b57cec5SDimitry Andric     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1430b57cec5SDimitry Andric                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1470b57cec5SDimitry Andric     // WebAssembly uses long long for int_least64_t and int_fast64_t.
1480b57cec5SDimitry Andric     return BitWidth == 64
1490b57cec5SDimitry Andric                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1500b57cec5SDimitry Andric                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
1510b57cec5SDimitry Andric   }
1525ffd83dbSDimitry Andric 
1535ffd83dbSDimitry Andric   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
1545ffd83dbSDimitry Andric     switch (CC) {
1555ffd83dbSDimitry Andric     case CC_C:
1565ffd83dbSDimitry Andric     case CC_Swift:
1575ffd83dbSDimitry Andric       return CCCR_OK;
158fe6060f1SDimitry Andric     case CC_SwiftAsync:
159fe6060f1SDimitry Andric       return CCCR_Error;
1605ffd83dbSDimitry Andric     default:
1615ffd83dbSDimitry Andric       return CCCR_Warning;
1625ffd83dbSDimitry Andric     }
1635ffd83dbSDimitry Andric   }
1645ffd83dbSDimitry Andric 
1650eae32dcSDimitry Andric   bool hasBitIntType() const override { return true; }
1665ffd83dbSDimitry Andric 
1675ffd83dbSDimitry Andric   bool hasProtectedVisibility() const override { return false; }
168fe6060f1SDimitry Andric 
169fe6060f1SDimitry Andric   void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
1700b57cec5SDimitry Andric };
1715ffd83dbSDimitry Andric 
1720b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
1730b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1740b57cec5SDimitry Andric public:
1750b57cec5SDimitry Andric   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
1760b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1770b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
178fe6060f1SDimitry Andric     if (T.isOSEmscripten())
179349cc55cSDimitry Andric       resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
180349cc55cSDimitry Andric                       "S128-ni:1:10:20");
181fe6060f1SDimitry Andric     else
182349cc55cSDimitry Andric       resetDataLayout(
183349cc55cSDimitry Andric           "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
1840b57cec5SDimitry Andric   }
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric protected:
1870b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
1880b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
1890b57cec5SDimitry Andric };
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
1920b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1930b57cec5SDimitry Andric public:
1940b57cec5SDimitry Andric   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
1950b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1960b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
1970b57cec5SDimitry Andric     LongAlign = LongWidth = 64;
1980b57cec5SDimitry Andric     PointerAlign = PointerWidth = 64;
1990b57cec5SDimitry Andric     SizeType = UnsignedLong;
2000b57cec5SDimitry Andric     PtrDiffType = SignedLong;
2010b57cec5SDimitry Andric     IntPtrType = SignedLong;
202fe6060f1SDimitry Andric     if (T.isOSEmscripten())
203349cc55cSDimitry Andric       resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
204349cc55cSDimitry Andric                       "S128-ni:1:10:20");
205fe6060f1SDimitry Andric     else
206349cc55cSDimitry Andric       resetDataLayout(
207349cc55cSDimitry Andric           "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric protected:
2110b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
2120b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
2130b57cec5SDimitry Andric };
2140b57cec5SDimitry Andric } // namespace targets
2150b57cec5SDimitry Andric } // namespace clang
2160b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
217