Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Basic/Targets/WebAssembly.h
Line
Count
Source (jump to first uncovered line)
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
    20, // wasm_funcref
46
};
47
48
class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
49
50
  enum SIMDEnum {
51
    NoSIMD,
52
    SIMD128,
53
    RelaxedSIMD,
54
  } SIMDLevel = NoSIMD;
55
56
  bool HasNontrappingFPToInt = false;
57
  bool HasSignExt = false;
58
  bool HasExceptionHandling = false;
59
  bool HasBulkMemory = false;
60
  bool HasAtomics = false;
61
  bool HasMutableGlobals = false;
62
  bool HasMultivalue = false;
63
  bool HasTailCall = false;
64
  bool HasReferenceTypes = false;
65
  bool HasExtendedConst = false;
66
  bool HasMultiMemory = false;
67
68
  std::string ABI;
69
70
public:
71
  explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
72
0
      : TargetInfo(T) {
73
0
    AddrSpaceMap = &WebAssemblyAddrSpaceMap;
74
0
    NoAsmVariants = true;
75
0
    SuitableAlign = 128;
76
0
    LargeArrayMinWidth = 128;
77
0
    LargeArrayAlign = 128;
78
0
    SigAtomicType = SignedLong;
79
0
    LongDoubleWidth = LongDoubleAlign = 128;
80
0
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
81
0
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
82
    // size_t being unsigned long for both wasm32 and wasm64 makes mangled names
83
    // more consistent between the two.
84
0
    SizeType = UnsignedLong;
85
0
    PtrDiffType = SignedLong;
86
0
    IntPtrType = SignedLong;
87
0
  }
88
89
  StringRef getABI() const override;
90
  bool setABI(const std::string &Name) override;
91
92
protected:
93
  void getTargetDefines(const LangOptions &Opts,
94
                        MacroBuilder &Builder) const override;
95
96
private:
97
  static void setSIMDLevel(llvm::StringMap<bool> &Features, SIMDEnum Level,
98
                           bool Enabled);
99
100
  bool
101
  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
102
                 StringRef CPU,
103
                 const std::vector<std::string> &FeaturesVec) const override;
104
  bool hasFeature(StringRef Feature) const final;
105
106
  void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
107
                         bool Enabled) const final;
108
109
  bool handleTargetFeatures(std::vector<std::string> &Features,
110
                            DiagnosticsEngine &Diags) final;
111
112
  bool isValidCPUName(StringRef Name) const final;
113
  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final;
114
115
0
  bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
116
117
  ArrayRef<Builtin::Info> getTargetBuiltins() const final;
118
119
0
  BuiltinVaListKind getBuiltinVaListKind() const final {
120
0
    return VoidPtrBuiltinVaList;
121
0
  }
122
123
0
  ArrayRef<const char *> getGCCRegNames() const final { return std::nullopt; }
124
125
0
  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
126
0
    return std::nullopt;
127
0
  }
128
129
  bool validateAsmConstraint(const char *&Name,
130
0
                             TargetInfo::ConstraintInfo &Info) const final {
131
0
    return false;
132
0
  }
133
134
0
  std::string_view getClobbers() const final { return ""; }
135
136
0
  bool isCLZForZeroUndef() const final { return false; }
137
138
0
  bool hasInt128Type() const final { return true; }
139
140
0
  IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
141
    // WebAssembly prefers long long for explicitly 64-bit integers.
142
0
    return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
143
0
                          : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
144
0
  }
145
146
0
  IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
147
    // WebAssembly uses long long for int_least64_t and int_fast64_t.
148
0
    return BitWidth == 64
149
0
               ? (IsSigned ? SignedLongLong : UnsignedLongLong)
150
0
               : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
151
0
  }
152
153
0
  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
154
0
    switch (CC) {
155
0
    case CC_C:
156
0
    case CC_Swift:
157
0
      return CCCR_OK;
158
0
    case CC_SwiftAsync:
159
0
      return CCCR_Error;
160
0
    default:
161
0
      return CCCR_Warning;
162
0
    }
163
0
  }
164
165
0
  bool hasBitIntType() const override { return true; }
166
167
0
  bool hasProtectedVisibility() const override { return false; }
168
169
  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
170
};
171
172
class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
173
    : public WebAssemblyTargetInfo {
174
public:
175
  explicit WebAssembly32TargetInfo(const llvm::Triple &T,
176
                                   const TargetOptions &Opts)
177
0
      : WebAssemblyTargetInfo(T, Opts) {
178
0
    if (T.isOSEmscripten())
179
0
      resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
180
0
                      "S128-ni:1:10:20");
181
0
    else
182
0
      resetDataLayout(
183
0
          "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
184
0
  }
185
186
protected:
187
  void getTargetDefines(const LangOptions &Opts,
188
                        MacroBuilder &Builder) const override;
189
};
190
191
class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
192
    : public WebAssemblyTargetInfo {
193
public:
194
  explicit WebAssembly64TargetInfo(const llvm::Triple &T,
195
                                   const TargetOptions &Opts)
196
0
      : WebAssemblyTargetInfo(T, Opts) {
197
0
    LongAlign = LongWidth = 64;
198
0
    PointerAlign = PointerWidth = 64;
199
0
    SizeType = UnsignedLong;
200
0
    PtrDiffType = SignedLong;
201
0
    IntPtrType = SignedLong;
202
0
    if (T.isOSEmscripten())
203
0
      resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
204
0
                      "S128-ni:1:10:20");
205
0
    else
206
0
      resetDataLayout(
207
0
          "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
208
0
  }
209
210
protected:
211
  void getTargetDefines(const LangOptions &Opts,
212
                        MacroBuilder &Builder) const override;
213
};
214
} // namespace targets
215
} // namespace clang
216
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_WEBASSEMBLY_H