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