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