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