==> include/wasm/opcodes.h <==1/* @ajax/wasm-opcodes: the instruction set as data.
2 *
3 * An instruction's id is its opcode byte, or for a prefixed one (prefix << 16) | sub-opcode:
4 * i32.trunc_sat_f32_s is 0xfc0000, v128.load 0xfd0000, memory.atomic.notify 0xfe0000. For each
5 * known id wasm_op_info gives the immediates that follow it in the binary, its operand signature
6 * when it is a plain one ("ii>i": pops i32 i32, pushes i32; NULL: the validator handles it), the
7 * proposal that introduced it, and wasmparser's name for it (its Operator variant, as meshd's float
8 * guard prints it: "F32Add"). SIMD and atomics are known by their immediates only (name "Simd",
9 * "RelaxedSimd", "Atomic"): enough to walk and refuse them, not to run them. */
10#ifndef WASM_OPCODES_H
11#define WASM_OPCODES_H
12
13#include "wasm/types.h"
14
15#include <stdint.h>
16
17/* Prefixes. */
18#define WASM_PREFIX_FC 0xfc
19#define WASM_PREFIX_SIMD 0xfd
20#define WASM_PREFIX_ATOMIC 0xfe
21#define WASM_OP_FC(sub) (0xfc0000u | (sub))
22#define WASM_OP_SIMD(sub) (0xfd0000u | (sub))
23#define WASM_OP_ATOMIC(sub) (0xfe0000u | (sub))
24
25/* What follows the opcode. */
26typedef enum {
27 WASM_IMM_NONE,
28 WASM_IMM_BLOCK, /* block type: 0x40, a value type, or an s33 type index */
29 WASM_IMM_LABEL, /* u32 label depth */
30 WASM_IMM_BR_TABLE, /* vec(u32) then u32 */
31 WASM_IMM_FUNC, /* u32 function index */
32 WASM_IMM_CALL_INDIRECT, /* u32 type index, u32 table index */
33 WASM_IMM_LOCAL, /* u32 */
34 WASM_IMM_GLOBAL, /* u32 */
35 WASM_IMM_TABLE, /* u32 table index */
36 WASM_IMM_MEMARG, /* u32 align (bit 6: a memory index follows), u32 offset */
37 WASM_IMM_MEMIDX, /* u32 memory index (memory.size, memory.grow, memory.fill) */
38 WASM_IMM_I32, /* s32 */
39 WASM_IMM_I64, /* s64 */
40 WASM_IMM_F32, /* 4 bytes */
41 WASM_IMM_F64, /* 8 bytes */
42 WASM_IMM_SELECT_T, /* vec(valtype) */
43 WASM_IMM_REFTYPE, /* one reference type byte */
44 WASM_IMM_MEMORY_INIT, /* u32 data index, u32 memory index */
45 WASM_IMM_DATA, /* u32 data index */
46 WASM_IMM_MEMORY_COPY, /* u32 memory index, u32 memory index */
47 WASM_IMM_TABLE_INIT, /* u32 element index, u32 table index */
48 WASM_IMM_ELEM, /* u32 element index */
49 WASM_IMM_TABLE_COPY, /* u32 table index, u32 table index */
50 WASM_IMM_V128, /* 16 bytes */
51 WASM_IMM_SHUFFLE, /* 16 lane bytes */
52 WASM_IMM_LANE, /* 1 lane byte */
53 WASM_IMM_MEMARG_LANE, /* memarg, then 1 lane byte */
54 WASM_IMM_ZERO_BYTE, /* one 0x00 byte (atomic.fence) */
55} wasm_imm;
56
57typedef struct {
58 uint32_t op;
59 const char *name; /* wasmparser's Operator variant */
60 uint8_t imm; /* wasm_imm */
61 uint32_t feature; /* WASM_F_* bit that introduced it; 0: the MVP */
62 const char *sig; /* "ab>c" over i (i32) l (i64) f (f32) d (f64), or NULL */
63 uint8_t mem_bytes; /* loads and stores: the access size in bytes; else 0 */
64} wasm_opinfo;
65
66/* The instruction with this id into *out; false when no proposal we know defines it. */
67bool wasm_op_info(uint32_t op, wasm_opinfo *out);
68
69/* The value type of a signature letter (i l f d), or 0. */
70static inline wasm_valtype wasm_sig_type(char c) {
71 switch (c) {
72 case 'i': return WASM_I32;
73 case 'l': return WASM_I64;
74 case 'f': return WASM_F32;
75 case 'd': return WASM_F64;
76 default: return 0;
77 }
78}
79
80/* The opcodes the interpreter and validator name directly. */
81enum {
82 WASM_OP_UNREACHABLE = 0x00,
83 WASM_OP_NOP = 0x01,
84 WASM_OP_BLOCK = 0x02,
85 WASM_OP_LOOP = 0x03,
86 WASM_OP_IF = 0x04,
87 WASM_OP_ELSE = 0x05,
88 WASM_OP_END = 0x0b,
89 WASM_OP_BR = 0x0c,
90 WASM_OP_BR_IF = 0x0d,
91 WASM_OP_BR_TABLE = 0x0e,
92 WASM_OP_RETURN = 0x0f,
93 WASM_OP_CALL = 0x10,
94 WASM_OP_CALL_INDIRECT = 0x11,
95 WASM_OP_DROP = 0x1a,
96 WASM_OP_SELECT = 0x1b,
97 WASM_OP_SELECT_T = 0x1c,
98 WASM_OP_LOCAL_GET = 0x20,
99 WASM_OP_LOCAL_SET = 0x21,
100 WASM_OP_LOCAL_TEE = 0x22,
101 WASM_OP_GLOBAL_GET = 0x23,
102 WASM_OP_GLOBAL_SET = 0x24,
103 WASM_OP_TABLE_GET = 0x25,
104 WASM_OP_TABLE_SET = 0x26,
105 WASM_OP_MEMORY_SIZE = 0x3f,
106 WASM_OP_MEMORY_GROW = 0x40,
107 WASM_OP_I32_CONST = 0x41,
108 WASM_OP_I64_CONST = 0x42,
109 WASM_OP_F32_CONST = 0x43,
110 WASM_OP_F64_CONST = 0x44,
111 WASM_OP_REF_NULL = 0xd0,
112 WASM_OP_REF_IS_NULL = 0xd1,
113 WASM_OP_REF_FUNC = 0xd2,
114};
115
116#define WASM_OP_MEMORY_INIT WASM_OP_FC(8)
117#define WASM_OP_DATA_DROP WASM_OP_FC(9)
118#define WASM_OP_MEMORY_COPY WASM_OP_FC(10)
119#define WASM_OP_MEMORY_FILL WASM_OP_FC(11)
120#define WASM_OP_TABLE_INIT WASM_OP_FC(12)
121#define WASM_OP_ELEM_DROP WASM_OP_FC(13)
122#define WASM_OP_TABLE_COPY WASM_OP_FC(14)
123#define WASM_OP_TABLE_GROW WASM_OP_FC(15)
124#define WASM_OP_TABLE_SIZE WASM_OP_FC(16)
125#define WASM_OP_TABLE_FILL WASM_OP_FC(17)
126
127#endif