1*0b57cec5SDimitry Andric //=== WebAssembly.h - Declare WebAssembly target feature support *- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file declares WebAssembly TargetInfo objects. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H 14*0b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 17*0b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 19*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric namespace clang { 22*0b57cec5SDimitry Andric namespace targets { 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { 25*0b57cec5SDimitry Andric static const Builtin::Info BuiltinInfo[]; 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric enum SIMDEnum { 28*0b57cec5SDimitry Andric NoSIMD, 29*0b57cec5SDimitry Andric SIMD128, 30*0b57cec5SDimitry Andric UnimplementedSIMD128, 31*0b57cec5SDimitry Andric } SIMDLevel = NoSIMD; 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric bool HasNontrappingFPToInt = false; 34*0b57cec5SDimitry Andric bool HasSignExt = false; 35*0b57cec5SDimitry Andric bool HasExceptionHandling = false; 36*0b57cec5SDimitry Andric bool HasBulkMemory = false; 37*0b57cec5SDimitry Andric bool HasAtomics = false; 38*0b57cec5SDimitry Andric bool HasMutableGlobals = false; 39*0b57cec5SDimitry Andric bool HasMultivalue = false; 40*0b57cec5SDimitry Andric bool HasTailCall = false; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric public: 43*0b57cec5SDimitry Andric explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &) 44*0b57cec5SDimitry Andric : TargetInfo(T) { 45*0b57cec5SDimitry Andric NoAsmVariants = true; 46*0b57cec5SDimitry Andric SuitableAlign = 128; 47*0b57cec5SDimitry Andric LargeArrayMinWidth = 128; 48*0b57cec5SDimitry Andric LargeArrayAlign = 128; 49*0b57cec5SDimitry Andric SimdDefaultAlign = 128; 50*0b57cec5SDimitry Andric SigAtomicType = SignedLong; 51*0b57cec5SDimitry Andric LongDoubleWidth = LongDoubleAlign = 128; 52*0b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEquad(); 53*0b57cec5SDimitry Andric MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 54*0b57cec5SDimitry Andric // size_t being unsigned long for both wasm32 and wasm64 makes mangled names 55*0b57cec5SDimitry Andric // more consistent between the two. 56*0b57cec5SDimitry Andric SizeType = UnsignedLong; 57*0b57cec5SDimitry Andric PtrDiffType = SignedLong; 58*0b57cec5SDimitry Andric IntPtrType = SignedLong; 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric protected: 62*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 63*0b57cec5SDimitry Andric MacroBuilder &Builder) const override; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric private: 66*0b57cec5SDimitry Andric static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level); 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric bool 69*0b57cec5SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 70*0b57cec5SDimitry Andric StringRef CPU, 71*0b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const override; 72*0b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const final; 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 75*0b57cec5SDimitry Andric DiagnosticsEngine &Diags) final; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric bool isValidCPUName(StringRef Name) const final; 78*0b57cec5SDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final; 79*0b57cec5SDimitry Andric 80*0b57cec5SDimitry Andric bool setCPU(const std::string &Name) final { return isValidCPUName(Name); } 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const final; 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const final { 85*0b57cec5SDimitry Andric return VoidPtrBuiltinVaList; 86*0b57cec5SDimitry Andric } 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const final { return None; } 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final { 91*0b57cec5SDimitry Andric return None; 92*0b57cec5SDimitry Andric } 93*0b57cec5SDimitry Andric 94*0b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 95*0b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info) const final { 96*0b57cec5SDimitry Andric return false; 97*0b57cec5SDimitry Andric } 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric const char *getClobbers() const final { return ""; } 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric bool isCLZForZeroUndef() const final { return false; } 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric bool hasInt128Type() const final { return true; } 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final { 106*0b57cec5SDimitry Andric // WebAssembly prefers long long for explicitly 64-bit integers. 107*0b57cec5SDimitry Andric return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong) 108*0b57cec5SDimitry Andric : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned); 109*0b57cec5SDimitry Andric } 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final { 112*0b57cec5SDimitry Andric // WebAssembly uses long long for int_least64_t and int_fast64_t. 113*0b57cec5SDimitry Andric return BitWidth == 64 114*0b57cec5SDimitry Andric ? (IsSigned ? SignedLongLong : UnsignedLongLong) 115*0b57cec5SDimitry Andric : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); 116*0b57cec5SDimitry Andric } 117*0b57cec5SDimitry Andric }; 118*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo 119*0b57cec5SDimitry Andric : public WebAssemblyTargetInfo { 120*0b57cec5SDimitry Andric public: 121*0b57cec5SDimitry Andric explicit WebAssembly32TargetInfo(const llvm::Triple &T, 122*0b57cec5SDimitry Andric const TargetOptions &Opts) 123*0b57cec5SDimitry Andric : WebAssemblyTargetInfo(T, Opts) { 124*0b57cec5SDimitry Andric resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128"); 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric protected: 128*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 129*0b57cec5SDimitry Andric MacroBuilder &Builder) const override; 130*0b57cec5SDimitry Andric }; 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo 133*0b57cec5SDimitry Andric : public WebAssemblyTargetInfo { 134*0b57cec5SDimitry Andric public: 135*0b57cec5SDimitry Andric explicit WebAssembly64TargetInfo(const llvm::Triple &T, 136*0b57cec5SDimitry Andric const TargetOptions &Opts) 137*0b57cec5SDimitry Andric : WebAssemblyTargetInfo(T, Opts) { 138*0b57cec5SDimitry Andric LongAlign = LongWidth = 64; 139*0b57cec5SDimitry Andric PointerAlign = PointerWidth = 64; 140*0b57cec5SDimitry Andric SizeType = UnsignedLong; 141*0b57cec5SDimitry Andric PtrDiffType = SignedLong; 142*0b57cec5SDimitry Andric IntPtrType = SignedLong; 143*0b57cec5SDimitry Andric resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); 144*0b57cec5SDimitry Andric } 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric protected: 147*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 148*0b57cec5SDimitry Andric MacroBuilder &Builder) const override; 149*0b57cec5SDimitry Andric }; 150*0b57cec5SDimitry Andric } // namespace targets 151*0b57cec5SDimitry Andric } // namespace clang 152*0b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H 153