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