• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 #if !V8_ENABLE_WEBASSEMBLY
6 #error This header should only be included if WebAssembly is enabled.
7 #endif  // !V8_ENABLE_WEBASSEMBLY
8 
9 #ifndef V8_WASM_WASM_OPCODES_INL_H_
10 #define V8_WASM_WASM_OPCODES_INL_H_
11 
12 #include <array>
13 
14 #include "src/base/template-utils.h"
15 #include "src/codegen/signature.h"
16 #include "src/execution/messages.h"
17 #include "src/runtime/runtime.h"
18 #include "src/wasm/wasm-opcodes.h"
19 
20 namespace v8 {
21 namespace internal {
22 namespace wasm {
23 
24 #define CASE_OP(name, str) \
25   case kExpr##name:        \
26     return str;
27 #define CASE_I32_OP(name, str) CASE_OP(I32##name, "i32." str)
28 #define CASE_I64_OP(name, str) CASE_OP(I64##name, "i64." str)
29 #define CASE_F32_OP(name, str) CASE_OP(F32##name, "f32." str)
30 #define CASE_F64_OP(name, str) CASE_OP(F64##name, "f64." str)
31 #define CASE_REF_OP(name, str) CASE_OP(Ref##name, "ref." str)
32 #define CASE_F64x2_OP(name, str) CASE_OP(F64x2##name, "f64x2." str)
33 #define CASE_F32x4_OP(name, str) CASE_OP(F32x4##name, "f32x4." str)
34 #define CASE_I64x2_OP(name, str) CASE_OP(I64x2##name, "i64x2." str)
35 #define CASE_I32x4_OP(name, str) CASE_OP(I32x4##name, "i32x4." str)
36 #define CASE_I16x8_OP(name, str) CASE_OP(I16x8##name, "i16x8." str)
37 #define CASE_I8x16_OP(name, str) CASE_OP(I8x16##name, "i8x16." str)
38 #define CASE_S128_OP(name, str) CASE_OP(S128##name, "s128." str)
39 #define CASE_V128_OP(name, str) CASE_OP(V128##name, "v128." str)
40 #define CASE_S64x2_OP(name, str) CASE_OP(S64x2##name, "s64x2." str)
41 #define CASE_S32x4_OP(name, str) CASE_OP(S32x4##name, "s32x4." str)
42 #define CASE_S16x8_OP(name, str) CASE_OP(S16x8##name, "s16x8." str)
43 #define CASE_V64x2_OP(name, str) CASE_OP(V64x2##name, "v64x2." str)
44 #define CASE_V32x4_OP(name, str) CASE_OP(V32x4##name, "v32x4." str)
45 #define CASE_V16x8_OP(name, str) CASE_OP(V16x8##name, "v16x8." str)
46 #define CASE_V8x16_OP(name, str) CASE_OP(V8x16##name, "v8x16." str)
47 #define CASE_INT_OP(name, str) CASE_I32_OP(name, str) CASE_I64_OP(name, str)
48 #define CASE_FLOAT_OP(name, str) CASE_F32_OP(name, str) CASE_F64_OP(name, str)
49 #define CASE_ALL_OP(name, str) CASE_FLOAT_OP(name, str) CASE_INT_OP(name, str)
50 #define CASE_SIMD_OP(name, str)                                              \
51   CASE_F64x2_OP(name, str) CASE_I64x2_OP(name, str) CASE_F32x4_OP(name, str) \
52       CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str)                      \
53           CASE_I8x16_OP(name, str)
54 #define CASE_SIMDF_OP(name, str) \
55   CASE_F32x4_OP(name, str) CASE_F64x2_OP(name, str)
56 #define CASE_SIMDI_OP(name, str)                                             \
57   CASE_I64x2_OP(name, str) CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) \
58       CASE_I8x16_OP(name, str)
59 #define CASE_SIMDI_NO64X2_OP(name, str) \
60   CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) CASE_I8x16_OP(name, str)
61 #define CASE_SIGN_OP(TYPE, name, str) \
62   CASE_##TYPE##_OP(name##S, str "_s") CASE_##TYPE##_OP(name##U, str "_u")
63 #define CASE_UNSIGNED_OP(TYPE, name, str) CASE_##TYPE##_OP(name##U, str "_u")
64 #define CASE_ALL_SIGN_OP(name, str) \
65   CASE_FLOAT_OP(name, str) CASE_SIGN_OP(INT, name, str)
66 #define CASE_CONVERT_OP(name, RES, SRC, src_suffix, str) \
67   CASE_##RES##_OP(U##name##SRC, str "_" src_suffix "_u") \
68       CASE_##RES##_OP(S##name##SRC, str "_" src_suffix "_s")
69 #define CASE_CONVERT_SAT_OP(name, RES, SRC, src_suffix, str)      \
70   CASE_##RES##_OP(U##name##Sat##SRC, str "_sat_" src_suffix "_u") \
71       CASE_##RES##_OP(S##name##Sat##SRC, str "_sat_" src_suffix "_s")
72 #define CASE_L32_OP(name, str)          \
73   CASE_SIGN_OP(I32, name##8, str "8")   \
74   CASE_SIGN_OP(I32, name##16, str "16") \
75   CASE_I32_OP(name, str "32")
76 #define CASE_U32_OP(name, str)            \
77   CASE_I32_OP(name, str "32")             \
78   CASE_UNSIGNED_OP(I32, name##8, str "8") \
79   CASE_UNSIGNED_OP(I32, name##16, str "16")
80 #define CASE_UNSIGNED_ALL_OP(name, str)     \
81   CASE_U32_OP(name, str)                    \
82   CASE_I64_OP(name, str "64")               \
83   CASE_UNSIGNED_OP(I64, name##8, str "8")   \
84   CASE_UNSIGNED_OP(I64, name##16, str "16") \
85   CASE_UNSIGNED_OP(I64, name##32, str "32")
86 
87 // static
OpcodeName(WasmOpcode opcode)88 constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
89   switch (opcode) {
90     // clang-format off
91 
92     // Standard opcodes
93     CASE_INT_OP(Eqz, "eqz")
94     CASE_ALL_OP(Eq, "eq")
95     CASE_ALL_OP(Ne, "ne")
96     CASE_ALL_OP(Add, "add")
97     CASE_ALL_OP(Sub, "sub")
98     CASE_ALL_OP(Mul, "mul")
99     CASE_ALL_SIGN_OP(Lt, "lt")
100     CASE_ALL_SIGN_OP(Gt, "gt")
101     CASE_ALL_SIGN_OP(Le, "le")
102     CASE_ALL_SIGN_OP(Ge, "ge")
103     CASE_INT_OP(Clz, "clz")
104     CASE_INT_OP(Ctz, "ctz")
105     CASE_INT_OP(Popcnt, "popcnt")
106     CASE_ALL_SIGN_OP(Div, "div")
107     CASE_SIGN_OP(INT, Rem, "rem")
108     CASE_INT_OP(And, "and")
109     CASE_INT_OP(Ior, "or")
110     CASE_INT_OP(Xor, "xor")
111     CASE_INT_OP(Shl, "shl")
112     CASE_SIGN_OP(INT, Shr, "shr")
113     CASE_INT_OP(Rol, "rol")
114     CASE_INT_OP(Ror, "ror")
115     CASE_FLOAT_OP(Abs, "abs")
116     CASE_FLOAT_OP(Neg, "neg")
117     CASE_FLOAT_OP(Ceil, "ceil")
118     CASE_FLOAT_OP(Floor, "floor")
119     CASE_FLOAT_OP(Trunc, "trunc")
120     CASE_FLOAT_OP(NearestInt, "nearest")
121     CASE_FLOAT_OP(Sqrt, "sqrt")
122     CASE_FLOAT_OP(Min, "min")
123     CASE_FLOAT_OP(Max, "max")
124     CASE_FLOAT_OP(CopySign, "copysign")
125     CASE_REF_OP(Null, "null")
126     CASE_REF_OP(IsNull, "is_null")
127     CASE_REF_OP(Func, "func")
128     CASE_REF_OP(AsNonNull, "as_non_null")
129     CASE_I32_OP(ConvertI64, "wrap_i64")
130     CASE_CONVERT_OP(Convert, INT, F32, "f32", "trunc")
131     CASE_CONVERT_OP(Convert, INT, F64, "f64", "trunc")
132     CASE_CONVERT_OP(Convert, I64, I32, "i32", "extend")
133     CASE_CONVERT_OP(Convert, F32, I32, "i32", "convert")
134     CASE_CONVERT_OP(Convert, F32, I64, "i64", "convert")
135     CASE_F32_OP(ConvertF64, "demote_f64")
136     CASE_CONVERT_OP(Convert, F64, I32, "i32", "convert")
137     CASE_CONVERT_OP(Convert, F64, I64, "i64", "convert")
138     CASE_F64_OP(ConvertF32, "promote_f32")
139     CASE_I32_OP(ReinterpretF32, "reinterpret_f32")
140     CASE_I64_OP(ReinterpretF64, "reinterpret_f64")
141     CASE_F32_OP(ReinterpretI32, "reinterpret_i32")
142     CASE_F64_OP(ReinterpretI64, "reinterpret_i64")
143     CASE_INT_OP(SExtendI8, "extend8_s")
144     CASE_INT_OP(SExtendI16, "extend16_s")
145     CASE_I64_OP(SExtendI32, "extend32_s")
146     CASE_OP(Unreachable, "unreachable")
147     CASE_OP(Nop, "nop")
148     CASE_OP(NopForTestingUnsupportedInLiftoff, "nop_for_testing")
149     CASE_OP(Block, "block")
150     CASE_OP(Loop, "loop")
151     CASE_OP(If, "if")
152     CASE_OP(Else, "else")
153     CASE_OP(End, "end")
154     CASE_OP(Br, "br")
155     CASE_OP(BrIf, "br_if")
156     CASE_OP(BrTable, "br_table")
157     CASE_OP(Return, "return")
158     CASE_OP(CallFunction, "call")
159     CASE_OP(CallIndirect, "call_indirect")
160     CASE_OP(ReturnCall, "return_call")
161     CASE_OP(ReturnCallIndirect, "return_call_indirect")
162     CASE_OP(CallRef, "call_ref")
163     CASE_OP(ReturnCallRef, "return_call_ref")
164     CASE_OP(BrOnNull, "br_on_null")
165     CASE_OP(BrOnNonNull, "br_on_non_null")
166     CASE_OP(Drop, "drop")
167     CASE_OP(Select, "select")
168     CASE_OP(SelectWithType, "select")
169     CASE_OP(LocalGet, "local.get")
170     CASE_OP(LocalSet, "local.set")
171     CASE_OP(LocalTee, "local.tee")
172     CASE_OP(GlobalGet, "global.get")
173     CASE_OP(GlobalSet, "global.set")
174     CASE_OP(TableGet, "table.get")
175     CASE_OP(TableSet, "table.set")
176     CASE_ALL_OP(Const, "const")
177     CASE_OP(MemorySize, "memory.size")
178     CASE_OP(MemoryGrow, "memory.grow")
179     CASE_ALL_OP(LoadMem, "load")
180     CASE_SIGN_OP(INT, LoadMem8, "load8")
181     CASE_SIGN_OP(INT, LoadMem16, "load16")
182     CASE_SIGN_OP(I64, LoadMem32, "load32")
183     CASE_S128_OP(LoadMem, "load128")
184     CASE_S128_OP(Const, "const")
185     CASE_ALL_OP(StoreMem, "store")
186     CASE_INT_OP(StoreMem8, "store8")
187     CASE_INT_OP(StoreMem16, "store16")
188     CASE_I64_OP(StoreMem32, "store32")
189     CASE_S128_OP(StoreMem, "store128")
190     CASE_OP(RefEq, "ref.eq")
191     CASE_OP(Let, "let")
192 
193     // Exception handling opcodes.
194     CASE_OP(Try, "try")
195     CASE_OP(Catch, "catch")
196     CASE_OP(Delegate, "delegate")
197     CASE_OP(Throw, "throw")
198     CASE_OP(Rethrow, "rethrow")
199     CASE_OP(CatchAll, "catch-all")
200 
201     // asm.js-only opcodes.
202     CASE_F64_OP(Acos, "acos")
203     CASE_F64_OP(Asin, "asin")
204     CASE_F64_OP(Atan, "atan")
205     CASE_F64_OP(Cos, "cos")
206     CASE_F64_OP(Sin, "sin")
207     CASE_F64_OP(Tan, "tan")
208     CASE_F64_OP(Exp, "exp")
209     CASE_F64_OP(Log, "log")
210     CASE_F64_OP(Atan2, "atan2")
211     CASE_F64_OP(Pow, "pow")
212     CASE_F64_OP(Mod, "mod")
213     CASE_F32_OP(AsmjsLoadMem, "asmjs_load")
214     CASE_F64_OP(AsmjsLoadMem, "asmjs_load")
215     CASE_L32_OP(AsmjsLoadMem, "asmjs_load")
216     CASE_I32_OP(AsmjsStoreMem, "asmjs_store")
217     CASE_F32_OP(AsmjsStoreMem, "asmjs_store")
218     CASE_F64_OP(AsmjsStoreMem, "asmjs_store")
219     CASE_I32_OP(AsmjsStoreMem8, "asmjs_store8")
220     CASE_I32_OP(AsmjsStoreMem16, "asmjs_store16")
221     CASE_SIGN_OP(I32, AsmjsDiv, "asmjs_div")
222     CASE_SIGN_OP(I32, AsmjsRem, "asmjs_rem")
223     CASE_I32_OP(AsmjsSConvertF32, "asmjs_convert_f32_s")
224     CASE_I32_OP(AsmjsUConvertF32, "asmjs_convert_f32_u")
225     CASE_I32_OP(AsmjsSConvertF64, "asmjs_convert_f64_s")
226     CASE_I32_OP(AsmjsUConvertF64, "asmjs_convert_f64_u")
227 
228     // Numeric Opcodes.
229     CASE_CONVERT_SAT_OP(Convert, I32, F32, "f32", "trunc")
230     CASE_CONVERT_SAT_OP(Convert, I32, F64, "f64", "trunc")
231     CASE_CONVERT_SAT_OP(Convert, I64, F32, "f32", "trunc")
232     CASE_CONVERT_SAT_OP(Convert, I64, F64, "f64", "trunc")
233     CASE_OP(MemoryInit, "memory.init")
234     CASE_OP(DataDrop, "data.drop")
235     CASE_OP(MemoryCopy, "memory.copy")
236     CASE_OP(MemoryFill, "memory.fill")
237     CASE_OP(TableInit, "table.init")
238     CASE_OP(ElemDrop, "elem.drop")
239     CASE_OP(TableCopy, "table.copy")
240     CASE_OP(TableGrow, "table.grow")
241     CASE_OP(TableSize, "table.size")
242     CASE_OP(TableFill, "table.fill")
243 
244     // SIMD opcodes.
245     CASE_SIMD_OP(Splat, "splat")
246     CASE_SIMD_OP(Neg, "neg")
247     CASE_SIMDF_OP(Sqrt, "sqrt")
248     CASE_SIMD_OP(Eq, "eq")
249     CASE_SIMD_OP(Ne, "ne")
250     CASE_SIMD_OP(Add, "add")
251     CASE_SIMD_OP(Sub, "sub")
252     CASE_I16x8_OP(Mul, "mul")
253     CASE_I32x4_OP(Mul, "mul")
254     CASE_I64x2_OP(Mul, "mul")
255     CASE_SIMDF_OP(Mul, "mul")
256     CASE_SIMDF_OP(Div, "div")
257     CASE_SIMDF_OP(Lt, "lt")
258     CASE_SIMDF_OP(Le, "le")
259     CASE_SIMDF_OP(Gt, "gt")
260     CASE_SIMDF_OP(Ge, "ge")
261     CASE_SIMDF_OP(Abs, "abs")
262     CASE_SIMDF_OP(Min, "min")
263     CASE_SIMDF_OP(Max, "max")
264     CASE_CONVERT_OP(Convert, F32x4, I32x4, "i32x4", "convert")
265     CASE_CONVERT_OP(Convert, I32x4, F32x4, "f32x4", "convert")
266     CASE_CONVERT_OP(Convert, I32x4, I16x8Low, "i16x8_low", "convert")
267     CASE_CONVERT_OP(Convert, I32x4, I16x8High, "i16x8_high", "convert")
268     CASE_CONVERT_OP(Convert, I16x8, I32x4, "i32x4", "convert")
269     CASE_CONVERT_OP(Convert, I16x8, I8x16Low, "i8x16_low", "convert")
270     CASE_CONVERT_OP(Convert, I16x8, I8x16High, "i8x16_high", "convert")
271     CASE_CONVERT_OP(Convert, I8x16, I16x8, "i16x8", "convert")
272     CASE_SIMDF_OP(ExtractLane, "extract_lane")
273     CASE_SIMDF_OP(ReplaceLane, "replace_lane")
274     CASE_I64x2_OP(ExtractLane, "extract_lane")
275     CASE_I32x4_OP(ExtractLane, "extract_lane")
276     CASE_SIGN_OP(I16x8, ExtractLane, "extract_lane")
277     CASE_SIGN_OP(I8x16, ExtractLane, "extract_lane")
278     CASE_SIMDI_OP(ReplaceLane, "replace_lane")
279     CASE_SIGN_OP(SIMDI_NO64X2, Min, "min")
280     CASE_SIGN_OP(SIMDI_NO64X2, Max, "max")
281     CASE_SIGN_OP(SIMDI_NO64X2, Lt, "lt")
282     CASE_I64x2_OP(LtS, "lt_s")
283     CASE_I64x2_OP(GtS, "gt_s")
284     CASE_I64x2_OP(LeS, "le_s")
285     CASE_I64x2_OP(GeS, "ge_s")
286     CASE_SIGN_OP(SIMDI_NO64X2, Le, "le")
287     CASE_SIGN_OP(SIMDI_NO64X2, Gt, "gt")
288     CASE_SIGN_OP(SIMDI_NO64X2, Ge, "ge")
289     CASE_CONVERT_OP(Convert, I64x2, I32x4Low, "i32x4_low", "convert")
290     CASE_CONVERT_OP(Convert, I64x2, I32x4High, "i32x4_high", "convert")
291     CASE_SIGN_OP(SIMDI, Shr, "shr")
292     CASE_SIMDI_OP(Shl, "shl")
293     CASE_SIGN_OP(I16x8, AddSat, "add_sat")
294     CASE_SIGN_OP(I8x16, AddSat, "add_sat")
295     CASE_SIGN_OP(I16x8, SubSat, "sub_sat")
296     CASE_SIGN_OP(I8x16, SubSat, "sub_sat")
297     CASE_S128_OP(And, "and")
298     CASE_S128_OP(Or, "or")
299     CASE_S128_OP(Xor, "xor")
300     CASE_S128_OP(Not, "not")
301     CASE_S128_OP(Select, "select")
302     CASE_S128_OP(AndNot, "andnot")
303     CASE_I8x16_OP(Swizzle, "swizzle")
304     CASE_I8x16_OP(Shuffle, "shuffle")
305     CASE_V128_OP(AnyTrue, "any_true")
306     CASE_SIMDI_OP(AllTrue, "all_true")
307 
308     CASE_S128_OP(Load32Zero, "load32_zero")
309     CASE_S128_OP(Load64Zero, "load64_zero")
310     CASE_S128_OP(Load8Splat, "load8_splat")
311     CASE_S128_OP(Load16Splat, "load16_splat")
312     CASE_S128_OP(Load32Splat, "load32_splat")
313     CASE_S128_OP(Load64Splat, "load64_splat")
314     CASE_S128_OP(Load8x8S, "load8x8_s")
315     CASE_S128_OP(Load8x8U, "load8x8_u")
316     CASE_S128_OP(Load16x4S, "load16x4_s")
317     CASE_S128_OP(Load16x4U, "load16x4_u")
318     CASE_S128_OP(Load32x2S, "load32x2_s")
319     CASE_S128_OP(Load32x2U, "load32x2_u")
320     CASE_S128_OP(Load8Lane, "load8_lane")
321     CASE_S128_OP(Load16Lane, "load16_lane")
322     CASE_S128_OP(Load32Lane, "load32_lane")
323     CASE_S128_OP(Load64Lane, "load64_lane")
324     CASE_S128_OP(Store8Lane, "store8_lane")
325     CASE_S128_OP(Store16Lane, "store16_lane")
326     CASE_S128_OP(Store32Lane, "store32_lane")
327     CASE_S128_OP(Store64Lane, "store64_lane")
328 
329     CASE_I8x16_OP(RoundingAverageU, "avgr_u")
330     CASE_I16x8_OP(RoundingAverageU, "avgr_u")
331     CASE_I16x8_OP(Q15MulRSatS, "q15mulr_sat_s")
332 
333     CASE_SIMDI_OP(Abs, "abs")
334     CASE_SIMDI_OP(BitMask, "bitmask")
335     CASE_I8x16_OP(Popcnt, "popcnt")
336 
337 
338     CASE_SIMDF_OP(Pmin, "pmin")
339     CASE_SIMDF_OP(Pmax, "pmax")
340 
341     CASE_SIMDF_OP(Ceil, "ceil")
342     CASE_SIMDF_OP(Floor, "floor")
343     CASE_SIMDF_OP(Trunc, "trunc")
344     CASE_SIMDF_OP(NearestInt, "nearest")
345 
346     CASE_I32x4_OP(DotI16x8S, "dot_i16x8_s")
347 
348     CASE_SIGN_OP(I16x8, ExtMulLowI8x16, "extmul_low_i8x16")
349     CASE_SIGN_OP(I16x8, ExtMulHighI8x16, "extmul_high_i8x16")
350     CASE_SIGN_OP(I32x4, ExtMulLowI16x8, "extmul_low_i16x8")
351     CASE_SIGN_OP(I32x4, ExtMulHighI16x8, "extmul_high_i16x8")
352     CASE_SIGN_OP(I64x2, ExtMulLowI32x4, "extmul_low_i32x4")
353     CASE_SIGN_OP(I64x2, ExtMulHighI32x4, "extmul_high_i32x4")
354 
355     CASE_SIGN_OP(I32x4, ExtAddPairwiseI16x8, "extadd_pairwise_i16x8")
356     CASE_SIGN_OP(I16x8, ExtAddPairwiseI8x16, "extadd_pairwise_i8x6")
357 
358     CASE_F64x2_OP(ConvertLowI32x4S, "convert_low_i32x4_s")
359     CASE_F64x2_OP(ConvertLowI32x4U, "convert_low_i32x4_u")
360     CASE_I32x4_OP(TruncSatF64x2SZero, "trunc_sat_f64x2_s_zero")
361     CASE_I32x4_OP(TruncSatF64x2UZero, "trunc_sat_f64x2_u_zero")
362     CASE_F32x4_OP(DemoteF64x2Zero, "demote_f64x2_zero")
363     CASE_F64x2_OP(PromoteLowF32x4, "promote_low_f32x4")
364 
365     // Relaxed SIMD opcodes.
366     CASE_F32x4_OP(RecipApprox, "recip_approx")
367     CASE_F32x4_OP(RecipSqrtApprox, "recip_sqrt_approx")
368     CASE_SIMDF_OP(Qfma, "qfma")
369     CASE_SIMDF_OP(Qfms, "qfms")
370     CASE_I8x16_OP(RelaxedSwizzle, "relaxed_swizzle");
371     CASE_I8x16_OP(RelaxedLaneSelect, "relaxed_laneselect");
372     CASE_I16x8_OP(RelaxedLaneSelect, "relaxed_laneselect");
373     CASE_I32x4_OP(RelaxedLaneSelect, "relaxed_laneselect");
374     CASE_I64x2_OP(RelaxedLaneSelect, "relaxed_laneselect");
375     CASE_SIMDF_OP(RelaxedMin, "relaxed_min");
376     CASE_SIMDF_OP(RelaxedMax, "relaxed_max");
377     CASE_I32x4_OP(RelaxedTruncF32x4S, "relaxed_trunc_f32x4_s");
378     CASE_I32x4_OP(RelaxedTruncF32x4U, "relaxed_trunc_f32x4_u");
379     CASE_I32x4_OP(RelaxedTruncF64x2SZero, "relaxed_trunc_f64x2_s_zero");
380     CASE_I32x4_OP(RelaxedTruncF64x2UZero, "relaxed_trunc_f64x2_u_zero");
381 
382     // Atomic operations.
383     CASE_OP(AtomicNotify, "atomic.notify")
384     CASE_INT_OP(AtomicWait, "atomic.wait")
385     CASE_OP(AtomicFence, "atomic.fence")
386     CASE_UNSIGNED_ALL_OP(AtomicLoad, "atomic.load")
387     CASE_UNSIGNED_ALL_OP(AtomicStore, "atomic.store")
388     CASE_UNSIGNED_ALL_OP(AtomicAdd, "atomic.add")
389     CASE_UNSIGNED_ALL_OP(AtomicSub, "atomic.sub")
390     CASE_UNSIGNED_ALL_OP(AtomicAnd, "atomic.and")
391     CASE_UNSIGNED_ALL_OP(AtomicOr, "atomic.or")
392     CASE_UNSIGNED_ALL_OP(AtomicXor, "atomic.xor")
393     CASE_UNSIGNED_ALL_OP(AtomicExchange, "atomic.xchng")
394     CASE_UNSIGNED_ALL_OP(AtomicCompareExchange, "atomic.cmpxchng")
395 
396     // GC operations.
397     CASE_OP(StructNewWithRtt, "struct.new_with_rtt")
398     CASE_OP(StructNewDefaultWithRtt, "struct.new_default_with_rtt")
399     CASE_OP(StructNew, "struct.new")
400     CASE_OP(StructNewDefault, "struct.new_default")
401     CASE_OP(StructGet, "struct.get")
402     CASE_OP(StructGetS, "struct.get_s")
403     CASE_OP(StructGetU, "struct.get_u")
404     CASE_OP(StructSet, "struct.set")
405     CASE_OP(ArrayNewWithRtt, "array.new_with_rtt")
406     CASE_OP(ArrayNewDefaultWithRtt, "array.new_default_with_rtt")
407     CASE_OP(ArrayNew, "array.new")
408     CASE_OP(ArrayNewDefault, "array.new_default")
409     CASE_OP(ArrayGet, "array.get")
410     CASE_OP(ArrayGetS, "array.get_s")
411     CASE_OP(ArrayGetU, "array.get_u")
412     CASE_OP(ArraySet, "array.set")
413     CASE_OP(ArrayLen, "array.len")
414     CASE_OP(ArrayCopy, "array.copy")
415     CASE_OP(ArrayInit, "array.init")
416     CASE_OP(ArrayInitStatic, "array.init_static")
417     CASE_OP(ArrayInitFromData, "array.init_from_data")
418     CASE_OP(ArrayInitFromDataStatic, "array.init_from_data_static")
419     CASE_OP(I31New, "i31.new")
420     CASE_OP(I31GetS, "i31.get_s")
421     CASE_OP(I31GetU, "i31.get_u")
422     CASE_OP(RttCanon, "rtt.canon")
423     CASE_OP(RefTest, "ref.test")
424     CASE_OP(RefTestStatic, "ref.test_static")
425     CASE_OP(RefCast, "ref.cast")
426     CASE_OP(RefCastStatic, "ref.cast_static")
427     CASE_OP(BrOnCast, "br_on_cast")
428     CASE_OP(BrOnCastStatic, "br_on_cast_static")
429     CASE_OP(BrOnCastFail, "br_on_cast_fail")
430     CASE_OP(BrOnCastStaticFail, "br_on_cast_static_fail")
431     CASE_OP(RefIsFunc, "ref.is_func")
432     CASE_OP(RefIsData, "ref.is_data")
433     CASE_OP(RefIsI31, "ref.is_i31")
434     CASE_OP(RefIsArray, "ref.is_array")
435     CASE_OP(RefAsFunc, "ref.as_func")
436     CASE_OP(RefAsData, "ref.as_data")
437     CASE_OP(RefAsI31, "ref.as_i31")
438     CASE_OP(RefAsArray, "ref.as_array")
439     CASE_OP(BrOnFunc, "br_on_func")
440     CASE_OP(BrOnData, "br_on_data")
441     CASE_OP(BrOnI31, "br_on_i31")
442     CASE_OP(BrOnArray, "br_on_array")
443     CASE_OP(BrOnNonFunc, "br_on_non_func")
444     CASE_OP(BrOnNonData, "br_on_non_data")
445     CASE_OP(BrOnNonI31, "br_on_non_i31")
446     CASE_OP(BrOnNonArray, "br_on_non_array")
447 
448     case kNumericPrefix:
449     case kSimdPrefix:
450     case kAtomicPrefix:
451     case kGCPrefix:
452       return "unknown";
453     // clang-format on
454   }
455   // Even though the switch above handles all well-defined enum values,
456   // random modules (e.g. fuzzer generated) can call this function with
457   // random (invalid) opcodes. Handle those here:
458   return "invalid opcode";
459 }
460 
461 #undef CASE_OP
462 #undef CASE_I32_OP
463 #undef CASE_I64_OP
464 #undef CASE_F32_OP
465 #undef CASE_F64_OP
466 #undef CASE_REF_OP
467 #undef CASE_F64x2_OP
468 #undef CASE_F32x4_OP
469 #undef CASE_I64x2_OP
470 #undef CASE_I32x4_OP
471 #undef CASE_I16x8_OP
472 #undef CASE_I8x16_OP
473 #undef CASE_S128_OP
474 #undef CASE_S64x2_OP
475 #undef CASE_S32x4_OP
476 #undef CASE_S16x8_OP
477 #undef CASE_INT_OP
478 #undef CASE_FLOAT_OP
479 #undef CASE_ALL_OP
480 #undef CASE_SIMD_OP
481 #undef CASE_SIMDI_OP
482 #undef CASE_SIMDI_NO64X2_OP
483 #undef CASE_SIGN_OP
484 #undef CASE_UNSIGNED_OP
485 #undef CASE_UNSIGNED_ALL_OP
486 #undef CASE_ALL_SIGN_OP
487 #undef CASE_CONVERT_OP
488 #undef CASE_CONVERT_SAT_OP
489 #undef CASE_L32_OP
490 #undef CASE_U32_OP
491 
492 // static
IsPrefixOpcode(WasmOpcode opcode)493 constexpr bool WasmOpcodes::IsPrefixOpcode(WasmOpcode opcode) {
494   switch (opcode) {
495 #define CHECK_PREFIX(name, opcode) case k##name##Prefix:
496     FOREACH_PREFIX(CHECK_PREFIX)
497 #undef CHECK_PREFIX
498     return true;
499     default:
500       return false;
501   }
502 }
503 
504 // static
IsControlOpcode(WasmOpcode opcode)505 constexpr bool WasmOpcodes::IsControlOpcode(WasmOpcode opcode) {
506   switch (opcode) {
507 #define CHECK_OPCODE(name, opcode, _) case kExpr##name:
508     FOREACH_CONTROL_OPCODE(CHECK_OPCODE)
509 #undef CHECK_OPCODE
510     return true;
511     default:
512       return false;
513   }
514 }
515 
516 // static
IsUnconditionalJump(WasmOpcode opcode)517 constexpr bool WasmOpcodes::IsUnconditionalJump(WasmOpcode opcode) {
518   switch (opcode) {
519     case kExprUnreachable:
520     case kExprBr:
521     case kExprBrTable:
522     case kExprReturn:
523     case kExprReturnCall:
524     case kExprReturnCallIndirect:
525     case kExprThrow:
526     case kExprRethrow:
527       return true;
528     default:
529       return false;
530   }
531 }
532 
533 // static
IsBreakable(WasmOpcode opcode)534 constexpr bool WasmOpcodes::IsBreakable(WasmOpcode opcode) {
535   switch (opcode) {
536     case kExprBlock:
537     case kExprTry:
538     case kExprCatch:
539     case kExprLoop:
540     case kExprElse:
541       return false;
542     default:
543       return true;
544   }
545 }
546 
547 // static
IsExternRefOpcode(WasmOpcode opcode)548 constexpr bool WasmOpcodes::IsExternRefOpcode(WasmOpcode opcode) {
549   switch (opcode) {
550     case kExprRefNull:
551     case kExprRefIsNull:
552     case kExprRefFunc:
553     case kExprRefAsNonNull:
554       return true;
555     default:
556       return false;
557   }
558 }
559 
560 // static
IsThrowingOpcode(WasmOpcode opcode)561 constexpr bool WasmOpcodes::IsThrowingOpcode(WasmOpcode opcode) {
562   // TODO(8729): Trapping opcodes are not yet considered to be throwing.
563   switch (opcode) {
564     case kExprThrow:
565     case kExprRethrow:
566     case kExprCallFunction:
567     case kExprCallIndirect:
568       return true;
569     default:
570       return false;
571   }
572 }
573 
574 // static
IsRelaxedSimdOpcode(WasmOpcode opcode)575 constexpr bool WasmOpcodes::IsRelaxedSimdOpcode(WasmOpcode opcode) {
576   switch (opcode) {
577 #define CHECK_OPCODE(name, opcode, _) case kExpr##name:
578     FOREACH_RELAXED_SIMD_OPCODE(CHECK_OPCODE)
579 #undef CHECK_OPCODE
580     return true;
581     default:
582       return false;
583   }
584 }
585 
586 namespace impl {
587 
588 #define DECLARE_SIG_ENUM(name, ...) kSigEnum_##name,
589 enum WasmOpcodeSig : byte {
590   kSigEnum_None,
591   FOREACH_SIGNATURE(DECLARE_SIG_ENUM)
592 };
593 #undef DECLARE_SIG_ENUM
594 #define DECLARE_SIG(name, ...)                                                \
595   constexpr ValueType kTypes_##name[] = {__VA_ARGS__};                        \
596   constexpr int kReturnsCount_##name = kTypes_##name[0] == kWasmVoid ? 0 : 1; \
597   constexpr FunctionSig kSig_##name(                                          \
598       kReturnsCount_##name, static_cast<int>(arraysize(kTypes_##name)) - 1,   \
599       kTypes_##name + (1 - kReturnsCount_##name));
600 FOREACH_SIGNATURE(DECLARE_SIG)
601 #undef DECLARE_SIG
602 
603 #define DECLARE_SIG_ENTRY(name, ...) &kSig_##name,
604 constexpr const FunctionSig* kCachedSigs[] = {
605     nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)};
606 #undef DECLARE_SIG_ENTRY
607 
GetShortOpcodeSigIndex(byte opcode)608 constexpr WasmOpcodeSig GetShortOpcodeSigIndex(byte opcode) {
609 #define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig:
610   return FOREACH_SIMPLE_OPCODE(CASE) FOREACH_SIMPLE_PROTOTYPE_OPCODE(CASE)
611       kSigEnum_None;
612 #undef CASE
613 }
614 
GetAsmJsOpcodeSigIndex(byte opcode)615 constexpr WasmOpcodeSig GetAsmJsOpcodeSigIndex(byte opcode) {
616 #define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig:
617   return FOREACH_ASMJS_COMPAT_OPCODE(CASE) kSigEnum_None;
618 #undef CASE
619 }
620 
GetSimdOpcodeSigIndex(byte opcode)621 constexpr WasmOpcodeSig GetSimdOpcodeSigIndex(byte opcode) {
622 #define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
623   return FOREACH_SIMD_0_OPERAND_OPCODE(CASE) FOREACH_SIMD_MEM_OPCODE(CASE)
624       FOREACH_SIMD_MEM_1_OPERAND_OPCODE(CASE) kSigEnum_None;
625 #undef CASE
626 }
627 
GetAtomicOpcodeSigIndex(byte opcode)628 constexpr WasmOpcodeSig GetAtomicOpcodeSigIndex(byte opcode) {
629 #define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
630   return FOREACH_ATOMIC_OPCODE(CASE) FOREACH_ATOMIC_0_OPERAND_OPCODE(CASE)
631       kSigEnum_None;
632 #undef CASE
633 }
634 
GetNumericOpcodeSigIndex(byte opcode)635 constexpr WasmOpcodeSig GetNumericOpcodeSigIndex(byte opcode) {
636 #define CASE_SIG(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
637 #define CASE_VARIADIC(name, opc)
638   return FOREACH_NUMERIC_OPCODE(CASE_SIG, CASE_VARIADIC) kSigEnum_None;
639 #undef CASE_SIG
640 #undef CASE_VARIADIC
641 }
642 
643 constexpr std::array<WasmOpcodeSig, 256> kShortSigTable =
644     base::make_array<256>(GetShortOpcodeSigIndex);
645 constexpr std::array<WasmOpcodeSig, 256> kSimpleAsmjsExprSigTable =
646     base::make_array<256>(GetAsmJsOpcodeSigIndex);
647 constexpr std::array<WasmOpcodeSig, 256> kSimdExprSigTable =
648     base::make_array<256>(GetSimdOpcodeSigIndex);
649 constexpr std::array<WasmOpcodeSig, 256> kAtomicExprSigTable =
650     base::make_array<256>(GetAtomicOpcodeSigIndex);
651 constexpr std::array<WasmOpcodeSig, 256> kNumericExprSigTable =
652     base::make_array<256>(GetNumericOpcodeSigIndex);
653 
654 }  // namespace impl
655 
Signature(WasmOpcode opcode)656 constexpr const FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
657   switch (opcode >> 8) {
658     case 0:
659       return impl::kCachedSigs[impl::kShortSigTable[opcode]];
660     case kSimdPrefix:
661       return impl::kCachedSigs[impl::kSimdExprSigTable[opcode & 0xFF]];
662     case kAtomicPrefix:
663       return impl::kCachedSigs[impl::kAtomicExprSigTable[opcode & 0xFF]];
664     case kNumericPrefix:
665       return impl::kCachedSigs[impl::kNumericExprSigTable[opcode & 0xFF]];
666     default:
667       UNREACHABLE();  // invalid prefix.
668   }
669 }
670 
AsmjsSignature(WasmOpcode opcode)671 constexpr const FunctionSig* WasmOpcodes::AsmjsSignature(WasmOpcode opcode) {
672   DCHECK_GT(impl::kSimpleAsmjsExprSigTable.size(), opcode);
673   return impl::kCachedSigs[impl::kSimpleAsmjsExprSigTable[opcode]];
674 }
675 
TrapReasonToMessageId(TrapReason reason)676 constexpr MessageTemplate WasmOpcodes::TrapReasonToMessageId(
677     TrapReason reason) {
678   switch (reason) {
679 #define TRAPREASON_TO_MESSAGE(name) \
680   case k##name:                     \
681     return MessageTemplate::kWasm##name;
682     FOREACH_WASM_TRAPREASON(TRAPREASON_TO_MESSAGE)
683 #undef TRAPREASON_TO_MESSAGE
684     default:
685       return MessageTemplate::kNone;
686   }
687 }
688 
TrapReasonMessage(TrapReason reason)689 const char* WasmOpcodes::TrapReasonMessage(TrapReason reason) {
690   return MessageFormatter::TemplateString(TrapReasonToMessageId(reason));
691 }
692 
693 }  // namespace wasm
694 }  // namespace internal
695 }  // namespace v8
696 
697 #endif  // V8_WASM_WASM_OPCODES_INL_H_
698