xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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/ADT/Triple.h"
190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace clang {
220b57cec5SDimitry Andric namespace targets {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
250b57cec5SDimitry Andric   static const Builtin::Info BuiltinInfo[];
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric   enum SIMDEnum {
280b57cec5SDimitry Andric     NoSIMD,
290b57cec5SDimitry Andric     SIMD128,
30349cc55cSDimitry Andric     RelaxedSIMD,
310b57cec5SDimitry Andric   } SIMDLevel = NoSIMD;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   bool HasNontrappingFPToInt = false;
340b57cec5SDimitry Andric   bool HasSignExt = false;
350b57cec5SDimitry Andric   bool HasExceptionHandling = false;
360b57cec5SDimitry Andric   bool HasBulkMemory = false;
370b57cec5SDimitry Andric   bool HasAtomics = false;
380b57cec5SDimitry Andric   bool HasMutableGlobals = false;
390b57cec5SDimitry Andric   bool HasMultivalue = false;
400b57cec5SDimitry Andric   bool HasTailCall = false;
415ffd83dbSDimitry Andric   bool HasReferenceTypes = false;
42*81ad6265SDimitry Andric   bool HasExtendedConst = false;
435ffd83dbSDimitry Andric 
445ffd83dbSDimitry Andric   std::string ABI;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric public:
470b57cec5SDimitry Andric   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
480b57cec5SDimitry Andric       : TargetInfo(T) {
490b57cec5SDimitry Andric     NoAsmVariants = true;
500b57cec5SDimitry Andric     SuitableAlign = 128;
510b57cec5SDimitry Andric     LargeArrayMinWidth = 128;
520b57cec5SDimitry Andric     LargeArrayAlign = 128;
530b57cec5SDimitry Andric     SimdDefaultAlign = 128;
540b57cec5SDimitry Andric     SigAtomicType = SignedLong;
550b57cec5SDimitry Andric     LongDoubleWidth = LongDoubleAlign = 128;
560b57cec5SDimitry Andric     LongDoubleFormat = &llvm::APFloat::IEEEquad();
570b57cec5SDimitry Andric     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
580b57cec5SDimitry Andric     // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
590b57cec5SDimitry Andric     // more consistent between the two.
600b57cec5SDimitry Andric     SizeType = UnsignedLong;
610b57cec5SDimitry Andric     PtrDiffType = SignedLong;
620b57cec5SDimitry Andric     IntPtrType = SignedLong;
630b57cec5SDimitry Andric   }
640b57cec5SDimitry Andric 
655ffd83dbSDimitry Andric   StringRef getABI() const override;
665ffd83dbSDimitry Andric   bool setABI(const std::string &Name) override;
675ffd83dbSDimitry Andric 
680b57cec5SDimitry Andric protected:
690b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
700b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric private:
7375b4d546SDimitry Andric   static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level,
7475b4d546SDimitry Andric                            bool Enabled);
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   bool
770b57cec5SDimitry Andric   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
780b57cec5SDimitry Andric                  StringRef CPU,
790b57cec5SDimitry Andric                  const std::vector<std::string> &FeaturesVec) const override;
800b57cec5SDimitry Andric   bool hasFeature(StringRef Feature) const final;
810b57cec5SDimitry Andric 
8275b4d546SDimitry Andric   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
8375b4d546SDimitry Andric                          bool Enabled) const final;
8475b4d546SDimitry Andric 
850b57cec5SDimitry Andric   bool handleTargetFeatures(std::vector<std::string> &Features,
860b57cec5SDimitry Andric                             DiagnosticsEngine &Diags) final;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   bool isValidCPUName(StringRef Name) const final;
890b57cec5SDimitry Andric   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   ArrayRef<Builtin::Info> getTargetBuiltins() const final;
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   BuiltinVaListKind getBuiltinVaListKind() const final {
960b57cec5SDimitry Andric     return VoidPtrBuiltinVaList;
970b57cec5SDimitry Andric   }
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   ArrayRef<const char *> getGCCRegNames() const final { return None; }
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
1020b57cec5SDimitry Andric     return None;
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   bool validateAsmConstraint(const char *&Name,
1060b57cec5SDimitry Andric                              TargetInfo::ConstraintInfo &Info) const final {
1070b57cec5SDimitry Andric     return false;
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   const char *getClobbers() const final { return ""; }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   bool isCLZForZeroUndef() const final { return false; }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   bool hasInt128Type() const final { return true; }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1170b57cec5SDimitry Andric     // WebAssembly prefers long long for explicitly 64-bit integers.
1180b57cec5SDimitry Andric     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1190b57cec5SDimitry Andric                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1230b57cec5SDimitry Andric     // WebAssembly uses long long for int_least64_t and int_fast64_t.
1240b57cec5SDimitry Andric     return BitWidth == 64
1250b57cec5SDimitry Andric                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1260b57cec5SDimitry Andric                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
1270b57cec5SDimitry Andric   }
1285ffd83dbSDimitry Andric 
1295ffd83dbSDimitry Andric   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
1305ffd83dbSDimitry Andric     switch (CC) {
1315ffd83dbSDimitry Andric     case CC_C:
1325ffd83dbSDimitry Andric     case CC_Swift:
1335ffd83dbSDimitry Andric       return CCCR_OK;
134fe6060f1SDimitry Andric     case CC_SwiftAsync:
135fe6060f1SDimitry Andric       return CCCR_Error;
1365ffd83dbSDimitry Andric     default:
1375ffd83dbSDimitry Andric       return CCCR_Warning;
1385ffd83dbSDimitry Andric     }
1395ffd83dbSDimitry Andric   }
1405ffd83dbSDimitry Andric 
1410eae32dcSDimitry Andric   bool hasBitIntType() const override { return true; }
1425ffd83dbSDimitry Andric 
1435ffd83dbSDimitry Andric   bool hasProtectedVisibility() const override { return false; }
144fe6060f1SDimitry Andric 
145fe6060f1SDimitry Andric   void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
1460b57cec5SDimitry Andric };
1475ffd83dbSDimitry Andric 
1480b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
1490b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1500b57cec5SDimitry Andric public:
1510b57cec5SDimitry Andric   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
1520b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1530b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
154fe6060f1SDimitry Andric     if (T.isOSEmscripten())
155349cc55cSDimitry Andric       resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
156349cc55cSDimitry Andric                       "S128-ni:1:10:20");
157fe6060f1SDimitry Andric     else
158349cc55cSDimitry Andric       resetDataLayout(
159349cc55cSDimitry Andric           "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
1600b57cec5SDimitry Andric   }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric protected:
1630b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
1640b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
1650b57cec5SDimitry Andric };
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
1680b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1690b57cec5SDimitry Andric public:
1700b57cec5SDimitry Andric   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
1710b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1720b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
1730b57cec5SDimitry Andric     LongAlign = LongWidth = 64;
1740b57cec5SDimitry Andric     PointerAlign = PointerWidth = 64;
1750b57cec5SDimitry Andric     SizeType = UnsignedLong;
1760b57cec5SDimitry Andric     PtrDiffType = SignedLong;
1770b57cec5SDimitry Andric     IntPtrType = SignedLong;
178fe6060f1SDimitry Andric     if (T.isOSEmscripten())
179349cc55cSDimitry Andric       resetDataLayout("e-m:e-p:64:64-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:64:64-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 } // namespace targets
1910b57cec5SDimitry Andric } // namespace clang
1920b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
193