• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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