Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_WASM_VALUE_TYPE_H_
6 : #define V8_WASM_VALUE_TYPE_H_
7 :
8 : #include "src/machine-type.h"
9 : #include "src/wasm/wasm-constants.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 : template <typename T>
15 : class Signature;
16 :
17 : namespace wasm {
18 :
19 : enum ValueType : uint8_t {
20 : kWasmStmt,
21 : kWasmI32,
22 : kWasmI64,
23 : kWasmF32,
24 : kWasmF64,
25 : kWasmS128,
26 : kWasmAnyRef,
27 : kWasmAnyFunc,
28 : kWasmExceptRef,
29 : kWasmVar,
30 : };
31 :
32 : using FunctionSig = Signature<ValueType>;
33 :
34 2468692 : inline size_t hash_value(ValueType type) { return static_cast<size_t>(type); }
35 :
36 : // TODO(clemensh): Compute memtype and size from ValueType once we have c++14
37 : // constexpr support.
38 : #define FOREACH_LOAD_TYPE(V) \
39 : V(I32, , Int32, 2) \
40 : V(I32, 8S, Int8, 0) \
41 : V(I32, 8U, Uint8, 0) \
42 : V(I32, 16S, Int16, 1) \
43 : V(I32, 16U, Uint16, 1) \
44 : V(I64, , Int64, 3) \
45 : V(I64, 8S, Int8, 0) \
46 : V(I64, 8U, Uint8, 0) \
47 : V(I64, 16S, Int16, 1) \
48 : V(I64, 16U, Uint16, 1) \
49 : V(I64, 32S, Int32, 2) \
50 : V(I64, 32U, Uint32, 2) \
51 : V(F32, , Float32, 2) \
52 : V(F64, , Float64, 3) \
53 : V(S128, , Simd128, 4)
54 :
55 : class LoadType {
56 : public:
57 : enum LoadTypeValue : uint8_t {
58 : #define DEF_ENUM(type, suffix, ...) k##type##Load##suffix,
59 : FOREACH_LOAD_TYPE(DEF_ENUM)
60 : #undef DEF_ENUM
61 : };
62 :
63 : // Allow implicit convertion of the enum value to this wrapper.
64 : constexpr LoadType(LoadTypeValue val) // NOLINT(runtime/explicit)
65 450891 : : val_(val) {}
66 :
67 238556 : constexpr LoadTypeValue value() const { return val_; }
68 421818 : constexpr unsigned size_log_2() const { return kLoadSizeLog2[val_]; }
69 104615 : constexpr unsigned size() const { return 1 << size_log_2(); }
70 620384 : constexpr ValueType value_type() const { return kValueType[val_]; }
71 198591 : constexpr MachineType mem_type() const { return kMemType[val_]; }
72 :
73 1272 : static LoadType ForValueType(ValueType type) {
74 1272 : switch (type) {
75 : case kWasmI32:
76 896 : return kI32Load;
77 : case kWasmI64:
78 68 : return kI64Load;
79 : case kWasmF32:
80 154 : return kF32Load;
81 : case kWasmF64:
82 154 : return kF64Load;
83 : default:
84 0 : UNREACHABLE();
85 : }
86 : }
87 :
88 : private:
89 : const LoadTypeValue val_;
90 :
91 : static constexpr uint8_t kLoadSizeLog2[] = {
92 : #define LOAD_SIZE(_, __, ___, size) size,
93 : FOREACH_LOAD_TYPE(LOAD_SIZE)
94 : #undef LOAD_SIZE
95 : };
96 :
97 : static constexpr ValueType kValueType[] = {
98 : #define VALUE_TYPE(type, ...) kWasm##type,
99 : FOREACH_LOAD_TYPE(VALUE_TYPE)
100 : #undef VALUE_TYPE
101 : };
102 :
103 : static constexpr MachineType kMemType[] = {
104 : #define MEMTYPE(_, __, memtype, ___) MachineType::memtype(),
105 : FOREACH_LOAD_TYPE(MEMTYPE)
106 : #undef MEMTYPE
107 : };
108 : };
109 :
110 : #define FOREACH_STORE_TYPE(V) \
111 : V(I32, , Word32, 2) \
112 : V(I32, 8, Word8, 0) \
113 : V(I32, 16, Word16, 1) \
114 : V(I64, , Word64, 3) \
115 : V(I64, 8, Word8, 0) \
116 : V(I64, 16, Word16, 1) \
117 : V(I64, 32, Word32, 2) \
118 : V(F32, , Float32, 2) \
119 : V(F64, , Float64, 3) \
120 : V(S128, , Simd128, 4)
121 :
122 : class StoreType {
123 : public:
124 : enum StoreTypeValue : uint8_t {
125 : #define DEF_ENUM(type, suffix, ...) k##type##Store##suffix,
126 : FOREACH_STORE_TYPE(DEF_ENUM)
127 : #undef DEF_ENUM
128 : };
129 :
130 : // Allow implicit convertion of the enum value to this wrapper.
131 : constexpr StoreType(StoreTypeValue val) // NOLINT(runtime/explicit)
132 404953 : : val_(val) {}
133 :
134 133868 : constexpr StoreTypeValue value() const { return val_; }
135 538827 : constexpr unsigned size_log_2() const { return kStoreSizeLog2[val_]; }
136 134077 : constexpr unsigned size() const { return 1 << size_log_2(); }
137 796752 : constexpr ValueType value_type() const { return kValueType[val_]; }
138 257947 : constexpr MachineRepresentation mem_rep() const { return kMemRep[val_]; }
139 :
140 479 : static StoreType ForValueType(ValueType type) {
141 479 : switch (type) {
142 : case kWasmI32:
143 283 : return kI32Store;
144 : case kWasmI64:
145 41 : return kI64Store;
146 : case kWasmF32:
147 73 : return kF32Store;
148 : case kWasmF64:
149 82 : return kF64Store;
150 : default:
151 0 : UNREACHABLE();
152 : }
153 : }
154 :
155 : private:
156 : const StoreTypeValue val_;
157 :
158 : static constexpr uint8_t kStoreSizeLog2[] = {
159 : #define STORE_SIZE(_, __, ___, size) size,
160 : FOREACH_STORE_TYPE(STORE_SIZE)
161 : #undef STORE_SIZE
162 : };
163 :
164 : static constexpr ValueType kValueType[] = {
165 : #define VALUE_TYPE(type, ...) kWasm##type,
166 : FOREACH_STORE_TYPE(VALUE_TYPE)
167 : #undef VALUE_TYPE
168 : };
169 :
170 : static constexpr MachineRepresentation kMemRep[] = {
171 : #define MEMREP(_, __, memrep, ___) MachineRepresentation::k##memrep,
172 : FOREACH_STORE_TYPE(MEMREP)
173 : #undef MEMREP
174 : };
175 : };
176 :
177 : // A collection of ValueType-related static methods.
178 : class V8_EXPORT_PRIVATE ValueTypes {
179 : public:
180 : static byte MemSize(MachineType type) {
181 1154110 : return 1 << i::ElementSizeLog2Of(type.representation());
182 : }
183 :
184 80771 : static int ElementSizeInBytes(ValueType type) {
185 80771 : switch (type) {
186 : case kWasmI32:
187 : case kWasmF32:
188 : return 4;
189 : case kWasmI64:
190 : case kWasmF64:
191 46536 : return 8;
192 : case kWasmS128:
193 0 : return 16;
194 : default:
195 0 : UNREACHABLE();
196 : }
197 : }
198 :
199 134762 : static int ElementSizeLog2Of(ValueType type) {
200 134762 : switch (type) {
201 : case kWasmI32:
202 : case kWasmF32:
203 : return 2;
204 : case kWasmI64:
205 : case kWasmF64:
206 9 : return 3;
207 : case kWasmS128:
208 0 : return 4;
209 : default:
210 0 : UNREACHABLE();
211 : }
212 : }
213 :
214 134744 : static byte MemSize(ValueType type) { return 1 << ElementSizeLog2Of(type); }
215 :
216 73160 : static ValueTypeCode ValueTypeCodeFor(ValueType type) {
217 73160 : switch (type) {
218 : case kWasmI32:
219 : return kLocalI32;
220 : case kWasmI64:
221 21249 : return kLocalI64;
222 : case kWasmF32:
223 1605 : return kLocalF32;
224 : case kWasmF64:
225 4487 : return kLocalF64;
226 : case kWasmS128:
227 3975 : return kLocalS128;
228 : case kWasmAnyRef:
229 29 : return kLocalAnyRef;
230 : case kWasmExceptRef:
231 1 : return kLocalExceptRef;
232 : case kWasmStmt:
233 15 : return kLocalVoid;
234 : default:
235 0 : UNREACHABLE();
236 : }
237 : }
238 :
239 1054954 : static MachineType MachineTypeFor(ValueType type) {
240 1054954 : switch (type) {
241 : case kWasmI32:
242 : return MachineType::Int32();
243 : case kWasmI64:
244 : return MachineType::Int64();
245 : case kWasmF32:
246 : return MachineType::Float32();
247 : case kWasmF64:
248 : return MachineType::Float64();
249 : case kWasmAnyFunc:
250 : case kWasmAnyRef:
251 : return MachineType::TaggedPointer();
252 : case kWasmS128:
253 : return MachineType::Simd128();
254 : case kWasmStmt:
255 : return MachineType::None();
256 : default:
257 0 : UNREACHABLE();
258 : }
259 : }
260 :
261 5519379 : static MachineRepresentation MachineRepresentationFor(ValueType type) {
262 5519379 : switch (type) {
263 : case kWasmI32:
264 : return MachineRepresentation::kWord32;
265 : case kWasmI64:
266 166785 : return MachineRepresentation::kWord64;
267 : case kWasmF32:
268 436616 : return MachineRepresentation::kFloat32;
269 : case kWasmF64:
270 689345 : return MachineRepresentation::kFloat64;
271 : case kWasmAnyRef:
272 : case kWasmAnyFunc:
273 : case kWasmExceptRef:
274 2757 : return MachineRepresentation::kTaggedPointer;
275 : case kWasmS128:
276 60 : return MachineRepresentation::kSimd128;
277 : case kWasmStmt:
278 0 : return MachineRepresentation::kNone;
279 : default:
280 0 : UNREACHABLE();
281 : }
282 : }
283 :
284 1446804 : static ValueType ValueTypeFor(MachineType type) {
285 1446804 : switch (type.representation()) {
286 : case MachineRepresentation::kWord8:
287 : case MachineRepresentation::kWord16:
288 : case MachineRepresentation::kWord32:
289 : return kWasmI32;
290 : case MachineRepresentation::kWord64:
291 : return kWasmI64;
292 : case MachineRepresentation::kFloat32:
293 : return kWasmF32;
294 : case MachineRepresentation::kFloat64:
295 : return kWasmF64;
296 : case MachineRepresentation::kTaggedPointer:
297 : return kWasmAnyRef;
298 : case MachineRepresentation::kSimd128:
299 : return kWasmS128;
300 : default:
301 0 : UNREACHABLE();
302 : }
303 : }
304 :
305 : static char ShortNameOf(ValueType type) {
306 : switch (type) {
307 : case kWasmI32:
308 : return 'i';
309 : case kWasmI64:
310 : return 'l';
311 : case kWasmF32:
312 : return 'f';
313 : case kWasmF64:
314 : return 'd';
315 : case kWasmAnyRef:
316 : return 'r';
317 : case kWasmAnyFunc:
318 : return 'a';
319 : case kWasmS128:
320 : return 's';
321 : case kWasmStmt:
322 : return 'v';
323 : case kWasmVar:
324 : return '*';
325 : default:
326 : return '?';
327 : }
328 : }
329 :
330 79942 : static const char* TypeName(ValueType type) {
331 79942 : switch (type) {
332 : case kWasmI32:
333 : return "i32";
334 : case kWasmI64:
335 17414 : return "i64";
336 : case kWasmF32:
337 16912 : return "f32";
338 : case kWasmF64:
339 14090 : return "f64";
340 : case kWasmAnyRef:
341 7212 : return "anyref";
342 : case kWasmAnyFunc:
343 18 : return "anyfunc";
344 : case kWasmExceptRef:
345 63 : return "exn";
346 : case kWasmS128:
347 18 : return "s128";
348 : case kWasmStmt:
349 596 : return "<stmt>";
350 : case kWasmVar:
351 0 : return "<var>";
352 : default:
353 0 : return "<unknown>";
354 : }
355 : }
356 :
357 : private:
358 : DISALLOW_IMPLICIT_CONSTRUCTORS(ValueTypes);
359 : };
360 :
361 : } // namespace wasm
362 : } // namespace internal
363 : } // namespace v8
364 :
365 : #endif // V8_WASM_VALUE_TYPE_H_
|