xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //=== WebAssembly.h - Declare WebAssembly target feature support *- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares WebAssembly TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
15 
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Basic/TargetOptions.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/TargetParser/Triple.h"
20 
21 namespace clang {
22 namespace targets {
23 
24 static const unsigned WebAssemblyAddrSpaceMap[] = {
25     0,  // Default
26     0,  // opencl_global
27     0,  // opencl_local
28     0,  // opencl_constant
29     0,  // opencl_private
30     0,  // opencl_generic
31     0,  // opencl_global_device
32     0,  // opencl_global_host
33     0,  // cuda_device
34     0,  // cuda_constant
35     0,  // cuda_shared
36     0,  // sycl_global
37     0,  // sycl_global_device
38     0,  // sycl_global_host
39     0,  // sycl_local
40     0,  // sycl_private
41     0,  // ptr32_sptr
42     0,  // ptr32_uptr
43     0,  // ptr64
44     0,  // hlsl_groupshared
45     0,  // hlsl_constant
46     0,  // hlsl_private
47     0,  // hlsl_device
48     0,  // hlsl_input
49     20, // wasm_funcref
50 };
51 
52 class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
53 
54   enum SIMDEnum {
55     NoSIMD,
56     SIMD128,
57     RelaxedSIMD,
58   } SIMDLevel = NoSIMD;
59 
60   bool HasAtomics = false;
61   bool HasBulkMemory = false;
62   bool HasBulkMemoryOpt = false;
63   bool HasCallIndirectOverlong = false;
64   bool HasExceptionHandling = false;
65   bool HasExtendedConst = false;
66   bool HasFP16 = false;
67   bool HasMultiMemory = false;
68   bool HasMultivalue = false;
69   bool HasMutableGlobals = false;
70   bool HasNontrappingFPToInt = false;
71   bool HasReferenceTypes = false;
72   bool HasSignExt = false;
73   bool HasTailCall = false;
74   bool HasWideArithmetic = false;
75 
76   std::string ABI;
77 
78 public:
WebAssemblyTargetInfo(const llvm::Triple & T,const TargetOptions &)79   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
80       : TargetInfo(T) {
81     AddrSpaceMap = &WebAssemblyAddrSpaceMap;
82     NoAsmVariants = true;
83     SuitableAlign = 128;
84     LargeArrayMinWidth = 128;
85     LargeArrayAlign = 128;
86     SigAtomicType = SignedLong;
87     LongDoubleWidth = LongDoubleAlign = 128;
88     LongDoubleFormat = &llvm::APFloat::IEEEquad();
89     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
90     // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
91     // more consistent between the two.
92     SizeType = UnsignedLong;
93     PtrDiffType = SignedLong;
94     IntPtrType = SignedLong;
95     HasUnalignedAccess = true;
96   }
97 
98   StringRef getABI() const override;
99   bool setABI(const std::string &Name) override;
useFP16ConversionIntrinsics()100   bool useFP16ConversionIntrinsics() const override { return !HasFP16; }
101 
102 protected:
103   void getTargetDefines(const LangOptions &Opts,
104                         MacroBuilder &Builder) const override;
105 
106 private:
107   static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level,
108                            bool Enabled);
109 
110   bool
111   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
112                  StringRef CPU,
113                  const std::vector<std::string> &FeaturesVec) const override;
114   bool hasFeature(StringRef Feature) const final;
115 
116   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
117                          bool Enabled) const final;
118 
119   bool handleTargetFeatures(std::vector<std::string> &Features,
120                             DiagnosticsEngine &Diags) final;
121 
122   bool isValidCPUName(StringRef Name) const final;
123   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
124 
setCPU(const std::string & Name)125   bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
126 
127   llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const final;
128 
getBuiltinVaListKind()129   BuiltinVaListKind getBuiltinVaListKind() const final {
130     return VoidPtrBuiltinVaList;
131   }
132 
getGCCRegNames()133   ArrayRef<const char *> getGCCRegNames() const final { return {}; }
134 
getGCCRegAliases()135   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
136     return {};
137   }
138 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info)139   bool validateAsmConstraint(const char *&Name,
140                              TargetInfo::ConstraintInfo &Info) const final {
141     return false;
142   }
143 
getClobbers()144   std::string_view getClobbers() const final { return ""; }
145 
isCLZForZeroUndef()146   bool isCLZForZeroUndef() const final { return false; }
147 
hasInt128Type()148   bool hasInt128Type() const final { return true; }
149 
getIntTypeByWidth(unsigned BitWidth,bool IsSigned)150   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
151     // WebAssembly prefers long long for explicitly 64-bit integers.
152     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
153                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
154   }
155 
getLeastIntTypeByWidth(unsigned BitWidth,bool IsSigned)156   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
157     // WebAssembly uses long long for int_least64_t and int_fast64_t.
158     return BitWidth == 64
159                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
160                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
161   }
162 
checkCallingConvention(CallingConv CC)163   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
164     switch (CC) {
165     case CC_C:
166     case CC_Swift:
167       return CCCR_OK;
168     case CC_SwiftAsync:
169       return CCCR_Error;
170     default:
171       return CCCR_Warning;
172     }
173   }
174 
hasBitIntType()175   bool hasBitIntType() const override { return true; }
176 
hasProtectedVisibility()177   bool hasProtectedVisibility() const override { return false; }
178 
179   void adjust(DiagnosticsEngine &Diags, LangOptions &Opts,
180               const TargetInfo *Aux) override;
181 };
182 
183 class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
184     : public WebAssemblyTargetInfo {
185 public:
WebAssembly32TargetInfo(const llvm::Triple & T,const TargetOptions & Opts)186   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
187                                    const TargetOptions &Opts)
188       : WebAssemblyTargetInfo(T, Opts) {
189     if (T.isOSEmscripten())
190       resetDataLayout(
191           "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-"
192           "S128-ni:1:10:20");
193     else
194       resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-"
195                       "S128-ni:1:10:20");
196   }
197 
198 protected:
199   void getTargetDefines(const LangOptions &Opts,
200                         MacroBuilder &Builder) const override;
201 };
202 
203 class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
204     : public WebAssemblyTargetInfo {
205 public:
WebAssembly64TargetInfo(const llvm::Triple & T,const TargetOptions & Opts)206   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
207                                    const TargetOptions &Opts)
208       : WebAssemblyTargetInfo(T, Opts) {
209     LongAlign = LongWidth = 64;
210     PointerAlign = PointerWidth = 64;
211     SizeType = UnsignedLong;
212     PtrDiffType = SignedLong;
213     IntPtrType = SignedLong;
214     if (T.isOSEmscripten())
215       resetDataLayout(
216           "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-"
217           "S128-ni:1:10:20");
218     else
219       resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-"
220                       "S128-ni:1:10:20");
221   }
222 
223 protected:
224   void getTargetDefines(const LangOptions &Opts,
225                         MacroBuilder &Builder) const override;
226 };
227 } // namespace targets
228 } // namespace clang
229 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H
230