xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
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,
300b57cec5SDimitry Andric     UnimplementedSIMD128,
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;
41*5ffd83dbSDimitry Andric   bool HasReferenceTypes = false;
42*5ffd83dbSDimitry Andric 
43*5ffd83dbSDimitry Andric   std::string ABI;
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric public:
460b57cec5SDimitry Andric   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
470b57cec5SDimitry Andric       : TargetInfo(T) {
480b57cec5SDimitry Andric     NoAsmVariants = true;
490b57cec5SDimitry Andric     SuitableAlign = 128;
500b57cec5SDimitry Andric     LargeArrayMinWidth = 128;
510b57cec5SDimitry Andric     LargeArrayAlign = 128;
520b57cec5SDimitry Andric     SimdDefaultAlign = 128;
530b57cec5SDimitry Andric     SigAtomicType = SignedLong;
540b57cec5SDimitry Andric     LongDoubleWidth = LongDoubleAlign = 128;
550b57cec5SDimitry Andric     LongDoubleFormat = &llvm::APFloat::IEEEquad();
560b57cec5SDimitry Andric     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
570b57cec5SDimitry Andric     // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
580b57cec5SDimitry Andric     // more consistent between the two.
590b57cec5SDimitry Andric     SizeType = UnsignedLong;
600b57cec5SDimitry Andric     PtrDiffType = SignedLong;
610b57cec5SDimitry Andric     IntPtrType = SignedLong;
620b57cec5SDimitry Andric   }
630b57cec5SDimitry Andric 
64*5ffd83dbSDimitry Andric   StringRef getABI() const override;
65*5ffd83dbSDimitry Andric   bool setABI(const std::string &Name) override;
66*5ffd83dbSDimitry Andric 
670b57cec5SDimitry Andric protected:
680b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
690b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric private:
720b57cec5SDimitry Andric   static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level);
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   bool
750b57cec5SDimitry Andric   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
760b57cec5SDimitry Andric                  StringRef CPU,
770b57cec5SDimitry Andric                  const std::vector<std::string> &FeaturesVec) const override;
780b57cec5SDimitry Andric   bool hasFeature(StringRef Feature) const final;
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   bool handleTargetFeatures(std::vector<std::string> &Features,
810b57cec5SDimitry Andric                             DiagnosticsEngine &Diags) final;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   bool isValidCPUName(StringRef Name) const final;
840b57cec5SDimitry Andric   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   ArrayRef<Builtin::Info> getTargetBuiltins() const final;
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   BuiltinVaListKind getBuiltinVaListKind() const final {
910b57cec5SDimitry Andric     return VoidPtrBuiltinVaList;
920b57cec5SDimitry Andric   }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   ArrayRef<const char *> getGCCRegNames() const final { return None; }
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
970b57cec5SDimitry Andric     return None;
980b57cec5SDimitry Andric   }
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   bool validateAsmConstraint(const char *&Name,
1010b57cec5SDimitry Andric                              TargetInfo::ConstraintInfo &Info) const final {
1020b57cec5SDimitry Andric     return false;
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   const char *getClobbers() const final { return ""; }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   bool isCLZForZeroUndef() const final { return false; }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   bool hasInt128Type() const final { return true; }
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1120b57cec5SDimitry Andric     // WebAssembly prefers long long for explicitly 64-bit integers.
1130b57cec5SDimitry Andric     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1140b57cec5SDimitry Andric                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
1150b57cec5SDimitry Andric   }
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
1180b57cec5SDimitry Andric     // WebAssembly uses long long for int_least64_t and int_fast64_t.
1190b57cec5SDimitry Andric     return BitWidth == 64
1200b57cec5SDimitry Andric                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
1210b57cec5SDimitry Andric                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
1220b57cec5SDimitry Andric   }
123*5ffd83dbSDimitry Andric 
124*5ffd83dbSDimitry Andric   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
125*5ffd83dbSDimitry Andric     switch (CC) {
126*5ffd83dbSDimitry Andric     case CC_C:
127*5ffd83dbSDimitry Andric     case CC_Swift:
128*5ffd83dbSDimitry Andric       return CCCR_OK;
129*5ffd83dbSDimitry Andric     default:
130*5ffd83dbSDimitry Andric       return CCCR_Warning;
131*5ffd83dbSDimitry Andric     }
132*5ffd83dbSDimitry Andric   }
133*5ffd83dbSDimitry Andric 
134*5ffd83dbSDimitry Andric   bool hasExtIntType() const override { return true; }
135*5ffd83dbSDimitry Andric 
136*5ffd83dbSDimitry Andric   bool hasProtectedVisibility() const override { return false; }
1370b57cec5SDimitry Andric };
138*5ffd83dbSDimitry Andric 
1390b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
1400b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1410b57cec5SDimitry Andric public:
1420b57cec5SDimitry Andric   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
1430b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1440b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
1450b57cec5SDimitry Andric     resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128");
1460b57cec5SDimitry Andric   }
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric protected:
1490b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
1500b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
1510b57cec5SDimitry Andric };
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
1540b57cec5SDimitry Andric     : public WebAssemblyTargetInfo {
1550b57cec5SDimitry Andric public:
1560b57cec5SDimitry Andric   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
1570b57cec5SDimitry Andric                                    const TargetOptions &Opts)
1580b57cec5SDimitry Andric       : WebAssemblyTargetInfo(T, Opts) {
1590b57cec5SDimitry Andric     LongAlign = LongWidth = 64;
1600b57cec5SDimitry Andric     PointerAlign = PointerWidth = 64;
1610b57cec5SDimitry Andric     SizeType = UnsignedLong;
1620b57cec5SDimitry Andric     PtrDiffType = SignedLong;
1630b57cec5SDimitry Andric     IntPtrType = SignedLong;
1640b57cec5SDimitry Andric     resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128");
1650b57cec5SDimitry Andric   }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric protected:
1680b57cec5SDimitry Andric   void getTargetDefines(const LangOptions &Opts,
1690b57cec5SDimitry Andric                         MacroBuilder &Builder) const override;
1700b57cec5SDimitry Andric };
1710b57cec5SDimitry Andric } // namespace targets
1720b57cec5SDimitry Andric } // namespace clang
1730b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
174