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 : kWasmNullRef,
29 : kWasmExceptRef,
30 : kWasmVar,
31 : };
32 :
33 : using FunctionSig = Signature<ValueType>;
34 :
35 2211975 : inline size_t hash_value(ValueType type) { return static_cast<size_t>(type); }
36 :
37 : // TODO(clemensh): Compute memtype and size from ValueType once we have c++14
38 : // constexpr support.
39 : #define FOREACH_LOAD_TYPE(V) \
40 : V(I32, , Int32, 2) \
41 : V(I32, 8S, Int8, 0) \
42 : V(I32, 8U, Uint8, 0) \
43 : V(I32, 16S, Int16, 1) \
44 : V(I32, 16U, Uint16, 1) \
45 : V(I64, , Int64, 3) \
46 : V(I64, 8S, Int8, 0) \
47 : V(I64, 8U, Uint8, 0) \
48 : V(I64, 16S, Int16, 1) \
49 : V(I64, 16U, Uint16, 1) \
50 : V(I64, 32S, Int32, 2) \
51 : V(I64, 32U, Uint32, 2) \
52 : V(F32, , Float32, 2) \
53 : V(F64, , Float64, 3) \
54 : V(S128, , Simd128, 4)
55 :
56 : class LoadType {
57 : public:
58 : enum LoadTypeValue : uint8_t {
59 : #define DEF_ENUM(type, suffix, ...) k##type##Load##suffix,
60 : FOREACH_LOAD_TYPE(DEF_ENUM)
61 : #undef DEF_ENUM
62 : };
63 :
64 : // Allow implicit convertion of the enum value to this wrapper.
65 : constexpr LoadType(LoadTypeValue val) // NOLINT(runtime/explicit)
66 311184 : : val_(val) {}
67 :
68 204207 : constexpr LoadTypeValue value() const { return val_; }
69 277958 : constexpr unsigned size_log_2() const { return kLoadSizeLog2[val_]; }
70 85390 : constexpr unsigned size() const { return 1 << size_log_2(); }
71 372225 : constexpr ValueType value_type() const { return kValueType[val_]; }
72 94288 : constexpr MachineType mem_type() const { return kMemType[val_]; }
73 :
74 1111 : static LoadType ForValueType(ValueType type) {
75 1111 : switch (type) {
76 : case kWasmI32:
77 787 : return kI32Load;
78 : case kWasmI64:
79 60 : return kI64Load;
80 : case kWasmF32:
81 132 : return kF32Load;
82 : case kWasmF64:
83 132 : return kF64Load;
84 : default:
85 0 : UNREACHABLE();
86 : }
87 : }
88 :
89 : private:
90 : const LoadTypeValue val_;
91 :
92 : static constexpr uint8_t kLoadSizeLog2[] = {
93 : #define LOAD_SIZE(_, __, ___, size) size,
94 : FOREACH_LOAD_TYPE(LOAD_SIZE)
95 : #undef LOAD_SIZE
96 : };
97 :
98 : static constexpr ValueType kValueType[] = {
99 : #define VALUE_TYPE(type, ...) kWasm##type,
100 : FOREACH_LOAD_TYPE(VALUE_TYPE)
101 : #undef VALUE_TYPE
102 : };
103 :
104 : static constexpr MachineType kMemType[] = {
105 : #define MEMTYPE(_, __, memtype, ___) MachineType::memtype(),
106 : FOREACH_LOAD_TYPE(MEMTYPE)
107 : #undef MEMTYPE
108 : };
109 : };
110 :
111 : #define FOREACH_STORE_TYPE(V) \
112 : V(I32, , Word32, 2) \
113 : V(I32, 8, Word8, 0) \
114 : V(I32, 16, Word16, 1) \
115 : V(I64, , Word64, 3) \
116 : V(I64, 8, Word8, 0) \
117 : V(I64, 16, Word16, 1) \
118 : V(I64, 32, Word32, 2) \
119 : V(F32, , Float32, 2) \
120 : V(F64, , Float64, 3) \
121 : V(S128, , Simd128, 4)
122 :
123 : class StoreType {
124 : public:
125 : enum StoreTypeValue : uint8_t {
126 : #define DEF_ENUM(type, suffix, ...) k##type##Store##suffix,
127 : FOREACH_STORE_TYPE(DEF_ENUM)
128 : #undef DEF_ENUM
129 : };
130 :
131 : // Allow implicit convertion of the enum value to this wrapper.
132 : constexpr StoreType(StoreTypeValue val) // NOLINT(runtime/explicit)
133 269844 : : val_(val) {}
134 :
135 113430 : constexpr StoreTypeValue value() const { return val_; }
136 383300 : constexpr unsigned size_log_2() const { return kStoreSizeLog2[val_]; }
137 113614 : constexpr unsigned size() const { return 1 << size_log_2(); }
138 527470 : constexpr ValueType value_type() const { return kValueType[val_]; }
139 144165 : constexpr MachineRepresentation mem_rep() const { return kMemRep[val_]; }
140 :
141 420 : static StoreType ForValueType(ValueType type) {
142 420 : switch (type) {
143 : case kWasmI32:
144 248 : return kI32Store;
145 : case kWasmI64:
146 36 : return kI64Store;
147 : case kWasmF32:
148 64 : return kF32Store;
149 : case kWasmF64:
150 72 : return kF64Store;
151 : default:
152 0 : UNREACHABLE();
153 : }
154 : }
155 :
156 : private:
157 : const StoreTypeValue val_;
158 :
159 : static constexpr uint8_t kStoreSizeLog2[] = {
160 : #define STORE_SIZE(_, __, ___, size) size,
161 : FOREACH_STORE_TYPE(STORE_SIZE)
162 : #undef STORE_SIZE
163 : };
164 :
165 : static constexpr ValueType kValueType[] = {
166 : #define VALUE_TYPE(type, ...) kWasm##type,
167 : FOREACH_STORE_TYPE(VALUE_TYPE)
168 : #undef VALUE_TYPE
169 : };
170 :
171 : static constexpr MachineRepresentation kMemRep[] = {
172 : #define MEMREP(_, __, memrep, ___) MachineRepresentation::k##memrep,
173 : FOREACH_STORE_TYPE(MEMREP)
174 : #undef MEMREP
175 : };
176 : };
177 :
178 : // A collection of ValueType-related static methods.
179 : class V8_EXPORT_PRIVATE ValueTypes {
180 : public:
181 : static byte MemSize(MachineType type) {
182 1039927 : return 1 << i::ElementSizeLog2Of(type.representation());
183 : }
184 :
185 114228 : static int ElementSizeInBytes(ValueType type) {
186 114228 : switch (type) {
187 : case kWasmI32:
188 : case kWasmF32:
189 : return 4;
190 : case kWasmI64:
191 : case kWasmF64:
192 83728 : return 8;
193 : case kWasmS128:
194 0 : return 16;
195 : default:
196 0 : UNREACHABLE();
197 : }
198 : }
199 :
200 107824 : static int ElementSizeLog2Of(ValueType type) {
201 107824 : switch (type) {
202 : case kWasmI32:
203 : case kWasmF32:
204 : return 2;
205 : case kWasmI64:
206 : case kWasmF64:
207 8 : return 3;
208 : case kWasmS128:
209 0 : return 4;
210 : default:
211 0 : UNREACHABLE();
212 : }
213 : }
214 :
215 107808 : static byte MemSize(ValueType type) { return 1 << ElementSizeLog2Of(type); }
216 :
217 59926 : static ValueTypeCode ValueTypeCodeFor(ValueType type) {
218 59926 : switch (type) {
219 : case kWasmI32:
220 : return kLocalI32;
221 : case kWasmI64:
222 17011 : return kLocalI64;
223 : case kWasmF32:
224 1314 : return kLocalF32;
225 : case kWasmF64:
226 3792 : return kLocalF64;
227 : case kWasmS128:
228 3180 : return kLocalS128;
229 : case kWasmAnyRef:
230 29 : return kLocalAnyRef;
231 : case kWasmExceptRef:
232 1 : return kLocalExceptRef;
233 : case kWasmStmt:
234 12 : return kLocalVoid;
235 : default:
236 0 : UNREACHABLE();
237 : }
238 : }
239 :
240 1007417 : static MachineType MachineTypeFor(ValueType type) {
241 1007417 : switch (type) {
242 : case kWasmI32:
243 : return MachineType::Int32();
244 : case kWasmI64:
245 : return MachineType::Int64();
246 : case kWasmF32:
247 : return MachineType::Float32();
248 : case kWasmF64:
249 : return MachineType::Float64();
250 : case kWasmAnyFunc:
251 : case kWasmAnyRef:
252 : return MachineType::TaggedPointer();
253 : case kWasmS128:
254 : return MachineType::Simd128();
255 : case kWasmStmt:
256 : return MachineType::None();
257 : default:
258 0 : UNREACHABLE();
259 : }
260 : }
261 :
262 4241067 : static MachineRepresentation MachineRepresentationFor(ValueType type) {
263 4241067 : switch (type) {
264 : case kWasmI32:
265 : return MachineRepresentation::kWord32;
266 : case kWasmI64:
267 111534 : return MachineRepresentation::kWord64;
268 : case kWasmF32:
269 371993 : return MachineRepresentation::kFloat32;
270 : case kWasmF64:
271 586683 : return MachineRepresentation::kFloat64;
272 : case kWasmAnyRef:
273 : case kWasmAnyFunc:
274 : case kWasmExceptRef:
275 14254 : return MachineRepresentation::kTaggedPointer;
276 : case kWasmS128:
277 32 : return MachineRepresentation::kSimd128;
278 : case kWasmStmt:
279 0 : return MachineRepresentation::kNone;
280 : default:
281 0 : UNREACHABLE();
282 : }
283 : }
284 :
285 1157956 : static ValueType ValueTypeFor(MachineType type) {
286 1157956 : switch (type.representation()) {
287 : case MachineRepresentation::kWord8:
288 : case MachineRepresentation::kWord16:
289 : case MachineRepresentation::kWord32:
290 : return kWasmI32;
291 : case MachineRepresentation::kWord64:
292 : return kWasmI64;
293 : case MachineRepresentation::kFloat32:
294 : return kWasmF32;
295 : case MachineRepresentation::kFloat64:
296 : return kWasmF64;
297 : case MachineRepresentation::kTaggedPointer:
298 : return kWasmAnyRef;
299 : case MachineRepresentation::kSimd128:
300 : return kWasmS128;
301 : default:
302 0 : UNREACHABLE();
303 : }
304 : }
305 :
306 : static char ShortNameOf(ValueType type) {
307 : switch (type) {
308 : case kWasmI32:
309 : return 'i';
310 : case kWasmI64:
311 : return 'l';
312 : case kWasmF32:
313 : return 'f';
314 : case kWasmF64:
315 : return 'd';
316 : case kWasmAnyRef:
317 : return 'r';
318 : case kWasmAnyFunc:
319 : return 'a';
320 : case kWasmS128:
321 : return 's';
322 : case kWasmStmt:
323 : return 'v';
324 : case kWasmVar:
325 : return '*';
326 : default:
327 : return '?';
328 : }
329 : }
330 :
331 77328 : static const char* TypeName(ValueType type) {
332 77328 : switch (type) {
333 : case kWasmI32:
334 : return "i32";
335 : case kWasmI64:
336 16691 : return "i64";
337 : case kWasmF32:
338 16196 : return "f32";
339 : case kWasmF64:
340 13747 : return "f64";
341 : case kWasmAnyRef:
342 7303 : return "anyref";
343 : case kWasmAnyFunc:
344 78 : return "anyfunc";
345 : case kWasmNullRef:
346 0 : return "nullref";
347 : case kWasmExceptRef:
348 56 : return "exn";
349 : case kWasmS128:
350 16 : return "s128";
351 : case kWasmStmt:
352 532 : return "<stmt>";
353 : case kWasmVar:
354 0 : return "<var>";
355 : default:
356 0 : return "<unknown>";
357 : }
358 : }
359 :
360 : private:
361 : DISALLOW_IMPLICIT_CONSTRUCTORS(ValueTypes);
362 : };
363 :
364 : } // namespace wasm
365 : } // namespace internal
366 : } // namespace v8
367 :
368 : #endif // V8_WASM_VALUE_TYPE_H_
|