commit 333f933dd57d8ea74433ff8b24ab2972b7660d07
parent f9ebea8f994b599258edb1f80ff8c84b247b672f
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 3 Jun 2026 10:44:47 -0700
wasm: collapse five parallel instruction switches into one WASM_INSN table
WasmInsnKind was re-derived five times that had to stay in lockstep:
encode's opcode/sub-opcode switches, the WAT mnemonic table, the WAT
parser's mnemonic->kind strcmp chain, and the disassembler's operand-class
grouping. Build one source-of-truth WASM_INSN_TABLE of
{kind, prefix, opcode byte, operand class, mnemonic} rows and derive:
- encode: O(1) row lookup for the single-byte / 0xfc / 0xfe opcode spaces
- wasm_insn_mnemonic: reads the mnemonic column
- wat_instr_kind: linear scan over the table (+ a 3-entry alias list),
has_imm derived from the operand class
- disasm render_operands: switch on the operand class
call_ref/return_call_ref get their own WASM_OC_TYPED_REF class so they
keep encoding/printing a uleb index while the WAT grammar (which takes the
type from context) still parses no trailing immediate.
decode keeps its hand-written byte->kind arms: the per-opcode operand
reads are genuinely irregular and stay the single decode authority via
decode_body_insn. Net -1087 LOC.
The table was cross-checked against the original switches: all 216
mnemonics, 166 single-byte opcodes, 32 threads sub-opcodes, 18 misc
sub-opcodes, 216 has_imm flags, and 216 disasm operand classes match.
(cherry picked from commit 5abd92402f8c1050293bc82f1c8f5dcafe172469)
Diffstat:
| M | src/arch/wasm/disasm.c | | | 62 | +++++++++++++++++++++++++++----------------------------------- |
| M | src/wasm/encode.c | | | 459 | +++---------------------------------------------------------------------------- |
| M | src/wasm/insn.c | | | 230 | +++---------------------------------------------------------------------------- |
| A | src/wasm/wasm_insn_table.c | | | 349 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/wasm/wasm_insn_table.h | | | 62 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/wasm/wat.c | | | 915 | ++++--------------------------------------------------------------------------- |
6 files changed, 495 insertions(+), 1582 deletions(-)
diff --git a/src/arch/wasm/disasm.c b/src/arch/wasm/disasm.c
@@ -18,6 +18,7 @@
#include "core/heap.h"
#include "core/strbuf.h"
#include "wasm/wasm.h"
+#include "wasm/wasm_insn_table.h"
#define WASM_DASM_MNEM_CAP 32u
#define WASM_DASM_OPS_CAP 192u
@@ -70,41 +71,31 @@ static const char* valtype_name(i64 b) {
}
}
-/* Render an instruction's immediate operands into d->ops. */
+/* Render an instruction's immediate operands into d->ops, dispatched on the
+ * shared operand class from WASM_INSN_TABLE rather than re-listing kinds. */
static void render_operands(WasmDisasm* d, const WasmInsn* in) {
- switch ((WasmInsnKind)in->kind) {
- case WASM_INSN_I32_CONST:
- case WASM_INSN_I64_CONST:
+ const WasmInsnInfo* info = wasm_insn_info((WasmInsnKind)in->kind);
+ WasmOperandClass oc = info ? (WasmOperandClass)info->operand_class : WASM_OC_NONE;
+ switch (oc) {
+ case WASM_OC_SLEB:
strbuf_put_i64(&d->ops, in->imm);
break;
- case WASM_INSN_F32_CONST:
- case WASM_INSN_F64_CONST: {
+ case WASM_OC_FP: {
char buf[40];
(void)snprintf(buf, sizeof buf, "%g", in->fp);
strbuf_puts(&d->ops, buf);
break;
}
- case WASM_INSN_LOCAL_GET:
- case WASM_INSN_LOCAL_SET:
- case WASM_INSN_LOCAL_TEE:
- case WASM_INSN_GLOBAL_GET:
- case WASM_INSN_GLOBAL_SET:
- case WASM_INSN_BR:
- case WASM_INSN_BR_IF:
- case WASM_INSN_CALL:
- case WASM_INSN_RETURN_CALL:
- case WASM_INSN_REF_FUNC:
- case WASM_INSN_CALL_REF:
- case WASM_INSN_RETURN_CALL_REF:
+ case WASM_OC_IDX:
+ case WASM_OC_TYPED_REF:
strbuf_put_u64(&d->ops, (u64)in->imm);
break;
- case WASM_INSN_CALL_INDIRECT:
- case WASM_INSN_RETURN_CALL_INDIRECT:
+ case WASM_OC_CALL_INDIRECT:
strbuf_put_u64(&d->ops, (u64)in->imm);
strbuf_puts(&d->ops, " ");
strbuf_put_u64(&d->ops, (u64)in->aux_idx);
break;
- case WASM_INSN_BR_TABLE: {
+ case WASM_OC_BR_TABLE: {
u32 i;
for (i = 0; i < in->ntargets; ++i) {
if (i) strbuf_putc(&d->ops, ' ');
@@ -112,24 +103,25 @@ static void render_operands(WasmDisasm* d, const WasmInsn* in) {
}
break;
}
- case WASM_INSN_REF_NULL:
+ case WASM_OC_REF_NULL:
strbuf_puts(&d->ops, valtype_name(in->imm));
break;
- default:
- if (wasm_insn_is_mem((WasmInsnKind)in->kind)) {
- int wrote = 0;
- if (in->offset64) {
- strbuf_puts(&d->ops, "offset=");
- strbuf_put_u64(&d->ops, in->offset64);
- wrote = 1;
- }
- if (in->align) {
- if (wrote) strbuf_putc(&d->ops, ' ');
- strbuf_puts(&d->ops, "align=");
- strbuf_put_u64(&d->ops, (u64)(1u << in->align));
- }
+ case WASM_OC_MEMARG: {
+ int wrote = 0;
+ if (in->offset64) {
+ strbuf_puts(&d->ops, "offset=");
+ strbuf_put_u64(&d->ops, in->offset64);
+ wrote = 1;
+ }
+ if (in->align) {
+ if (wrote) strbuf_putc(&d->ops, ' ');
+ strbuf_puts(&d->ops, "align=");
+ strbuf_put_u64(&d->ops, (u64)(1u << in->align));
}
break;
+ }
+ default:
+ break;
}
}
diff --git a/src/wasm/encode.c b/src/wasm/encode.c
@@ -1,4 +1,5 @@
#include "wasm/wasm.h"
+#include "wasm/wasm_insn_table.h"
static void write_byte(KitWriter* w, uint8_t b) { w->write(w, &b, 1); }
@@ -213,457 +214,27 @@ static void enc_global(KitWriter* w, const WasmModule* m) {
}
}
+/* Single-byte opcode for `kind` (0 if prefixed or unknown), read off the one
+ * WASM_INSN_TABLE map. */
static uint8_t wasm_opcode(uint8_t kind) {
- switch (kind) {
- case WASM_INSN_UNREACHABLE:
- return 0x00;
- case WASM_INSN_NOP:
- return 0x01;
- case WASM_INSN_BLOCK:
- return 0x02;
- case WASM_INSN_LOOP:
- return 0x03;
- case WASM_INSN_IF:
- return 0x04;
- case WASM_INSN_ELSE:
- return 0x05;
- case WASM_INSN_END:
- return 0x0b;
- case WASM_INSN_BR:
- return 0x0c;
- case WASM_INSN_BR_IF:
- return 0x0d;
- case WASM_INSN_BR_TABLE:
- return 0x0e;
- case WASM_INSN_I32_CONST:
- return 0x41;
- case WASM_INSN_I64_CONST:
- return 0x42;
- case WASM_INSN_F32_CONST:
- return 0x43;
- case WASM_INSN_F64_CONST:
- return 0x44;
- case WASM_INSN_LOCAL_GET:
- return 0x20;
- case WASM_INSN_LOCAL_SET:
- return 0x21;
- case WASM_INSN_LOCAL_TEE:
- return 0x22;
- case WASM_INSN_CALL:
- return 0x10;
- case WASM_INSN_CALL_INDIRECT:
- return 0x11;
- case WASM_INSN_RETURN_CALL:
- return 0x12;
- case WASM_INSN_RETURN_CALL_INDIRECT:
- return 0x13;
- case WASM_INSN_CALL_REF:
- return 0x14;
- case WASM_INSN_RETURN_CALL_REF:
- return 0x15;
- case WASM_INSN_REF_NULL:
- return 0xd0;
- case WASM_INSN_REF_IS_NULL:
- return 0xd1;
- case WASM_INSN_REF_FUNC:
- return 0xd2;
- case WASM_INSN_GLOBAL_GET:
- return 0x23;
- case WASM_INSN_GLOBAL_SET:
- return 0x24;
- case WASM_INSN_RETURN:
- return 0x0f;
- case WASM_INSN_DROP:
- return 0x1a;
- case WASM_INSN_SELECT:
- return 0x1b;
- case WASM_INSN_I32_LOAD:
- return 0x28;
- case WASM_INSN_I64_LOAD:
- return 0x29;
- case WASM_INSN_F32_LOAD:
- return 0x2a;
- case WASM_INSN_F64_LOAD:
- return 0x2b;
- case WASM_INSN_I32_LOAD8_S:
- return 0x2c;
- case WASM_INSN_I32_LOAD8_U:
- return 0x2d;
- case WASM_INSN_I32_LOAD16_S:
- return 0x2e;
- case WASM_INSN_I32_LOAD16_U:
- return 0x2f;
- case WASM_INSN_I64_LOAD8_S:
- return 0x30;
- case WASM_INSN_I64_LOAD8_U:
- return 0x31;
- case WASM_INSN_I64_LOAD16_S:
- return 0x32;
- case WASM_INSN_I64_LOAD16_U:
- return 0x33;
- case WASM_INSN_I64_LOAD32_S:
- return 0x34;
- case WASM_INSN_I64_LOAD32_U:
- return 0x35;
- case WASM_INSN_I32_STORE:
- return 0x36;
- case WASM_INSN_I64_STORE:
- return 0x37;
- case WASM_INSN_F32_STORE:
- return 0x38;
- case WASM_INSN_F64_STORE:
- return 0x39;
- case WASM_INSN_I32_STORE8:
- return 0x3a;
- case WASM_INSN_I32_STORE16:
- return 0x3b;
- case WASM_INSN_I64_STORE8:
- return 0x3c;
- case WASM_INSN_I64_STORE16:
- return 0x3d;
- case WASM_INSN_I64_STORE32:
- return 0x3e;
- case WASM_INSN_MEMORY_SIZE:
- return 0x3f;
- case WASM_INSN_MEMORY_GROW:
- return 0x40;
- case WASM_INSN_I32_EQZ:
- return 0x45;
- case WASM_INSN_I32_EQ:
- return 0x46;
- case WASM_INSN_I32_NE:
- return 0x47;
- case WASM_INSN_I32_LT_S:
- return 0x48;
- case WASM_INSN_I32_LT_U:
- return 0x49;
- case WASM_INSN_I32_GT_S:
- return 0x4a;
- case WASM_INSN_I32_GT_U:
- return 0x4b;
- case WASM_INSN_I32_LE_S:
- return 0x4c;
- case WASM_INSN_I32_LE_U:
- return 0x4d;
- case WASM_INSN_I32_GE_S:
- return 0x4e;
- case WASM_INSN_I32_GE_U:
- return 0x4f;
- case WASM_INSN_I64_EQZ:
- return 0x50;
- case WASM_INSN_I64_EQ:
- return 0x51;
- case WASM_INSN_I64_NE:
- return 0x52;
- case WASM_INSN_I64_LT_S:
- return 0x53;
- case WASM_INSN_I64_LT_U:
- return 0x54;
- case WASM_INSN_I64_GT_S:
- return 0x55;
- case WASM_INSN_I64_GT_U:
- return 0x56;
- case WASM_INSN_I64_LE_S:
- return 0x57;
- case WASM_INSN_I64_LE_U:
- return 0x58;
- case WASM_INSN_I64_GE_S:
- return 0x59;
- case WASM_INSN_I64_GE_U:
- return 0x5a;
- case WASM_INSN_I32_ADD:
- return 0x6a;
- case WASM_INSN_I32_SUB:
- return 0x6b;
- case WASM_INSN_I32_MUL:
- return 0x6c;
- case WASM_INSN_I32_DIV_S:
- return 0x6d;
- case WASM_INSN_I32_DIV_U:
- return 0x6e;
- case WASM_INSN_I32_REM_S:
- return 0x6f;
- case WASM_INSN_I32_REM_U:
- return 0x70;
- case WASM_INSN_I32_AND:
- return 0x71;
- case WASM_INSN_I32_OR:
- return 0x72;
- case WASM_INSN_I32_XOR:
- return 0x73;
- case WASM_INSN_I32_SHL:
- return 0x74;
- case WASM_INSN_I32_SHR_S:
- return 0x75;
- case WASM_INSN_I32_SHR_U:
- return 0x76;
- case WASM_INSN_I32_CLZ:
- return 0x67;
- case WASM_INSN_I32_CTZ:
- return 0x68;
- case WASM_INSN_I32_POPCNT:
- return 0x69;
- case WASM_INSN_I32_ROTL:
- return 0x77;
- case WASM_INSN_I32_ROTR:
- return 0x78;
- case WASM_INSN_I64_CLZ:
- return 0x79;
- case WASM_INSN_I64_CTZ:
- return 0x7a;
- case WASM_INSN_I64_POPCNT:
- return 0x7b;
- case WASM_INSN_I64_ADD:
- return 0x7c;
- case WASM_INSN_I64_SUB:
- return 0x7d;
- case WASM_INSN_I64_MUL:
- return 0x7e;
- case WASM_INSN_I64_DIV_S:
- return 0x7f;
- case WASM_INSN_I64_DIV_U:
- return 0x80;
- case WASM_INSN_I64_REM_S:
- return 0x81;
- case WASM_INSN_I64_REM_U:
- return 0x82;
- case WASM_INSN_I64_AND:
- return 0x83;
- case WASM_INSN_I64_OR:
- return 0x84;
- case WASM_INSN_I64_XOR:
- return 0x85;
- case WASM_INSN_I64_SHL:
- return 0x86;
- case WASM_INSN_I64_SHR_S:
- return 0x87;
- case WASM_INSN_I64_SHR_U:
- return 0x88;
- case WASM_INSN_I64_ROTL:
- return 0x89;
- case WASM_INSN_I64_ROTR:
- return 0x8a;
- case WASM_INSN_F32_ADD:
- return 0x92;
- case WASM_INSN_F32_SUB:
- return 0x93;
- case WASM_INSN_F32_MUL:
- return 0x94;
- case WASM_INSN_F32_DIV:
- return 0x95;
- case WASM_INSN_F64_ADD:
- return 0xa0;
- case WASM_INSN_F64_SUB:
- return 0xa1;
- case WASM_INSN_F64_MUL:
- return 0xa2;
- case WASM_INSN_F64_DIV:
- return 0xa3;
- case WASM_INSN_F32_EQ:
- return 0x5b;
- case WASM_INSN_F32_NE:
- return 0x5c;
- case WASM_INSN_F32_LT:
- return 0x5d;
- case WASM_INSN_F32_GT:
- return 0x5e;
- case WASM_INSN_F32_LE:
- return 0x5f;
- case WASM_INSN_F32_GE:
- return 0x60;
- case WASM_INSN_F64_EQ:
- return 0x61;
- case WASM_INSN_F64_NE:
- return 0x62;
- case WASM_INSN_F64_LT:
- return 0x63;
- case WASM_INSN_F64_GT:
- return 0x64;
- case WASM_INSN_F64_LE:
- return 0x65;
- case WASM_INSN_F64_GE:
- return 0x66;
- case WASM_INSN_F32_NEG:
- return 0x8c;
- case WASM_INSN_F64_NEG:
- return 0x9a;
- case WASM_INSN_I32_WRAP_I64:
- return 0xa7;
- case WASM_INSN_I32_TRUNC_F32_S:
- return 0xa8;
- case WASM_INSN_I32_TRUNC_F32_U:
- return 0xa9;
- case WASM_INSN_I32_TRUNC_F64_S:
- return 0xaa;
- case WASM_INSN_I32_TRUNC_F64_U:
- return 0xab;
- case WASM_INSN_I64_EXTEND_I32_S:
- return 0xac;
- case WASM_INSN_I64_EXTEND_I32_U:
- return 0xad;
- case WASM_INSN_I64_TRUNC_F32_S:
- return 0xae;
- case WASM_INSN_I64_TRUNC_F32_U:
- return 0xaf;
- case WASM_INSN_I64_TRUNC_F64_S:
- return 0xb0;
- case WASM_INSN_I64_TRUNC_F64_U:
- return 0xb1;
- case WASM_INSN_F32_CONVERT_I32_S:
- return 0xb2;
- case WASM_INSN_F32_CONVERT_I32_U:
- return 0xb3;
- case WASM_INSN_F32_CONVERT_I64_S:
- return 0xb4;
- case WASM_INSN_F32_CONVERT_I64_U:
- return 0xb5;
- case WASM_INSN_F32_DEMOTE_F64:
- return 0xb6;
- case WASM_INSN_F64_CONVERT_I32_S:
- return 0xb7;
- case WASM_INSN_F64_CONVERT_I32_U:
- return 0xb8;
- case WASM_INSN_F64_CONVERT_I64_S:
- return 0xb9;
- case WASM_INSN_F64_CONVERT_I64_U:
- return 0xba;
- case WASM_INSN_F64_PROMOTE_F32:
- return 0xbb;
- case WASM_INSN_I32_REINTERPRET_F32:
- return 0xbc;
- case WASM_INSN_I64_REINTERPRET_F64:
- return 0xbd;
- case WASM_INSN_F32_REINTERPRET_I32:
- return 0xbe;
- case WASM_INSN_F64_REINTERPRET_I64:
- return 0xbf;
- case WASM_INSN_I32_EXTEND8_S:
- return 0xc0;
- case WASM_INSN_I32_EXTEND16_S:
- return 0xc1;
- case WASM_INSN_I64_EXTEND8_S:
- return 0xc2;
- case WASM_INSN_I64_EXTEND16_S:
- return 0xc3;
- case WASM_INSN_I64_EXTEND32_S:
- return 0xc4;
- }
- return 0;
+ const WasmInsnInfo* info = wasm_insn_info((WasmInsnKind)kind);
+ if (!info || info->prefix != WASM_PREFIX_NONE) return 0;
+ return info->byte;
}
+/* 0xfe-prefixed (threads/atomics) sub-opcode for `kind`, or UINT32_MAX. */
static uint32_t wasm_threads_subopcode(uint8_t kind) {
- switch (kind) {
- case WASM_INSN_MEMORY_ATOMIC_NOTIFY:
- return 0x00;
- case WASM_INSN_I32_ATOMIC_WAIT:
- return 0x01;
- case WASM_INSN_I64_ATOMIC_WAIT:
- return 0x02;
- case WASM_INSN_ATOMIC_FENCE:
- return 0x03;
- case WASM_INSN_I32_ATOMIC_LOAD:
- return 0x10;
- case WASM_INSN_I64_ATOMIC_LOAD:
- return 0x11;
- case WASM_INSN_I32_ATOMIC_LOAD8_U:
- return 0x12;
- case WASM_INSN_I32_ATOMIC_LOAD16_U:
- return 0x13;
- case WASM_INSN_I64_ATOMIC_LOAD8_U:
- return 0x14;
- case WASM_INSN_I64_ATOMIC_LOAD16_U:
- return 0x15;
- case WASM_INSN_I64_ATOMIC_LOAD32_U:
- return 0x16;
- case WASM_INSN_I32_ATOMIC_STORE:
- return 0x17;
- case WASM_INSN_I64_ATOMIC_STORE:
- return 0x18;
- case WASM_INSN_I32_ATOMIC_STORE8:
- return 0x19;
- case WASM_INSN_I32_ATOMIC_STORE16:
- return 0x1a;
- case WASM_INSN_I64_ATOMIC_STORE8:
- return 0x1b;
- case WASM_INSN_I64_ATOMIC_STORE16:
- return 0x1c;
- case WASM_INSN_I64_ATOMIC_STORE32:
- return 0x1d;
- case WASM_INSN_I32_ATOMIC_RMW_ADD:
- return 0x1e;
- case WASM_INSN_I64_ATOMIC_RMW_ADD:
- return 0x1f;
- case WASM_INSN_I32_ATOMIC_RMW_SUB:
- return 0x25;
- case WASM_INSN_I64_ATOMIC_RMW_SUB:
- return 0x26;
- case WASM_INSN_I32_ATOMIC_RMW_AND:
- return 0x2c;
- case WASM_INSN_I64_ATOMIC_RMW_AND:
- return 0x2d;
- case WASM_INSN_I32_ATOMIC_RMW_OR:
- return 0x33;
- case WASM_INSN_I64_ATOMIC_RMW_OR:
- return 0x34;
- case WASM_INSN_I32_ATOMIC_RMW_XOR:
- return 0x3a;
- case WASM_INSN_I64_ATOMIC_RMW_XOR:
- return 0x3b;
- case WASM_INSN_I32_ATOMIC_RMW_XCHG:
- return 0x41;
- case WASM_INSN_I64_ATOMIC_RMW_XCHG:
- return 0x42;
- case WASM_INSN_I32_ATOMIC_RMW_CMPXCHG:
- return 0x48;
- case WASM_INSN_I64_ATOMIC_RMW_CMPXCHG:
- return 0x49;
- default:
- return UINT32_MAX;
- }
+ const WasmInsnInfo* info = wasm_insn_info((WasmInsnKind)kind);
+ if (!info || info->prefix != WASM_PREFIX_FE) return UINT32_MAX;
+ return info->byte;
}
-/* 0xfc-prefixed sub-opcodes: non-trapping FTOI and bulk memory ops. */
+/* 0xfc-prefixed sub-opcode (non-trapping FTOI + bulk memory/table) for `kind`,
+ * or UINT32_MAX. */
static uint32_t wasm_misc_subopcode(uint8_t kind) {
- switch (kind) {
- case WASM_INSN_I32_TRUNC_SAT_F32_S:
- return 0x00;
- case WASM_INSN_I32_TRUNC_SAT_F32_U:
- return 0x01;
- case WASM_INSN_I32_TRUNC_SAT_F64_S:
- return 0x02;
- case WASM_INSN_I32_TRUNC_SAT_F64_U:
- return 0x03;
- case WASM_INSN_I64_TRUNC_SAT_F32_S:
- return 0x04;
- case WASM_INSN_I64_TRUNC_SAT_F32_U:
- return 0x05;
- case WASM_INSN_I64_TRUNC_SAT_F64_S:
- return 0x06;
- case WASM_INSN_I64_TRUNC_SAT_F64_U:
- return 0x07;
- case WASM_INSN_MEMORY_INIT:
- return 0x08;
- case WASM_INSN_DATA_DROP:
- return 0x09;
- case WASM_INSN_MEMORY_COPY:
- return 0x0a;
- case WASM_INSN_MEMORY_FILL:
- return 0x0b;
- case WASM_INSN_TABLE_INIT:
- return 0x0c;
- case WASM_INSN_ELEM_DROP:
- return 0x0d;
- case WASM_INSN_TABLE_COPY:
- return 0x0e;
- case WASM_INSN_TABLE_GROW:
- return 0x0f;
- case WASM_INSN_TABLE_SIZE:
- return 0x10;
- case WASM_INSN_TABLE_FILL:
- return 0x11;
- default:
- return UINT32_MAX;
- }
+ const WasmInsnInfo* info = wasm_insn_info((WasmInsnKind)kind);
+ if (!info || info->prefix != WASM_PREFIX_FC) return UINT32_MAX;
+ return info->byte;
}
static void enc_code(KitWriter* w, const WasmModule* m) {
diff --git a/src/wasm/insn.c b/src/wasm/insn.c
@@ -1,4 +1,5 @@
#include "wasm/wasm.h"
+#include "wasm/wasm_insn_table.h"
int wasm_is_num_type(WasmValType vt) {
return vt == WASM_VAL_I32 || vt == WASM_VAL_I64 || vt == WASM_VAL_F32 ||
@@ -434,229 +435,10 @@ int wasm_conversion_kind(uint8_t kind, WasmValType* src, WasmValType* dst) {
}
}
-/* WAT mnemonic for an instruction kind. Spellings match the WAT parser in
- * wat.c so the disassembler and assembler agree. Returns ".unknown" for any
- * out-of-range kind rather than NULL so callers can print unconditionally. */
+/* WAT mnemonic for an instruction kind. Spellings live in WASM_INSN_TABLE so
+ * the encoder, disassembler, and WAT parser all agree. Returns ".unknown" for
+ * any out-of-range kind rather than NULL so callers can print unconditionally. */
const char* wasm_insn_mnemonic(WasmInsnKind kind) {
- static const char* const names[] = {
- [WASM_INSN_UNREACHABLE] = "unreachable",
- [WASM_INSN_NOP] = "nop",
- [WASM_INSN_BLOCK] = "block",
- [WASM_INSN_LOOP] = "loop",
- [WASM_INSN_IF] = "if",
- [WASM_INSN_ELSE] = "else",
- [WASM_INSN_END] = "end",
- [WASM_INSN_BR] = "br",
- [WASM_INSN_BR_IF] = "br_if",
- [WASM_INSN_BR_TABLE] = "br_table",
- [WASM_INSN_SELECT] = "select",
- [WASM_INSN_F32_CONST] = "f32.const",
- [WASM_INSN_F64_CONST] = "f64.const",
- [WASM_INSN_I32_CONST] = "i32.const",
- [WASM_INSN_I64_CONST] = "i64.const",
- [WASM_INSN_LOCAL_GET] = "local.get",
- [WASM_INSN_LOCAL_SET] = "local.set",
- [WASM_INSN_LOCAL_TEE] = "local.tee",
- [WASM_INSN_CALL] = "call",
- [WASM_INSN_CALL_INDIRECT] = "call_indirect",
- [WASM_INSN_RETURN_CALL] = "return_call",
- [WASM_INSN_RETURN_CALL_INDIRECT] = "return_call_indirect",
- [WASM_INSN_REF_NULL] = "ref.null",
- [WASM_INSN_REF_FUNC] = "ref.func",
- [WASM_INSN_REF_IS_NULL] = "ref.is_null",
- [WASM_INSN_CALL_REF] = "call_ref",
- [WASM_INSN_RETURN_CALL_REF] = "return_call_ref",
- [WASM_INSN_GLOBAL_GET] = "global.get",
- [WASM_INSN_GLOBAL_SET] = "global.set",
- [WASM_INSN_RETURN] = "return",
- [WASM_INSN_DROP] = "drop",
- [WASM_INSN_I32_LOAD] = "i32.load",
- [WASM_INSN_I64_LOAD] = "i64.load",
- [WASM_INSN_F32_LOAD] = "f32.load",
- [WASM_INSN_F64_LOAD] = "f64.load",
- [WASM_INSN_I32_LOAD8_S] = "i32.load8_s",
- [WASM_INSN_I32_LOAD8_U] = "i32.load8_u",
- [WASM_INSN_I32_LOAD16_S] = "i32.load16_s",
- [WASM_INSN_I32_LOAD16_U] = "i32.load16_u",
- [WASM_INSN_I64_LOAD8_S] = "i64.load8_s",
- [WASM_INSN_I64_LOAD8_U] = "i64.load8_u",
- [WASM_INSN_I64_LOAD16_S] = "i64.load16_s",
- [WASM_INSN_I64_LOAD16_U] = "i64.load16_u",
- [WASM_INSN_I64_LOAD32_S] = "i64.load32_s",
- [WASM_INSN_I64_LOAD32_U] = "i64.load32_u",
- [WASM_INSN_I32_STORE] = "i32.store",
- [WASM_INSN_I64_STORE] = "i64.store",
- [WASM_INSN_F32_STORE] = "f32.store",
- [WASM_INSN_F64_STORE] = "f64.store",
- [WASM_INSN_I32_STORE8] = "i32.store8",
- [WASM_INSN_I32_STORE16] = "i32.store16",
- [WASM_INSN_I64_STORE8] = "i64.store8",
- [WASM_INSN_I64_STORE16] = "i64.store16",
- [WASM_INSN_I64_STORE32] = "i64.store32",
- [WASM_INSN_MEMORY_SIZE] = "memory.size",
- [WASM_INSN_MEMORY_GROW] = "memory.grow",
- [WASM_INSN_ATOMIC_FENCE] = "atomic.fence",
- [WASM_INSN_I32_ATOMIC_LOAD] = "i32.atomic.load",
- [WASM_INSN_I64_ATOMIC_LOAD] = "i64.atomic.load",
- [WASM_INSN_I32_ATOMIC_LOAD8_U] = "i32.atomic.load8_u",
- [WASM_INSN_I32_ATOMIC_LOAD16_U] = "i32.atomic.load16_u",
- [WASM_INSN_I64_ATOMIC_LOAD8_U] = "i64.atomic.load8_u",
- [WASM_INSN_I64_ATOMIC_LOAD16_U] = "i64.atomic.load16_u",
- [WASM_INSN_I64_ATOMIC_LOAD32_U] = "i64.atomic.load32_u",
- [WASM_INSN_I32_ATOMIC_STORE] = "i32.atomic.store",
- [WASM_INSN_I64_ATOMIC_STORE] = "i64.atomic.store",
- [WASM_INSN_I32_ATOMIC_STORE8] = "i32.atomic.store8",
- [WASM_INSN_I32_ATOMIC_STORE16] = "i32.atomic.store16",
- [WASM_INSN_I64_ATOMIC_STORE8] = "i64.atomic.store8",
- [WASM_INSN_I64_ATOMIC_STORE16] = "i64.atomic.store16",
- [WASM_INSN_I64_ATOMIC_STORE32] = "i64.atomic.store32",
- [WASM_INSN_I32_ATOMIC_RMW_ADD] = "i32.atomic.rmw.add",
- [WASM_INSN_I64_ATOMIC_RMW_ADD] = "i64.atomic.rmw.add",
- [WASM_INSN_I32_ATOMIC_RMW_SUB] = "i32.atomic.rmw.sub",
- [WASM_INSN_I64_ATOMIC_RMW_SUB] = "i64.atomic.rmw.sub",
- [WASM_INSN_I32_ATOMIC_RMW_AND] = "i32.atomic.rmw.and",
- [WASM_INSN_I64_ATOMIC_RMW_AND] = "i64.atomic.rmw.and",
- [WASM_INSN_I32_ATOMIC_RMW_OR] = "i32.atomic.rmw.or",
- [WASM_INSN_I64_ATOMIC_RMW_OR] = "i64.atomic.rmw.or",
- [WASM_INSN_I32_ATOMIC_RMW_XOR] = "i32.atomic.rmw.xor",
- [WASM_INSN_I64_ATOMIC_RMW_XOR] = "i64.atomic.rmw.xor",
- [WASM_INSN_I32_ATOMIC_RMW_XCHG] = "i32.atomic.rmw.xchg",
- [WASM_INSN_I64_ATOMIC_RMW_XCHG] = "i64.atomic.rmw.xchg",
- [WASM_INSN_I32_ATOMIC_RMW_CMPXCHG] = "i32.atomic.rmw.cmpxchg",
- [WASM_INSN_I64_ATOMIC_RMW_CMPXCHG] = "i64.atomic.rmw.cmpxchg",
- [WASM_INSN_I32_ATOMIC_WAIT] = "memory.atomic.wait32",
- [WASM_INSN_I64_ATOMIC_WAIT] = "memory.atomic.wait64",
- [WASM_INSN_MEMORY_ATOMIC_NOTIFY] = "memory.atomic.notify",
- [WASM_INSN_I32_ADD] = "i32.add",
- [WASM_INSN_I32_SUB] = "i32.sub",
- [WASM_INSN_I32_MUL] = "i32.mul",
- [WASM_INSN_I32_DIV_S] = "i32.div_s",
- [WASM_INSN_I32_DIV_U] = "i32.div_u",
- [WASM_INSN_I32_REM_S] = "i32.rem_s",
- [WASM_INSN_I32_REM_U] = "i32.rem_u",
- [WASM_INSN_I32_AND] = "i32.and",
- [WASM_INSN_I32_OR] = "i32.or",
- [WASM_INSN_I32_XOR] = "i32.xor",
- [WASM_INSN_I32_SHL] = "i32.shl",
- [WASM_INSN_I32_SHR_S] = "i32.shr_s",
- [WASM_INSN_I32_SHR_U] = "i32.shr_u",
- [WASM_INSN_I32_ROTL] = "i32.rotl",
- [WASM_INSN_I32_ROTR] = "i32.rotr",
- [WASM_INSN_I32_CLZ] = "i32.clz",
- [WASM_INSN_I32_CTZ] = "i32.ctz",
- [WASM_INSN_I32_POPCNT] = "i32.popcnt",
- [WASM_INSN_I32_EQZ] = "i32.eqz",
- [WASM_INSN_I32_EQ] = "i32.eq",
- [WASM_INSN_I32_NE] = "i32.ne",
- [WASM_INSN_I32_LT_S] = "i32.lt_s",
- [WASM_INSN_I32_LT_U] = "i32.lt_u",
- [WASM_INSN_I32_GT_S] = "i32.gt_s",
- [WASM_INSN_I32_GT_U] = "i32.gt_u",
- [WASM_INSN_I32_LE_S] = "i32.le_s",
- [WASM_INSN_I32_LE_U] = "i32.le_u",
- [WASM_INSN_I32_GE_S] = "i32.ge_s",
- [WASM_INSN_I32_GE_U] = "i32.ge_u",
- [WASM_INSN_I64_ADD] = "i64.add",
- [WASM_INSN_I64_SUB] = "i64.sub",
- [WASM_INSN_I64_MUL] = "i64.mul",
- [WASM_INSN_I64_DIV_S] = "i64.div_s",
- [WASM_INSN_I64_DIV_U] = "i64.div_u",
- [WASM_INSN_I64_REM_S] = "i64.rem_s",
- [WASM_INSN_I64_REM_U] = "i64.rem_u",
- [WASM_INSN_I64_AND] = "i64.and",
- [WASM_INSN_I64_OR] = "i64.or",
- [WASM_INSN_I64_XOR] = "i64.xor",
- [WASM_INSN_I64_SHL] = "i64.shl",
- [WASM_INSN_I64_SHR_S] = "i64.shr_s",
- [WASM_INSN_I64_SHR_U] = "i64.shr_u",
- [WASM_INSN_I64_ROTL] = "i64.rotl",
- [WASM_INSN_I64_ROTR] = "i64.rotr",
- [WASM_INSN_I64_CLZ] = "i64.clz",
- [WASM_INSN_I64_CTZ] = "i64.ctz",
- [WASM_INSN_I64_POPCNT] = "i64.popcnt",
- [WASM_INSN_I64_EQZ] = "i64.eqz",
- [WASM_INSN_I64_EQ] = "i64.eq",
- [WASM_INSN_I64_NE] = "i64.ne",
- [WASM_INSN_I64_LT_S] = "i64.lt_s",
- [WASM_INSN_I64_LT_U] = "i64.lt_u",
- [WASM_INSN_I64_GT_S] = "i64.gt_s",
- [WASM_INSN_I64_GT_U] = "i64.gt_u",
- [WASM_INSN_I64_LE_S] = "i64.le_s",
- [WASM_INSN_I64_LE_U] = "i64.le_u",
- [WASM_INSN_I64_GE_S] = "i64.ge_s",
- [WASM_INSN_I64_GE_U] = "i64.ge_u",
- [WASM_INSN_F32_ADD] = "f32.add",
- [WASM_INSN_F32_SUB] = "f32.sub",
- [WASM_INSN_F32_MUL] = "f32.mul",
- [WASM_INSN_F32_DIV] = "f32.div",
- [WASM_INSN_F32_EQ] = "f32.eq",
- [WASM_INSN_F32_NE] = "f32.ne",
- [WASM_INSN_F32_LT] = "f32.lt",
- [WASM_INSN_F32_GT] = "f32.gt",
- [WASM_INSN_F32_LE] = "f32.le",
- [WASM_INSN_F32_GE] = "f32.ge",
- [WASM_INSN_F64_ADD] = "f64.add",
- [WASM_INSN_F64_SUB] = "f64.sub",
- [WASM_INSN_F64_MUL] = "f64.mul",
- [WASM_INSN_F64_DIV] = "f64.div",
- [WASM_INSN_F64_EQ] = "f64.eq",
- [WASM_INSN_F64_NE] = "f64.ne",
- [WASM_INSN_F64_LT] = "f64.lt",
- [WASM_INSN_F64_GT] = "f64.gt",
- [WASM_INSN_F64_LE] = "f64.le",
- [WASM_INSN_F64_GE] = "f64.ge",
- [WASM_INSN_F32_NEG] = "f32.neg",
- [WASM_INSN_F64_NEG] = "f64.neg",
- [WASM_INSN_I32_WRAP_I64] = "i32.wrap_i64",
- [WASM_INSN_I32_TRUNC_F32_S] = "i32.trunc_f32_s",
- [WASM_INSN_I32_TRUNC_F32_U] = "i32.trunc_f32_u",
- [WASM_INSN_I32_TRUNC_F64_S] = "i32.trunc_f64_s",
- [WASM_INSN_I32_TRUNC_F64_U] = "i32.trunc_f64_u",
- [WASM_INSN_I64_EXTEND_I32_S] = "i64.extend_i32_s",
- [WASM_INSN_I64_EXTEND_I32_U] = "i64.extend_i32_u",
- [WASM_INSN_I64_TRUNC_F32_S] = "i64.trunc_f32_s",
- [WASM_INSN_I64_TRUNC_F32_U] = "i64.trunc_f32_u",
- [WASM_INSN_I64_TRUNC_F64_S] = "i64.trunc_f64_s",
- [WASM_INSN_I64_TRUNC_F64_U] = "i64.trunc_f64_u",
- [WASM_INSN_F32_CONVERT_I32_S] = "f32.convert_i32_s",
- [WASM_INSN_F32_CONVERT_I32_U] = "f32.convert_i32_u",
- [WASM_INSN_F32_CONVERT_I64_S] = "f32.convert_i64_s",
- [WASM_INSN_F32_CONVERT_I64_U] = "f32.convert_i64_u",
- [WASM_INSN_F32_DEMOTE_F64] = "f32.demote_f64",
- [WASM_INSN_F64_CONVERT_I32_S] = "f64.convert_i32_s",
- [WASM_INSN_F64_CONVERT_I32_U] = "f64.convert_i32_u",
- [WASM_INSN_F64_CONVERT_I64_S] = "f64.convert_i64_s",
- [WASM_INSN_F64_CONVERT_I64_U] = "f64.convert_i64_u",
- [WASM_INSN_F64_PROMOTE_F32] = "f64.promote_f32",
- [WASM_INSN_I32_REINTERPRET_F32] = "i32.reinterpret_f32",
- [WASM_INSN_I64_REINTERPRET_F64] = "i64.reinterpret_f64",
- [WASM_INSN_F32_REINTERPRET_I32] = "f32.reinterpret_i32",
- [WASM_INSN_F64_REINTERPRET_I64] = "f64.reinterpret_i64",
- [WASM_INSN_I32_EXTEND8_S] = "i32.extend8_s",
- [WASM_INSN_I32_EXTEND16_S] = "i32.extend16_s",
- [WASM_INSN_I64_EXTEND8_S] = "i64.extend8_s",
- [WASM_INSN_I64_EXTEND16_S] = "i64.extend16_s",
- [WASM_INSN_I64_EXTEND32_S] = "i64.extend32_s",
- [WASM_INSN_I32_TRUNC_SAT_F32_S] = "i32.trunc_sat_f32_s",
- [WASM_INSN_I32_TRUNC_SAT_F32_U] = "i32.trunc_sat_f32_u",
- [WASM_INSN_I32_TRUNC_SAT_F64_S] = "i32.trunc_sat_f64_s",
- [WASM_INSN_I32_TRUNC_SAT_F64_U] = "i32.trunc_sat_f64_u",
- [WASM_INSN_I64_TRUNC_SAT_F32_S] = "i64.trunc_sat_f32_s",
- [WASM_INSN_I64_TRUNC_SAT_F32_U] = "i64.trunc_sat_f32_u",
- [WASM_INSN_I64_TRUNC_SAT_F64_S] = "i64.trunc_sat_f64_s",
- [WASM_INSN_I64_TRUNC_SAT_F64_U] = "i64.trunc_sat_f64_u",
- [WASM_INSN_MEMORY_INIT] = "memory.init",
- [WASM_INSN_DATA_DROP] = "data.drop",
- [WASM_INSN_MEMORY_COPY] = "memory.copy",
- [WASM_INSN_MEMORY_FILL] = "memory.fill",
- [WASM_INSN_TABLE_INIT] = "table.init",
- [WASM_INSN_ELEM_DROP] = "elem.drop",
- [WASM_INSN_TABLE_COPY] = "table.copy",
- [WASM_INSN_TABLE_GROW] = "table.grow",
- [WASM_INSN_TABLE_SIZE] = "table.size",
- [WASM_INSN_TABLE_FILL] = "table.fill",
- };
- if ((unsigned)kind >= sizeof(names) / sizeof(names[0]) || !names[kind])
- return ".unknown";
- return names[kind];
+ const WasmInsnInfo* info = wasm_insn_info(kind);
+ return info ? info->mnemonic : ".unknown";
}
diff --git a/src/wasm/wasm_insn_table.c b/src/wasm/wasm_insn_table.c
@@ -0,0 +1,349 @@
+#include "wasm/wasm_insn_table.h"
+
+/* The one map. Each row is {kind, prefix, opcode-byte, operand-class, mnemonic}.
+ * Rows are designated-initialized by kind so the array stays enum-indexed (the
+ * mnemonic helper, encode's O(1) lookup, and the byte->kind reverse index all
+ * rely on that). Opcode bytes and prefixes mirror the Wasm binary format;
+ * operand classes mirror how encode writes / decode reads / WAT parses the
+ * immediates. */
+#define I(k, pfx, b, oc, mn) \
+ [k] = {(uint8_t)(k), (uint8_t)(pfx), (uint8_t)(b), (uint8_t)(oc), mn}
+
+static const WasmInsnInfo WASM_INSN_TABLE[] = {
+ I(WASM_INSN_UNREACHABLE, WASM_PREFIX_NONE, 0x00, WASM_OC_NONE,
+ "unreachable"),
+ I(WASM_INSN_NOP, WASM_PREFIX_NONE, 0x01, WASM_OC_NONE, "nop"),
+ I(WASM_INSN_BLOCK, WASM_PREFIX_NONE, 0x02, WASM_OC_BLOCK_TYPE, "block"),
+ I(WASM_INSN_LOOP, WASM_PREFIX_NONE, 0x03, WASM_OC_BLOCK_TYPE, "loop"),
+ I(WASM_INSN_IF, WASM_PREFIX_NONE, 0x04, WASM_OC_BLOCK_TYPE, "if"),
+ I(WASM_INSN_ELSE, WASM_PREFIX_NONE, 0x05, WASM_OC_NONE, "else"),
+ I(WASM_INSN_END, WASM_PREFIX_NONE, 0x0b, WASM_OC_NONE, "end"),
+ I(WASM_INSN_BR, WASM_PREFIX_NONE, 0x0c, WASM_OC_IDX, "br"),
+ I(WASM_INSN_BR_IF, WASM_PREFIX_NONE, 0x0d, WASM_OC_IDX, "br_if"),
+ I(WASM_INSN_BR_TABLE, WASM_PREFIX_NONE, 0x0e, WASM_OC_BR_TABLE, "br_table"),
+ I(WASM_INSN_SELECT, WASM_PREFIX_NONE, 0x1b, WASM_OC_NONE, "select"),
+ I(WASM_INSN_F32_CONST, WASM_PREFIX_NONE, 0x43, WASM_OC_FP, "f32.const"),
+ I(WASM_INSN_F64_CONST, WASM_PREFIX_NONE, 0x44, WASM_OC_FP, "f64.const"),
+ I(WASM_INSN_I32_CONST, WASM_PREFIX_NONE, 0x41, WASM_OC_SLEB, "i32.const"),
+ I(WASM_INSN_I64_CONST, WASM_PREFIX_NONE, 0x42, WASM_OC_SLEB, "i64.const"),
+ I(WASM_INSN_LOCAL_GET, WASM_PREFIX_NONE, 0x20, WASM_OC_IDX, "local.get"),
+ I(WASM_INSN_LOCAL_SET, WASM_PREFIX_NONE, 0x21, WASM_OC_IDX, "local.set"),
+ I(WASM_INSN_LOCAL_TEE, WASM_PREFIX_NONE, 0x22, WASM_OC_IDX, "local.tee"),
+ I(WASM_INSN_CALL, WASM_PREFIX_NONE, 0x10, WASM_OC_IDX, "call"),
+ I(WASM_INSN_CALL_INDIRECT, WASM_PREFIX_NONE, 0x11, WASM_OC_CALL_INDIRECT,
+ "call_indirect"),
+ I(WASM_INSN_RETURN_CALL, WASM_PREFIX_NONE, 0x12, WASM_OC_IDX,
+ "return_call"),
+ I(WASM_INSN_RETURN_CALL_INDIRECT, WASM_PREFIX_NONE, 0x13,
+ WASM_OC_CALL_INDIRECT, "return_call_indirect"),
+ I(WASM_INSN_REF_NULL, WASM_PREFIX_NONE, 0xd0, WASM_OC_REF_NULL, "ref.null"),
+ I(WASM_INSN_REF_FUNC, WASM_PREFIX_NONE, 0xd2, WASM_OC_IDX, "ref.func"),
+ I(WASM_INSN_REF_IS_NULL, WASM_PREFIX_NONE, 0xd1, WASM_OC_NONE,
+ "ref.is_null"),
+ I(WASM_INSN_CALL_REF, WASM_PREFIX_NONE, 0x14, WASM_OC_TYPED_REF,
+ "call_ref"),
+ I(WASM_INSN_RETURN_CALL_REF, WASM_PREFIX_NONE, 0x15, WASM_OC_TYPED_REF,
+ "return_call_ref"),
+ I(WASM_INSN_GLOBAL_GET, WASM_PREFIX_NONE, 0x23, WASM_OC_IDX, "global.get"),
+ I(WASM_INSN_GLOBAL_SET, WASM_PREFIX_NONE, 0x24, WASM_OC_IDX, "global.set"),
+ I(WASM_INSN_RETURN, WASM_PREFIX_NONE, 0x0f, WASM_OC_NONE, "return"),
+ I(WASM_INSN_DROP, WASM_PREFIX_NONE, 0x1a, WASM_OC_NONE, "drop"),
+ I(WASM_INSN_I32_LOAD, WASM_PREFIX_NONE, 0x28, WASM_OC_MEMARG, "i32.load"),
+ I(WASM_INSN_I64_LOAD, WASM_PREFIX_NONE, 0x29, WASM_OC_MEMARG, "i64.load"),
+ I(WASM_INSN_F32_LOAD, WASM_PREFIX_NONE, 0x2a, WASM_OC_MEMARG, "f32.load"),
+ I(WASM_INSN_F64_LOAD, WASM_PREFIX_NONE, 0x2b, WASM_OC_MEMARG, "f64.load"),
+ I(WASM_INSN_I32_LOAD8_S, WASM_PREFIX_NONE, 0x2c, WASM_OC_MEMARG,
+ "i32.load8_s"),
+ I(WASM_INSN_I32_LOAD8_U, WASM_PREFIX_NONE, 0x2d, WASM_OC_MEMARG,
+ "i32.load8_u"),
+ I(WASM_INSN_I32_LOAD16_S, WASM_PREFIX_NONE, 0x2e, WASM_OC_MEMARG,
+ "i32.load16_s"),
+ I(WASM_INSN_I32_LOAD16_U, WASM_PREFIX_NONE, 0x2f, WASM_OC_MEMARG,
+ "i32.load16_u"),
+ I(WASM_INSN_I64_LOAD8_S, WASM_PREFIX_NONE, 0x30, WASM_OC_MEMARG,
+ "i64.load8_s"),
+ I(WASM_INSN_I64_LOAD8_U, WASM_PREFIX_NONE, 0x31, WASM_OC_MEMARG,
+ "i64.load8_u"),
+ I(WASM_INSN_I64_LOAD16_S, WASM_PREFIX_NONE, 0x32, WASM_OC_MEMARG,
+ "i64.load16_s"),
+ I(WASM_INSN_I64_LOAD16_U, WASM_PREFIX_NONE, 0x33, WASM_OC_MEMARG,
+ "i64.load16_u"),
+ I(WASM_INSN_I64_LOAD32_S, WASM_PREFIX_NONE, 0x34, WASM_OC_MEMARG,
+ "i64.load32_s"),
+ I(WASM_INSN_I64_LOAD32_U, WASM_PREFIX_NONE, 0x35, WASM_OC_MEMARG,
+ "i64.load32_u"),
+ I(WASM_INSN_I32_STORE, WASM_PREFIX_NONE, 0x36, WASM_OC_MEMARG, "i32.store"),
+ I(WASM_INSN_I64_STORE, WASM_PREFIX_NONE, 0x37, WASM_OC_MEMARG, "i64.store"),
+ I(WASM_INSN_F32_STORE, WASM_PREFIX_NONE, 0x38, WASM_OC_MEMARG, "f32.store"),
+ I(WASM_INSN_F64_STORE, WASM_PREFIX_NONE, 0x39, WASM_OC_MEMARG, "f64.store"),
+ I(WASM_INSN_I32_STORE8, WASM_PREFIX_NONE, 0x3a, WASM_OC_MEMARG,
+ "i32.store8"),
+ I(WASM_INSN_I32_STORE16, WASM_PREFIX_NONE, 0x3b, WASM_OC_MEMARG,
+ "i32.store16"),
+ I(WASM_INSN_I64_STORE8, WASM_PREFIX_NONE, 0x3c, WASM_OC_MEMARG,
+ "i64.store8"),
+ I(WASM_INSN_I64_STORE16, WASM_PREFIX_NONE, 0x3d, WASM_OC_MEMARG,
+ "i64.store16"),
+ I(WASM_INSN_I64_STORE32, WASM_PREFIX_NONE, 0x3e, WASM_OC_MEMARG,
+ "i64.store32"),
+ I(WASM_INSN_MEMORY_SIZE, WASM_PREFIX_NONE, 0x3f, WASM_OC_MEM_IDX,
+ "memory.size"),
+ I(WASM_INSN_MEMORY_GROW, WASM_PREFIX_NONE, 0x40, WASM_OC_MEM_IDX,
+ "memory.grow"),
+ I(WASM_INSN_ATOMIC_FENCE, WASM_PREFIX_FE, 0x03, WASM_OC_FENCE,
+ "atomic.fence"),
+ I(WASM_INSN_I32_ATOMIC_LOAD, WASM_PREFIX_FE, 0x10, WASM_OC_MEMARG,
+ "i32.atomic.load"),
+ I(WASM_INSN_I64_ATOMIC_LOAD, WASM_PREFIX_FE, 0x11, WASM_OC_MEMARG,
+ "i64.atomic.load"),
+ I(WASM_INSN_I32_ATOMIC_LOAD8_U, WASM_PREFIX_FE, 0x12, WASM_OC_MEMARG,
+ "i32.atomic.load8_u"),
+ I(WASM_INSN_I32_ATOMIC_LOAD16_U, WASM_PREFIX_FE, 0x13, WASM_OC_MEMARG,
+ "i32.atomic.load16_u"),
+ I(WASM_INSN_I64_ATOMIC_LOAD8_U, WASM_PREFIX_FE, 0x14, WASM_OC_MEMARG,
+ "i64.atomic.load8_u"),
+ I(WASM_INSN_I64_ATOMIC_LOAD16_U, WASM_PREFIX_FE, 0x15, WASM_OC_MEMARG,
+ "i64.atomic.load16_u"),
+ I(WASM_INSN_I64_ATOMIC_LOAD32_U, WASM_PREFIX_FE, 0x16, WASM_OC_MEMARG,
+ "i64.atomic.load32_u"),
+ I(WASM_INSN_I32_ATOMIC_STORE, WASM_PREFIX_FE, 0x17, WASM_OC_MEMARG,
+ "i32.atomic.store"),
+ I(WASM_INSN_I64_ATOMIC_STORE, WASM_PREFIX_FE, 0x18, WASM_OC_MEMARG,
+ "i64.atomic.store"),
+ I(WASM_INSN_I32_ATOMIC_STORE8, WASM_PREFIX_FE, 0x19, WASM_OC_MEMARG,
+ "i32.atomic.store8"),
+ I(WASM_INSN_I32_ATOMIC_STORE16, WASM_PREFIX_FE, 0x1a, WASM_OC_MEMARG,
+ "i32.atomic.store16"),
+ I(WASM_INSN_I64_ATOMIC_STORE8, WASM_PREFIX_FE, 0x1b, WASM_OC_MEMARG,
+ "i64.atomic.store8"),
+ I(WASM_INSN_I64_ATOMIC_STORE16, WASM_PREFIX_FE, 0x1c, WASM_OC_MEMARG,
+ "i64.atomic.store16"),
+ I(WASM_INSN_I64_ATOMIC_STORE32, WASM_PREFIX_FE, 0x1d, WASM_OC_MEMARG,
+ "i64.atomic.store32"),
+ I(WASM_INSN_I32_ATOMIC_RMW_ADD, WASM_PREFIX_FE, 0x1e, WASM_OC_MEMARG,
+ "i32.atomic.rmw.add"),
+ I(WASM_INSN_I64_ATOMIC_RMW_ADD, WASM_PREFIX_FE, 0x1f, WASM_OC_MEMARG,
+ "i64.atomic.rmw.add"),
+ I(WASM_INSN_I32_ATOMIC_RMW_SUB, WASM_PREFIX_FE, 0x25, WASM_OC_MEMARG,
+ "i32.atomic.rmw.sub"),
+ I(WASM_INSN_I64_ATOMIC_RMW_SUB, WASM_PREFIX_FE, 0x26, WASM_OC_MEMARG,
+ "i64.atomic.rmw.sub"),
+ I(WASM_INSN_I32_ATOMIC_RMW_AND, WASM_PREFIX_FE, 0x2c, WASM_OC_MEMARG,
+ "i32.atomic.rmw.and"),
+ I(WASM_INSN_I64_ATOMIC_RMW_AND, WASM_PREFIX_FE, 0x2d, WASM_OC_MEMARG,
+ "i64.atomic.rmw.and"),
+ I(WASM_INSN_I32_ATOMIC_RMW_OR, WASM_PREFIX_FE, 0x33, WASM_OC_MEMARG,
+ "i32.atomic.rmw.or"),
+ I(WASM_INSN_I64_ATOMIC_RMW_OR, WASM_PREFIX_FE, 0x34, WASM_OC_MEMARG,
+ "i64.atomic.rmw.or"),
+ I(WASM_INSN_I32_ATOMIC_RMW_XOR, WASM_PREFIX_FE, 0x3a, WASM_OC_MEMARG,
+ "i32.atomic.rmw.xor"),
+ I(WASM_INSN_I64_ATOMIC_RMW_XOR, WASM_PREFIX_FE, 0x3b, WASM_OC_MEMARG,
+ "i64.atomic.rmw.xor"),
+ I(WASM_INSN_I32_ATOMIC_RMW_XCHG, WASM_PREFIX_FE, 0x41, WASM_OC_MEMARG,
+ "i32.atomic.rmw.xchg"),
+ I(WASM_INSN_I64_ATOMIC_RMW_XCHG, WASM_PREFIX_FE, 0x42, WASM_OC_MEMARG,
+ "i64.atomic.rmw.xchg"),
+ I(WASM_INSN_I32_ATOMIC_RMW_CMPXCHG, WASM_PREFIX_FE, 0x48, WASM_OC_MEMARG,
+ "i32.atomic.rmw.cmpxchg"),
+ I(WASM_INSN_I64_ATOMIC_RMW_CMPXCHG, WASM_PREFIX_FE, 0x49, WASM_OC_MEMARG,
+ "i64.atomic.rmw.cmpxchg"),
+ I(WASM_INSN_I32_ATOMIC_WAIT, WASM_PREFIX_FE, 0x01, WASM_OC_MEMARG,
+ "memory.atomic.wait32"),
+ I(WASM_INSN_I64_ATOMIC_WAIT, WASM_PREFIX_FE, 0x02, WASM_OC_MEMARG,
+ "memory.atomic.wait64"),
+ I(WASM_INSN_MEMORY_ATOMIC_NOTIFY, WASM_PREFIX_FE, 0x00, WASM_OC_MEMARG,
+ "memory.atomic.notify"),
+ I(WASM_INSN_I32_ADD, WASM_PREFIX_NONE, 0x6a, WASM_OC_NONE, "i32.add"),
+ I(WASM_INSN_I32_SUB, WASM_PREFIX_NONE, 0x6b, WASM_OC_NONE, "i32.sub"),
+ I(WASM_INSN_I32_MUL, WASM_PREFIX_NONE, 0x6c, WASM_OC_NONE, "i32.mul"),
+ I(WASM_INSN_I32_DIV_S, WASM_PREFIX_NONE, 0x6d, WASM_OC_NONE, "i32.div_s"),
+ I(WASM_INSN_I32_DIV_U, WASM_PREFIX_NONE, 0x6e, WASM_OC_NONE, "i32.div_u"),
+ I(WASM_INSN_I32_REM_S, WASM_PREFIX_NONE, 0x6f, WASM_OC_NONE, "i32.rem_s"),
+ I(WASM_INSN_I32_REM_U, WASM_PREFIX_NONE, 0x70, WASM_OC_NONE, "i32.rem_u"),
+ I(WASM_INSN_I32_AND, WASM_PREFIX_NONE, 0x71, WASM_OC_NONE, "i32.and"),
+ I(WASM_INSN_I32_OR, WASM_PREFIX_NONE, 0x72, WASM_OC_NONE, "i32.or"),
+ I(WASM_INSN_I32_XOR, WASM_PREFIX_NONE, 0x73, WASM_OC_NONE, "i32.xor"),
+ I(WASM_INSN_I32_SHL, WASM_PREFIX_NONE, 0x74, WASM_OC_NONE, "i32.shl"),
+ I(WASM_INSN_I32_SHR_S, WASM_PREFIX_NONE, 0x75, WASM_OC_NONE, "i32.shr_s"),
+ I(WASM_INSN_I32_SHR_U, WASM_PREFIX_NONE, 0x76, WASM_OC_NONE, "i32.shr_u"),
+ I(WASM_INSN_I32_ROTL, WASM_PREFIX_NONE, 0x77, WASM_OC_NONE, "i32.rotl"),
+ I(WASM_INSN_I32_ROTR, WASM_PREFIX_NONE, 0x78, WASM_OC_NONE, "i32.rotr"),
+ I(WASM_INSN_I32_CLZ, WASM_PREFIX_NONE, 0x67, WASM_OC_NONE, "i32.clz"),
+ I(WASM_INSN_I32_CTZ, WASM_PREFIX_NONE, 0x68, WASM_OC_NONE, "i32.ctz"),
+ I(WASM_INSN_I32_POPCNT, WASM_PREFIX_NONE, 0x69, WASM_OC_NONE, "i32.popcnt"),
+ I(WASM_INSN_I32_EQZ, WASM_PREFIX_NONE, 0x45, WASM_OC_NONE, "i32.eqz"),
+ I(WASM_INSN_I32_EQ, WASM_PREFIX_NONE, 0x46, WASM_OC_NONE, "i32.eq"),
+ I(WASM_INSN_I32_NE, WASM_PREFIX_NONE, 0x47, WASM_OC_NONE, "i32.ne"),
+ I(WASM_INSN_I32_LT_S, WASM_PREFIX_NONE, 0x48, WASM_OC_NONE, "i32.lt_s"),
+ I(WASM_INSN_I32_LT_U, WASM_PREFIX_NONE, 0x49, WASM_OC_NONE, "i32.lt_u"),
+ I(WASM_INSN_I32_GT_S, WASM_PREFIX_NONE, 0x4a, WASM_OC_NONE, "i32.gt_s"),
+ I(WASM_INSN_I32_GT_U, WASM_PREFIX_NONE, 0x4b, WASM_OC_NONE, "i32.gt_u"),
+ I(WASM_INSN_I32_LE_S, WASM_PREFIX_NONE, 0x4c, WASM_OC_NONE, "i32.le_s"),
+ I(WASM_INSN_I32_LE_U, WASM_PREFIX_NONE, 0x4d, WASM_OC_NONE, "i32.le_u"),
+ I(WASM_INSN_I32_GE_S, WASM_PREFIX_NONE, 0x4e, WASM_OC_NONE, "i32.ge_s"),
+ I(WASM_INSN_I32_GE_U, WASM_PREFIX_NONE, 0x4f, WASM_OC_NONE, "i32.ge_u"),
+ I(WASM_INSN_I64_ADD, WASM_PREFIX_NONE, 0x7c, WASM_OC_NONE, "i64.add"),
+ I(WASM_INSN_I64_SUB, WASM_PREFIX_NONE, 0x7d, WASM_OC_NONE, "i64.sub"),
+ I(WASM_INSN_I64_MUL, WASM_PREFIX_NONE, 0x7e, WASM_OC_NONE, "i64.mul"),
+ I(WASM_INSN_I64_DIV_S, WASM_PREFIX_NONE, 0x7f, WASM_OC_NONE, "i64.div_s"),
+ I(WASM_INSN_I64_DIV_U, WASM_PREFIX_NONE, 0x80, WASM_OC_NONE, "i64.div_u"),
+ I(WASM_INSN_I64_REM_S, WASM_PREFIX_NONE, 0x81, WASM_OC_NONE, "i64.rem_s"),
+ I(WASM_INSN_I64_REM_U, WASM_PREFIX_NONE, 0x82, WASM_OC_NONE, "i64.rem_u"),
+ I(WASM_INSN_I64_AND, WASM_PREFIX_NONE, 0x83, WASM_OC_NONE, "i64.and"),
+ I(WASM_INSN_I64_OR, WASM_PREFIX_NONE, 0x84, WASM_OC_NONE, "i64.or"),
+ I(WASM_INSN_I64_XOR, WASM_PREFIX_NONE, 0x85, WASM_OC_NONE, "i64.xor"),
+ I(WASM_INSN_I64_SHL, WASM_PREFIX_NONE, 0x86, WASM_OC_NONE, "i64.shl"),
+ I(WASM_INSN_I64_SHR_S, WASM_PREFIX_NONE, 0x87, WASM_OC_NONE, "i64.shr_s"),
+ I(WASM_INSN_I64_SHR_U, WASM_PREFIX_NONE, 0x88, WASM_OC_NONE, "i64.shr_u"),
+ I(WASM_INSN_I64_ROTL, WASM_PREFIX_NONE, 0x89, WASM_OC_NONE, "i64.rotl"),
+ I(WASM_INSN_I64_ROTR, WASM_PREFIX_NONE, 0x8a, WASM_OC_NONE, "i64.rotr"),
+ I(WASM_INSN_I64_CLZ, WASM_PREFIX_NONE, 0x79, WASM_OC_NONE, "i64.clz"),
+ I(WASM_INSN_I64_CTZ, WASM_PREFIX_NONE, 0x7a, WASM_OC_NONE, "i64.ctz"),
+ I(WASM_INSN_I64_POPCNT, WASM_PREFIX_NONE, 0x7b, WASM_OC_NONE, "i64.popcnt"),
+ I(WASM_INSN_I64_EQZ, WASM_PREFIX_NONE, 0x50, WASM_OC_NONE, "i64.eqz"),
+ I(WASM_INSN_I64_EQ, WASM_PREFIX_NONE, 0x51, WASM_OC_NONE, "i64.eq"),
+ I(WASM_INSN_I64_NE, WASM_PREFIX_NONE, 0x52, WASM_OC_NONE, "i64.ne"),
+ I(WASM_INSN_I64_LT_S, WASM_PREFIX_NONE, 0x53, WASM_OC_NONE, "i64.lt_s"),
+ I(WASM_INSN_I64_LT_U, WASM_PREFIX_NONE, 0x54, WASM_OC_NONE, "i64.lt_u"),
+ I(WASM_INSN_I64_GT_S, WASM_PREFIX_NONE, 0x55, WASM_OC_NONE, "i64.gt_s"),
+ I(WASM_INSN_I64_GT_U, WASM_PREFIX_NONE, 0x56, WASM_OC_NONE, "i64.gt_u"),
+ I(WASM_INSN_I64_LE_S, WASM_PREFIX_NONE, 0x57, WASM_OC_NONE, "i64.le_s"),
+ I(WASM_INSN_I64_LE_U, WASM_PREFIX_NONE, 0x58, WASM_OC_NONE, "i64.le_u"),
+ I(WASM_INSN_I64_GE_S, WASM_PREFIX_NONE, 0x59, WASM_OC_NONE, "i64.ge_s"),
+ I(WASM_INSN_I64_GE_U, WASM_PREFIX_NONE, 0x5a, WASM_OC_NONE, "i64.ge_u"),
+ I(WASM_INSN_F32_ADD, WASM_PREFIX_NONE, 0x92, WASM_OC_NONE, "f32.add"),
+ I(WASM_INSN_F32_SUB, WASM_PREFIX_NONE, 0x93, WASM_OC_NONE, "f32.sub"),
+ I(WASM_INSN_F32_MUL, WASM_PREFIX_NONE, 0x94, WASM_OC_NONE, "f32.mul"),
+ I(WASM_INSN_F32_DIV, WASM_PREFIX_NONE, 0x95, WASM_OC_NONE, "f32.div"),
+ I(WASM_INSN_F32_EQ, WASM_PREFIX_NONE, 0x5b, WASM_OC_NONE, "f32.eq"),
+ I(WASM_INSN_F32_NE, WASM_PREFIX_NONE, 0x5c, WASM_OC_NONE, "f32.ne"),
+ I(WASM_INSN_F32_LT, WASM_PREFIX_NONE, 0x5d, WASM_OC_NONE, "f32.lt"),
+ I(WASM_INSN_F32_GT, WASM_PREFIX_NONE, 0x5e, WASM_OC_NONE, "f32.gt"),
+ I(WASM_INSN_F32_LE, WASM_PREFIX_NONE, 0x5f, WASM_OC_NONE, "f32.le"),
+ I(WASM_INSN_F32_GE, WASM_PREFIX_NONE, 0x60, WASM_OC_NONE, "f32.ge"),
+ I(WASM_INSN_F64_ADD, WASM_PREFIX_NONE, 0xa0, WASM_OC_NONE, "f64.add"),
+ I(WASM_INSN_F64_SUB, WASM_PREFIX_NONE, 0xa1, WASM_OC_NONE, "f64.sub"),
+ I(WASM_INSN_F64_MUL, WASM_PREFIX_NONE, 0xa2, WASM_OC_NONE, "f64.mul"),
+ I(WASM_INSN_F64_DIV, WASM_PREFIX_NONE, 0xa3, WASM_OC_NONE, "f64.div"),
+ I(WASM_INSN_F64_EQ, WASM_PREFIX_NONE, 0x61, WASM_OC_NONE, "f64.eq"),
+ I(WASM_INSN_F64_NE, WASM_PREFIX_NONE, 0x62, WASM_OC_NONE, "f64.ne"),
+ I(WASM_INSN_F64_LT, WASM_PREFIX_NONE, 0x63, WASM_OC_NONE, "f64.lt"),
+ I(WASM_INSN_F64_GT, WASM_PREFIX_NONE, 0x64, WASM_OC_NONE, "f64.gt"),
+ I(WASM_INSN_F64_LE, WASM_PREFIX_NONE, 0x65, WASM_OC_NONE, "f64.le"),
+ I(WASM_INSN_F64_GE, WASM_PREFIX_NONE, 0x66, WASM_OC_NONE, "f64.ge"),
+ I(WASM_INSN_F32_NEG, WASM_PREFIX_NONE, 0x8c, WASM_OC_NONE, "f32.neg"),
+ I(WASM_INSN_F64_NEG, WASM_PREFIX_NONE, 0x9a, WASM_OC_NONE, "f64.neg"),
+ I(WASM_INSN_I32_WRAP_I64, WASM_PREFIX_NONE, 0xa7, WASM_OC_NONE,
+ "i32.wrap_i64"),
+ I(WASM_INSN_I32_TRUNC_F32_S, WASM_PREFIX_NONE, 0xa8, WASM_OC_NONE,
+ "i32.trunc_f32_s"),
+ I(WASM_INSN_I32_TRUNC_F32_U, WASM_PREFIX_NONE, 0xa9, WASM_OC_NONE,
+ "i32.trunc_f32_u"),
+ I(WASM_INSN_I32_TRUNC_F64_S, WASM_PREFIX_NONE, 0xaa, WASM_OC_NONE,
+ "i32.trunc_f64_s"),
+ I(WASM_INSN_I32_TRUNC_F64_U, WASM_PREFIX_NONE, 0xab, WASM_OC_NONE,
+ "i32.trunc_f64_u"),
+ I(WASM_INSN_I64_EXTEND_I32_S, WASM_PREFIX_NONE, 0xac, WASM_OC_NONE,
+ "i64.extend_i32_s"),
+ I(WASM_INSN_I64_EXTEND_I32_U, WASM_PREFIX_NONE, 0xad, WASM_OC_NONE,
+ "i64.extend_i32_u"),
+ I(WASM_INSN_I64_TRUNC_F32_S, WASM_PREFIX_NONE, 0xae, WASM_OC_NONE,
+ "i64.trunc_f32_s"),
+ I(WASM_INSN_I64_TRUNC_F32_U, WASM_PREFIX_NONE, 0xaf, WASM_OC_NONE,
+ "i64.trunc_f32_u"),
+ I(WASM_INSN_I64_TRUNC_F64_S, WASM_PREFIX_NONE, 0xb0, WASM_OC_NONE,
+ "i64.trunc_f64_s"),
+ I(WASM_INSN_I64_TRUNC_F64_U, WASM_PREFIX_NONE, 0xb1, WASM_OC_NONE,
+ "i64.trunc_f64_u"),
+ I(WASM_INSN_F32_CONVERT_I32_S, WASM_PREFIX_NONE, 0xb2, WASM_OC_NONE,
+ "f32.convert_i32_s"),
+ I(WASM_INSN_F32_CONVERT_I32_U, WASM_PREFIX_NONE, 0xb3, WASM_OC_NONE,
+ "f32.convert_i32_u"),
+ I(WASM_INSN_F32_CONVERT_I64_S, WASM_PREFIX_NONE, 0xb4, WASM_OC_NONE,
+ "f32.convert_i64_s"),
+ I(WASM_INSN_F32_CONVERT_I64_U, WASM_PREFIX_NONE, 0xb5, WASM_OC_NONE,
+ "f32.convert_i64_u"),
+ I(WASM_INSN_F32_DEMOTE_F64, WASM_PREFIX_NONE, 0xb6, WASM_OC_NONE,
+ "f32.demote_f64"),
+ I(WASM_INSN_F64_CONVERT_I32_S, WASM_PREFIX_NONE, 0xb7, WASM_OC_NONE,
+ "f64.convert_i32_s"),
+ I(WASM_INSN_F64_CONVERT_I32_U, WASM_PREFIX_NONE, 0xb8, WASM_OC_NONE,
+ "f64.convert_i32_u"),
+ I(WASM_INSN_F64_CONVERT_I64_S, WASM_PREFIX_NONE, 0xb9, WASM_OC_NONE,
+ "f64.convert_i64_s"),
+ I(WASM_INSN_F64_CONVERT_I64_U, WASM_PREFIX_NONE, 0xba, WASM_OC_NONE,
+ "f64.convert_i64_u"),
+ I(WASM_INSN_F64_PROMOTE_F32, WASM_PREFIX_NONE, 0xbb, WASM_OC_NONE,
+ "f64.promote_f32"),
+ I(WASM_INSN_I32_REINTERPRET_F32, WASM_PREFIX_NONE, 0xbc, WASM_OC_NONE,
+ "i32.reinterpret_f32"),
+ I(WASM_INSN_I64_REINTERPRET_F64, WASM_PREFIX_NONE, 0xbd, WASM_OC_NONE,
+ "i64.reinterpret_f64"),
+ I(WASM_INSN_F32_REINTERPRET_I32, WASM_PREFIX_NONE, 0xbe, WASM_OC_NONE,
+ "f32.reinterpret_i32"),
+ I(WASM_INSN_F64_REINTERPRET_I64, WASM_PREFIX_NONE, 0xbf, WASM_OC_NONE,
+ "f64.reinterpret_i64"),
+ I(WASM_INSN_I32_EXTEND8_S, WASM_PREFIX_NONE, 0xc0, WASM_OC_NONE,
+ "i32.extend8_s"),
+ I(WASM_INSN_I32_EXTEND16_S, WASM_PREFIX_NONE, 0xc1, WASM_OC_NONE,
+ "i32.extend16_s"),
+ I(WASM_INSN_I64_EXTEND8_S, WASM_PREFIX_NONE, 0xc2, WASM_OC_NONE,
+ "i64.extend8_s"),
+ I(WASM_INSN_I64_EXTEND16_S, WASM_PREFIX_NONE, 0xc3, WASM_OC_NONE,
+ "i64.extend16_s"),
+ I(WASM_INSN_I64_EXTEND32_S, WASM_PREFIX_NONE, 0xc4, WASM_OC_NONE,
+ "i64.extend32_s"),
+ I(WASM_INSN_I32_TRUNC_SAT_F32_S, WASM_PREFIX_FC, 0x00, WASM_OC_NONE,
+ "i32.trunc_sat_f32_s"),
+ I(WASM_INSN_I32_TRUNC_SAT_F32_U, WASM_PREFIX_FC, 0x01, WASM_OC_NONE,
+ "i32.trunc_sat_f32_u"),
+ I(WASM_INSN_I32_TRUNC_SAT_F64_S, WASM_PREFIX_FC, 0x02, WASM_OC_NONE,
+ "i32.trunc_sat_f64_s"),
+ I(WASM_INSN_I32_TRUNC_SAT_F64_U, WASM_PREFIX_FC, 0x03, WASM_OC_NONE,
+ "i32.trunc_sat_f64_u"),
+ I(WASM_INSN_I64_TRUNC_SAT_F32_S, WASM_PREFIX_FC, 0x04, WASM_OC_NONE,
+ "i64.trunc_sat_f32_s"),
+ I(WASM_INSN_I64_TRUNC_SAT_F32_U, WASM_PREFIX_FC, 0x05, WASM_OC_NONE,
+ "i64.trunc_sat_f32_u"),
+ I(WASM_INSN_I64_TRUNC_SAT_F64_S, WASM_PREFIX_FC, 0x06, WASM_OC_NONE,
+ "i64.trunc_sat_f64_s"),
+ I(WASM_INSN_I64_TRUNC_SAT_F64_U, WASM_PREFIX_FC, 0x07, WASM_OC_NONE,
+ "i64.trunc_sat_f64_u"),
+ I(WASM_INSN_MEMORY_INIT, WASM_PREFIX_FC, 0x08, WASM_OC_BULK,
+ "memory.init"),
+ I(WASM_INSN_DATA_DROP, WASM_PREFIX_FC, 0x09, WASM_OC_BULK, "data.drop"),
+ I(WASM_INSN_MEMORY_COPY, WASM_PREFIX_FC, 0x0a, WASM_OC_BULK,
+ "memory.copy"),
+ I(WASM_INSN_MEMORY_FILL, WASM_PREFIX_FC, 0x0b, WASM_OC_BULK,
+ "memory.fill"),
+ I(WASM_INSN_TABLE_INIT, WASM_PREFIX_FC, 0x0c, WASM_OC_BULK, "table.init"),
+ I(WASM_INSN_ELEM_DROP, WASM_PREFIX_FC, 0x0d, WASM_OC_BULK, "elem.drop"),
+ I(WASM_INSN_TABLE_COPY, WASM_PREFIX_FC, 0x0e, WASM_OC_BULK, "table.copy"),
+ I(WASM_INSN_TABLE_GROW, WASM_PREFIX_FC, 0x0f, WASM_OC_BULK, "table.grow"),
+ I(WASM_INSN_TABLE_SIZE, WASM_PREFIX_FC, 0x10, WASM_OC_BULK, "table.size"),
+ I(WASM_INSN_TABLE_FILL, WASM_PREFIX_FC, 0x11, WASM_OC_BULK, "table.fill"),
+};
+
+#undef I
+
+#define WASM_INSN_TABLE_LEN \
+ (sizeof(WASM_INSN_TABLE) / sizeof(WASM_INSN_TABLE[0]))
+
+const WasmInsnInfo* wasm_insn_info(WasmInsnKind kind) {
+ if ((unsigned)kind >= WASM_INSN_TABLE_LEN) return NULL;
+ if (!WASM_INSN_TABLE[kind].mnemonic) return NULL;
+ return &WASM_INSN_TABLE[kind];
+}
+
+int wasm_operand_class_has_imm(WasmOperandClass oc) {
+ switch (oc) {
+ case WASM_OC_SLEB:
+ case WASM_OC_FP:
+ case WASM_OC_IDX:
+ case WASM_OC_REF_NULL:
+ return 1;
+ default:
+ return 0;
+ }
+}
diff --git a/src/wasm/wasm_insn_table.h b/src/wasm/wasm_insn_table.h
@@ -0,0 +1,62 @@
+#ifndef KIT_WASM_INSN_TABLE_H
+#define KIT_WASM_INSN_TABLE_H
+
+/* Single source of truth for the Wasm instruction set.
+ *
+ * WasmInsnKind is the same logical instruction described five different ways:
+ * its opcode bytes (encode), its byte->kind map (decode), its WAT mnemonic
+ * (disassembler), its mnemonic->kind map (WAT parser), and the operand class
+ * that drives how immediates are read/written. Historically each of those was
+ * its own ~200-arm switch that had to stay in lockstep. WASM_INSN_TABLE below
+ * is that map, written once; encode/wat/disasm derive their behaviour from it
+ * by O(1) row lookup or a linear scan, and the mnemonic helper reads a column.
+ *
+ * Decode keeps its hand-written arms: the per-opcode operand reads are genuinely
+ * irregular (two index immediates, block-type bytes, br_table vectors, ...) and
+ * are not worth forcing into a table; it still shares decode_body_insn so the
+ * byte<->kind mapping lives in exactly one place there too. */
+
+#include "wasm/wasm.h"
+
+/* Opcode-space prefix for an instruction's encoding. */
+typedef enum WasmInsnPrefix {
+ WASM_PREFIX_NONE = 0, /* single-byte opcode, `byte` is the opcode */
+ WASM_PREFIX_FC = 1, /* 0xfc-prefixed (misc: trunc_sat + bulk memory/table) */
+ WASM_PREFIX_FE = 2, /* 0xfe-prefixed (threads/atomics) */
+} WasmInsnPrefix;
+
+/* Operand-class column: how an instruction's immediates are spelled. Drives
+ * encode (write), the disassembler's render_operands (read), and the WAT
+ * parser's has_imm. Classes with a trailing comment of "has_imm" are the ones
+ * for which the WAT grammar parses a single trailing immediate token. */
+typedef enum WasmOperandClass {
+ WASM_OC_NONE = 0, /* no immediate */
+ WASM_OC_SLEB, /* i32/i64.const signed leb (has_imm) */
+ WASM_OC_FP, /* f32/f64.const float literal (has_imm) */
+ WASM_OC_IDX, /* one uleb index immediate (has_imm) */
+ WASM_OC_TYPED_REF, /* call_ref/return_call_ref: uleb typeidx, but WAT
+ * takes the type from context, so no trailing token */
+ WASM_OC_REF_NULL, /* ref.null valtype (has_imm) */
+ WASM_OC_CALL_INDIRECT, /* typeidx + tableidx */
+ WASM_OC_BR_TABLE, /* label vector + default */
+ WASM_OC_BLOCK_TYPE, /* block/loop/if: 0x40 blocktype byte */
+ WASM_OC_MEMARG, /* memory access: align/offset/memidx */
+ WASM_OC_MEM_IDX, /* memory.size/grow: single memidx */
+ WASM_OC_BULK, /* 0xfc bulk memory/table ops, irregular index slots */
+ WASM_OC_FENCE, /* atomic.fence: a single 0x00 byte */
+} WasmOperandClass;
+
+typedef struct WasmInsnInfo {
+ uint8_t kind; /* WasmInsnKind; rows are enum-indexed */
+ uint8_t prefix; /* WasmInsnPrefix */
+ uint8_t byte; /* opcode byte (PREFIX_NONE) or sub-opcode otherwise */
+ uint8_t operand_class; /* WasmOperandClass */
+ const char* mnemonic; /* canonical WAT spelling; never NULL in-table */
+} WasmInsnInfo;
+
+/* Row for `kind`, or NULL if out of range. O(1). */
+const WasmInsnInfo* wasm_insn_info(WasmInsnKind kind);
+/* WAT operand-token presence derived from the operand class. */
+int wasm_operand_class_has_imm(WasmOperandClass oc);
+
+#endif
diff --git a/src/wasm/wat.c b/src/wasm/wat.c
@@ -1,6 +1,7 @@
#include <kit/source.h>
#include "wasm/wasm.h"
+#include "wasm/wasm_insn_table.h"
typedef struct WasmTok {
const char* p;
@@ -329,888 +330,44 @@ static void wat_skip_list(WatParser* p) {
}
}
+/* A handful of mnemonics have legacy spellings that map to the same kind as
+ * their canonical WASM_INSN_TABLE name; the table carries only the canonical
+ * spelling, so these aliases are checked separately. */
+static const struct {
+ const char* mnemonic;
+ WasmInsnKind kind;
+} WAT_INSN_ALIASES[] = {
+ {"i32.atomic.wait", WASM_INSN_I32_ATOMIC_WAIT},
+ {"i64.atomic.wait", WASM_INSN_I64_ATOMIC_WAIT},
+ {"atomic.notify", WASM_INSN_MEMORY_ATOMIC_NOTIFY},
+};
+
+/* Resolve a WAT mnemonic token to its instruction kind via a linear scan over
+ * the single WASM_INSN_TABLE map (same set, same semantics as the former
+ * 200-arm strcmp chain), plus a tiny alias list. `has_imm` reflects whether the
+ * grammar parses one trailing immediate token, derived from the operand
+ * class. */
static int wat_instr_kind(WasmTok t, WasmInsnKind* out, int* has_imm) {
*has_imm = 0;
- if (tok_is(t, "unreachable")) {
- *out = WASM_INSN_UNREACHABLE;
- return 1;
- }
- if (tok_is(t, "nop")) {
- *out = WASM_INSN_NOP;
- return 1;
- }
- if (tok_is(t, "block")) {
- *out = WASM_INSN_BLOCK;
- return 1;
- }
- if (tok_is(t, "loop")) {
- *out = WASM_INSN_LOOP;
- return 1;
- }
- if (tok_is(t, "if")) {
- *out = WASM_INSN_IF;
- return 1;
- }
- if (tok_is(t, "else")) {
- *out = WASM_INSN_ELSE;
- return 1;
- }
- if (tok_is(t, "end")) {
- *out = WASM_INSN_END;
- return 1;
- }
- if (tok_is(t, "br")) {
- *out = WASM_INSN_BR;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "br_if")) {
- *out = WASM_INSN_BR_IF;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "br_table")) {
- *out = WASM_INSN_BR_TABLE;
- return 1;
- }
- if (tok_is(t, "select")) {
- *out = WASM_INSN_SELECT;
- return 1;
- }
- if (tok_is(t, "f32.const")) {
- *out = WASM_INSN_F32_CONST;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "f64.const")) {
- *out = WASM_INSN_F64_CONST;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "i32.const")) {
- *out = WASM_INSN_I32_CONST;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "i64.const")) {
- *out = WASM_INSN_I64_CONST;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "local.get")) {
- *out = WASM_INSN_LOCAL_GET;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "local.set")) {
- *out = WASM_INSN_LOCAL_SET;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "local.tee")) {
- *out = WASM_INSN_LOCAL_TEE;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "call")) {
- *out = WASM_INSN_CALL;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "call_indirect")) {
- *out = WASM_INSN_CALL_INDIRECT;
- return 1;
- }
- if (tok_is(t, "call_ref")) {
- *out = WASM_INSN_CALL_REF;
- return 1;
- }
- if (tok_is(t, "return_call")) {
- *out = WASM_INSN_RETURN_CALL;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "return_call_indirect")) {
- *out = WASM_INSN_RETURN_CALL_INDIRECT;
- return 1;
- }
- if (tok_is(t, "return_call_ref")) {
- *out = WASM_INSN_RETURN_CALL_REF;
- return 1;
- }
- if (tok_is(t, "ref.null")) {
- *out = WASM_INSN_REF_NULL;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "ref.func")) {
- *out = WASM_INSN_REF_FUNC;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "ref.is_null")) {
- *out = WASM_INSN_REF_IS_NULL;
- return 1;
- }
- if (tok_is(t, "global.get")) {
- *out = WASM_INSN_GLOBAL_GET;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "global.set")) {
- *out = WASM_INSN_GLOBAL_SET;
- *has_imm = 1;
- return 1;
- }
- if (tok_is(t, "return")) {
- *out = WASM_INSN_RETURN;
- return 1;
- }
- if (tok_is(t, "drop")) {
- *out = WASM_INSN_DROP;
- return 1;
- }
- if (tok_is(t, "atomic.fence")) {
- *out = WASM_INSN_ATOMIC_FENCE;
- return 1;
- }
- if (tok_is(t, "i32.load")) {
- *out = WASM_INSN_I32_LOAD;
- return 1;
- }
- if (tok_is(t, "i32.atomic.load")) {
- *out = WASM_INSN_I32_ATOMIC_LOAD;
- return 1;
- }
- if (tok_is(t, "i64.load")) {
- *out = WASM_INSN_I64_LOAD;
- return 1;
- }
- if (tok_is(t, "f32.load")) {
- *out = WASM_INSN_F32_LOAD;
- return 1;
- }
- if (tok_is(t, "f64.load")) {
- *out = WASM_INSN_F64_LOAD;
- return 1;
- }
- if (tok_is(t, "i64.atomic.load")) {
- *out = WASM_INSN_I64_ATOMIC_LOAD;
- return 1;
- }
- if (tok_is(t, "i32.load8_s")) {
- *out = WASM_INSN_I32_LOAD8_S;
- return 1;
- }
- if (tok_is(t, "i32.load8_u")) {
- *out = WASM_INSN_I32_LOAD8_U;
- return 1;
- }
- if (tok_is(t, "i32.atomic.load8_u")) {
- *out = WASM_INSN_I32_ATOMIC_LOAD8_U;
- return 1;
- }
- if (tok_is(t, "i32.load16_s")) {
- *out = WASM_INSN_I32_LOAD16_S;
- return 1;
- }
- if (tok_is(t, "i32.load16_u")) {
- *out = WASM_INSN_I32_LOAD16_U;
- return 1;
- }
- if (tok_is(t, "i32.atomic.load16_u")) {
- *out = WASM_INSN_I32_ATOMIC_LOAD16_U;
- return 1;
- }
- if (tok_is(t, "i64.load8_s")) {
- *out = WASM_INSN_I64_LOAD8_S;
- return 1;
- }
- if (tok_is(t, "i64.load8_u")) {
- *out = WASM_INSN_I64_LOAD8_U;
- return 1;
- }
- if (tok_is(t, "i64.atomic.load8_u")) {
- *out = WASM_INSN_I64_ATOMIC_LOAD8_U;
- return 1;
- }
- if (tok_is(t, "i64.load16_s")) {
- *out = WASM_INSN_I64_LOAD16_S;
- return 1;
- }
- if (tok_is(t, "i64.load16_u")) {
- *out = WASM_INSN_I64_LOAD16_U;
- return 1;
- }
- if (tok_is(t, "i64.atomic.load16_u")) {
- *out = WASM_INSN_I64_ATOMIC_LOAD16_U;
- return 1;
- }
- if (tok_is(t, "i64.load32_s")) {
- *out = WASM_INSN_I64_LOAD32_S;
- return 1;
- }
- if (tok_is(t, "i64.load32_u")) {
- *out = WASM_INSN_I64_LOAD32_U;
- return 1;
- }
- if (tok_is(t, "i64.atomic.load32_u")) {
- *out = WASM_INSN_I64_ATOMIC_LOAD32_U;
- return 1;
- }
- if (tok_is(t, "i32.store")) {
- *out = WASM_INSN_I32_STORE;
- return 1;
- }
- if (tok_is(t, "i32.atomic.store")) {
- *out = WASM_INSN_I32_ATOMIC_STORE;
- return 1;
- }
- if (tok_is(t, "i64.store")) {
- *out = WASM_INSN_I64_STORE;
- return 1;
- }
- if (tok_is(t, "f32.store")) {
- *out = WASM_INSN_F32_STORE;
- return 1;
- }
- if (tok_is(t, "f64.store")) {
- *out = WASM_INSN_F64_STORE;
- return 1;
- }
- if (tok_is(t, "i64.atomic.store")) {
- *out = WASM_INSN_I64_ATOMIC_STORE;
- return 1;
- }
- if (tok_is(t, "i32.store8")) {
- *out = WASM_INSN_I32_STORE8;
- return 1;
- }
- if (tok_is(t, "i32.atomic.store8")) {
- *out = WASM_INSN_I32_ATOMIC_STORE8;
- return 1;
- }
- if (tok_is(t, "i32.store16")) {
- *out = WASM_INSN_I32_STORE16;
- return 1;
- }
- if (tok_is(t, "i32.atomic.store16")) {
- *out = WASM_INSN_I32_ATOMIC_STORE16;
- return 1;
- }
- if (tok_is(t, "i64.store8")) {
- *out = WASM_INSN_I64_STORE8;
- return 1;
- }
- if (tok_is(t, "i64.atomic.store8")) {
- *out = WASM_INSN_I64_ATOMIC_STORE8;
- return 1;
- }
- if (tok_is(t, "i64.store16")) {
- *out = WASM_INSN_I64_STORE16;
- return 1;
- }
- if (tok_is(t, "i64.atomic.store16")) {
- *out = WASM_INSN_I64_ATOMIC_STORE16;
- return 1;
- }
- if (tok_is(t, "i64.store32")) {
- *out = WASM_INSN_I64_STORE32;
- return 1;
- }
- if (tok_is(t, "i64.atomic.store32")) {
- *out = WASM_INSN_I64_ATOMIC_STORE32;
- return 1;
- }
- if (tok_is(t, "i32.atomic.rmw.add")) {
- *out = WASM_INSN_I32_ATOMIC_RMW_ADD;
- return 1;
- }
- if (tok_is(t, "i64.atomic.rmw.add")) {
- *out = WASM_INSN_I64_ATOMIC_RMW_ADD;
- return 1;
- }
- if (tok_is(t, "i32.atomic.rmw.sub")) {
- *out = WASM_INSN_I32_ATOMIC_RMW_SUB;
- return 1;
- }
- if (tok_is(t, "i64.atomic.rmw.sub")) {
- *out = WASM_INSN_I64_ATOMIC_RMW_SUB;
- return 1;
- }
- if (tok_is(t, "i32.atomic.rmw.and")) {
- *out = WASM_INSN_I32_ATOMIC_RMW_AND;
- return 1;
- }
- if (tok_is(t, "i64.atomic.rmw.and")) {
- *out = WASM_INSN_I64_ATOMIC_RMW_AND;
- return 1;
- }
- if (tok_is(t, "i32.atomic.rmw.or")) {
- *out = WASM_INSN_I32_ATOMIC_RMW_OR;
- return 1;
- }
- if (tok_is(t, "i64.atomic.rmw.or")) {
- *out = WASM_INSN_I64_ATOMIC_RMW_OR;
- return 1;
- }
- if (tok_is(t, "i32.atomic.rmw.xor")) {
- *out = WASM_INSN_I32_ATOMIC_RMW_XOR;
- return 1;
- }
- if (tok_is(t, "i64.atomic.rmw.xor")) {
- *out = WASM_INSN_I64_ATOMIC_RMW_XOR;
- return 1;
- }
- if (tok_is(t, "i32.atomic.rmw.xchg")) {
- *out = WASM_INSN_I32_ATOMIC_RMW_XCHG;
- return 1;
- }
- if (tok_is(t, "i64.atomic.rmw.xchg")) {
- *out = WASM_INSN_I64_ATOMIC_RMW_XCHG;
- return 1;
- }
- if (tok_is(t, "i32.atomic.rmw.cmpxchg")) {
- *out = WASM_INSN_I32_ATOMIC_RMW_CMPXCHG;
- return 1;
- }
- if (tok_is(t, "i64.atomic.rmw.cmpxchg")) {
- *out = WASM_INSN_I64_ATOMIC_RMW_CMPXCHG;
- return 1;
- }
- if (tok_is(t, "memory.atomic.wait32") || tok_is(t, "i32.atomic.wait")) {
- *out = WASM_INSN_I32_ATOMIC_WAIT;
- return 1;
- }
- if (tok_is(t, "memory.atomic.wait64") || tok_is(t, "i64.atomic.wait")) {
- *out = WASM_INSN_I64_ATOMIC_WAIT;
- return 1;
- }
- if (tok_is(t, "memory.atomic.notify") || tok_is(t, "atomic.notify")) {
- *out = WASM_INSN_MEMORY_ATOMIC_NOTIFY;
- return 1;
- }
- if (tok_is(t, "memory.size")) {
- *out = WASM_INSN_MEMORY_SIZE;
- return 1;
- }
- if (tok_is(t, "memory.grow")) {
- *out = WASM_INSN_MEMORY_GROW;
- return 1;
- }
- /* Bulk memory and table ops (0xfc prefix). */
- if (tok_is(t, "memory.init")) {
- *out = WASM_INSN_MEMORY_INIT;
- return 1;
- }
- if (tok_is(t, "data.drop")) {
- *out = WASM_INSN_DATA_DROP;
- return 1;
- }
- if (tok_is(t, "memory.copy")) {
- *out = WASM_INSN_MEMORY_COPY;
- return 1;
- }
- if (tok_is(t, "memory.fill")) {
- *out = WASM_INSN_MEMORY_FILL;
- return 1;
- }
- if (tok_is(t, "table.init")) {
- *out = WASM_INSN_TABLE_INIT;
- return 1;
- }
- if (tok_is(t, "elem.drop")) {
- *out = WASM_INSN_ELEM_DROP;
- return 1;
- }
- if (tok_is(t, "table.copy")) {
- *out = WASM_INSN_TABLE_COPY;
- return 1;
- }
- if (tok_is(t, "table.grow")) {
- *out = WASM_INSN_TABLE_GROW;
- return 1;
- }
- if (tok_is(t, "table.size")) {
- *out = WASM_INSN_TABLE_SIZE;
- return 1;
- }
- if (tok_is(t, "table.fill")) {
- *out = WASM_INSN_TABLE_FILL;
- return 1;
- }
- /* Saturating float-to-int conversions. */
- if (tok_is(t, "i32.trunc_sat_f32_s")) {
- *out = WASM_INSN_I32_TRUNC_SAT_F32_S;
- return 1;
- }
- if (tok_is(t, "i32.trunc_sat_f32_u")) {
- *out = WASM_INSN_I32_TRUNC_SAT_F32_U;
- return 1;
- }
- if (tok_is(t, "i32.trunc_sat_f64_s")) {
- *out = WASM_INSN_I32_TRUNC_SAT_F64_S;
- return 1;
- }
- if (tok_is(t, "i32.trunc_sat_f64_u")) {
- *out = WASM_INSN_I32_TRUNC_SAT_F64_U;
- return 1;
- }
- if (tok_is(t, "i64.trunc_sat_f32_s")) {
- *out = WASM_INSN_I64_TRUNC_SAT_F32_S;
- return 1;
- }
- if (tok_is(t, "i64.trunc_sat_f32_u")) {
- *out = WASM_INSN_I64_TRUNC_SAT_F32_U;
- return 1;
- }
- if (tok_is(t, "i64.trunc_sat_f64_s")) {
- *out = WASM_INSN_I64_TRUNC_SAT_F64_S;
- return 1;
- }
- if (tok_is(t, "i64.trunc_sat_f64_u")) {
- *out = WASM_INSN_I64_TRUNC_SAT_F64_U;
- return 1;
- }
- if (tok_is(t, "i32.add")) {
- *out = WASM_INSN_I32_ADD;
- return 1;
- }
- if (tok_is(t, "i32.sub")) {
- *out = WASM_INSN_I32_SUB;
- return 1;
- }
- if (tok_is(t, "i32.mul")) {
- *out = WASM_INSN_I32_MUL;
- return 1;
- }
- if (tok_is(t, "i32.div_s")) {
- *out = WASM_INSN_I32_DIV_S;
- return 1;
- }
- if (tok_is(t, "i32.div_u")) {
- *out = WASM_INSN_I32_DIV_U;
- return 1;
- }
- if (tok_is(t, "i32.rem_s")) {
- *out = WASM_INSN_I32_REM_S;
- return 1;
- }
- if (tok_is(t, "i32.rem_u")) {
- *out = WASM_INSN_I32_REM_U;
- return 1;
- }
- if (tok_is(t, "i32.and")) {
- *out = WASM_INSN_I32_AND;
- return 1;
- }
- if (tok_is(t, "i32.or")) {
- *out = WASM_INSN_I32_OR;
- return 1;
- }
- if (tok_is(t, "i32.xor")) {
- *out = WASM_INSN_I32_XOR;
- return 1;
- }
- if (tok_is(t, "i32.shl")) {
- *out = WASM_INSN_I32_SHL;
- return 1;
- }
- if (tok_is(t, "i32.shr_s")) {
- *out = WASM_INSN_I32_SHR_S;
- return 1;
- }
- if (tok_is(t, "i32.shr_u")) {
- *out = WASM_INSN_I32_SHR_U;
- return 1;
- }
- if (tok_is(t, "i32.rotl")) {
- *out = WASM_INSN_I32_ROTL;
- return 1;
- }
- if (tok_is(t, "i32.rotr")) {
- *out = WASM_INSN_I32_ROTR;
- return 1;
- }
- if (tok_is(t, "i32.clz")) {
- *out = WASM_INSN_I32_CLZ;
- return 1;
- }
- if (tok_is(t, "i32.ctz")) {
- *out = WASM_INSN_I32_CTZ;
- return 1;
- }
- if (tok_is(t, "i32.popcnt")) {
- *out = WASM_INSN_I32_POPCNT;
- return 1;
- }
- if (tok_is(t, "i32.eqz")) {
- *out = WASM_INSN_I32_EQZ;
- return 1;
- }
- if (tok_is(t, "i32.eq")) {
- *out = WASM_INSN_I32_EQ;
- return 1;
- }
- if (tok_is(t, "i32.ne")) {
- *out = WASM_INSN_I32_NE;
- return 1;
- }
- if (tok_is(t, "i32.lt_s")) {
- *out = WASM_INSN_I32_LT_S;
- return 1;
- }
- if (tok_is(t, "i32.lt_u")) {
- *out = WASM_INSN_I32_LT_U;
- return 1;
- }
- if (tok_is(t, "i32.gt_s")) {
- *out = WASM_INSN_I32_GT_S;
- return 1;
- }
- if (tok_is(t, "i32.gt_u")) {
- *out = WASM_INSN_I32_GT_U;
- return 1;
- }
- if (tok_is(t, "i32.le_s")) {
- *out = WASM_INSN_I32_LE_S;
- return 1;
- }
- if (tok_is(t, "i32.le_u")) {
- *out = WASM_INSN_I32_LE_U;
- return 1;
- }
- if (tok_is(t, "i32.ge_s")) {
- *out = WASM_INSN_I32_GE_S;
- return 1;
- }
- if (tok_is(t, "i32.ge_u")) {
- *out = WASM_INSN_I32_GE_U;
- return 1;
- }
- if (tok_is(t, "i64.add")) {
- *out = WASM_INSN_I64_ADD;
- return 1;
- }
- if (tok_is(t, "i64.sub")) {
- *out = WASM_INSN_I64_SUB;
- return 1;
- }
- if (tok_is(t, "i64.mul")) {
- *out = WASM_INSN_I64_MUL;
- return 1;
- }
- if (tok_is(t, "i64.div_s")) {
- *out = WASM_INSN_I64_DIV_S;
- return 1;
- }
- if (tok_is(t, "i64.div_u")) {
- *out = WASM_INSN_I64_DIV_U;
- return 1;
- }
- if (tok_is(t, "i64.rem_s")) {
- *out = WASM_INSN_I64_REM_S;
- return 1;
- }
- if (tok_is(t, "i64.rem_u")) {
- *out = WASM_INSN_I64_REM_U;
- return 1;
- }
- if (tok_is(t, "i64.and")) {
- *out = WASM_INSN_I64_AND;
- return 1;
- }
- if (tok_is(t, "i64.or")) {
- *out = WASM_INSN_I64_OR;
- return 1;
- }
- if (tok_is(t, "i64.xor")) {
- *out = WASM_INSN_I64_XOR;
- return 1;
- }
- if (tok_is(t, "i64.shl")) {
- *out = WASM_INSN_I64_SHL;
- return 1;
- }
- if (tok_is(t, "i64.shr_s")) {
- *out = WASM_INSN_I64_SHR_S;
- return 1;
- }
- if (tok_is(t, "i64.shr_u")) {
- *out = WASM_INSN_I64_SHR_U;
- return 1;
- }
- if (tok_is(t, "i64.rotl")) {
- *out = WASM_INSN_I64_ROTL;
- return 1;
- }
- if (tok_is(t, "i64.rotr")) {
- *out = WASM_INSN_I64_ROTR;
- return 1;
- }
- if (tok_is(t, "i64.clz")) {
- *out = WASM_INSN_I64_CLZ;
- return 1;
- }
- if (tok_is(t, "i64.ctz")) {
- *out = WASM_INSN_I64_CTZ;
- return 1;
- }
- if (tok_is(t, "i64.popcnt")) {
- *out = WASM_INSN_I64_POPCNT;
- return 1;
- }
- if (tok_is(t, "i64.eqz")) {
- *out = WASM_INSN_I64_EQZ;
- return 1;
- }
- if (tok_is(t, "i64.eq")) {
- *out = WASM_INSN_I64_EQ;
- return 1;
- }
- if (tok_is(t, "i64.ne")) {
- *out = WASM_INSN_I64_NE;
- return 1;
- }
- if (tok_is(t, "i64.lt_s")) {
- *out = WASM_INSN_I64_LT_S;
- return 1;
- }
- if (tok_is(t, "i64.lt_u")) {
- *out = WASM_INSN_I64_LT_U;
- return 1;
- }
- if (tok_is(t, "i64.gt_s")) {
- *out = WASM_INSN_I64_GT_S;
- return 1;
- }
- if (tok_is(t, "i64.gt_u")) {
- *out = WASM_INSN_I64_GT_U;
- return 1;
- }
- if (tok_is(t, "i64.le_s")) {
- *out = WASM_INSN_I64_LE_S;
- return 1;
- }
- if (tok_is(t, "i64.le_u")) {
- *out = WASM_INSN_I64_LE_U;
- return 1;
- }
- if (tok_is(t, "i64.ge_s")) {
- *out = WASM_INSN_I64_GE_S;
- return 1;
- }
- if (tok_is(t, "i64.ge_u")) {
- *out = WASM_INSN_I64_GE_U;
- return 1;
- }
- if (tok_is(t, "f32.neg")) {
- *out = WASM_INSN_F32_NEG;
- return 1;
- }
- if (tok_is(t, "f64.neg")) {
- *out = WASM_INSN_F64_NEG;
- return 1;
- }
- if (tok_is(t, "f32.add")) {
- *out = WASM_INSN_F32_ADD;
- return 1;
- }
- if (tok_is(t, "f32.sub")) {
- *out = WASM_INSN_F32_SUB;
- return 1;
- }
- if (tok_is(t, "f32.mul")) {
- *out = WASM_INSN_F32_MUL;
- return 1;
- }
- if (tok_is(t, "f32.div")) {
- *out = WASM_INSN_F32_DIV;
- return 1;
- }
- if (tok_is(t, "f32.eq")) {
- *out = WASM_INSN_F32_EQ;
- return 1;
- }
- if (tok_is(t, "f32.ne")) {
- *out = WASM_INSN_F32_NE;
- return 1;
- }
- if (tok_is(t, "f32.lt")) {
- *out = WASM_INSN_F32_LT;
- return 1;
- }
- if (tok_is(t, "f32.gt")) {
- *out = WASM_INSN_F32_GT;
- return 1;
- }
- if (tok_is(t, "f32.le")) {
- *out = WASM_INSN_F32_LE;
- return 1;
- }
- if (tok_is(t, "f32.ge")) {
- *out = WASM_INSN_F32_GE;
- return 1;
- }
- if (tok_is(t, "f64.add")) {
- *out = WASM_INSN_F64_ADD;
- return 1;
- }
- if (tok_is(t, "f64.sub")) {
- *out = WASM_INSN_F64_SUB;
- return 1;
- }
- if (tok_is(t, "f64.mul")) {
- *out = WASM_INSN_F64_MUL;
- return 1;
- }
- if (tok_is(t, "f64.div")) {
- *out = WASM_INSN_F64_DIV;
- return 1;
- }
- if (tok_is(t, "f64.eq")) {
- *out = WASM_INSN_F64_EQ;
- return 1;
- }
- if (tok_is(t, "f64.ne")) {
- *out = WASM_INSN_F64_NE;
- return 1;
- }
- if (tok_is(t, "f64.lt")) {
- *out = WASM_INSN_F64_LT;
- return 1;
- }
- if (tok_is(t, "f64.gt")) {
- *out = WASM_INSN_F64_GT;
- return 1;
- }
- if (tok_is(t, "f64.le")) {
- *out = WASM_INSN_F64_LE;
- return 1;
- }
- if (tok_is(t, "f64.ge")) {
- *out = WASM_INSN_F64_GE;
- return 1;
- }
- if (tok_is(t, "i32.wrap_i64")) {
- *out = WASM_INSN_I32_WRAP_I64;
- return 1;
- }
- if (tok_is(t, "i32.trunc_f32_s")) {
- *out = WASM_INSN_I32_TRUNC_F32_S;
- return 1;
- }
- if (tok_is(t, "i32.trunc_f32_u")) {
- *out = WASM_INSN_I32_TRUNC_F32_U;
- return 1;
- }
- if (tok_is(t, "i32.trunc_f64_s")) {
- *out = WASM_INSN_I32_TRUNC_F64_S;
- return 1;
- }
- if (tok_is(t, "i32.trunc_f64_u")) {
- *out = WASM_INSN_I32_TRUNC_F64_U;
- return 1;
- }
- if (tok_is(t, "i64.extend_i32_s")) {
- *out = WASM_INSN_I64_EXTEND_I32_S;
- return 1;
- }
- if (tok_is(t, "i64.extend_i32_u")) {
- *out = WASM_INSN_I64_EXTEND_I32_U;
- return 1;
- }
- if (tok_is(t, "i64.trunc_f32_s")) {
- *out = WASM_INSN_I64_TRUNC_F32_S;
- return 1;
- }
- if (tok_is(t, "i64.trunc_f32_u")) {
- *out = WASM_INSN_I64_TRUNC_F32_U;
- return 1;
- }
- if (tok_is(t, "i64.trunc_f64_s")) {
- *out = WASM_INSN_I64_TRUNC_F64_S;
- return 1;
- }
- if (tok_is(t, "i64.trunc_f64_u")) {
- *out = WASM_INSN_I64_TRUNC_F64_U;
- return 1;
- }
- if (tok_is(t, "f32.convert_i32_s")) {
- *out = WASM_INSN_F32_CONVERT_I32_S;
- return 1;
- }
- if (tok_is(t, "f32.convert_i32_u")) {
- *out = WASM_INSN_F32_CONVERT_I32_U;
- return 1;
- }
- if (tok_is(t, "f32.convert_i64_s")) {
- *out = WASM_INSN_F32_CONVERT_I64_S;
- return 1;
- }
- if (tok_is(t, "f32.convert_i64_u")) {
- *out = WASM_INSN_F32_CONVERT_I64_U;
- return 1;
- }
- if (tok_is(t, "f32.demote_f64")) {
- *out = WASM_INSN_F32_DEMOTE_F64;
- return 1;
- }
- if (tok_is(t, "f64.convert_i32_s")) {
- *out = WASM_INSN_F64_CONVERT_I32_S;
- return 1;
- }
- if (tok_is(t, "f64.convert_i32_u")) {
- *out = WASM_INSN_F64_CONVERT_I32_U;
- return 1;
- }
- if (tok_is(t, "f64.convert_i64_s")) {
- *out = WASM_INSN_F64_CONVERT_I64_S;
- return 1;
- }
- if (tok_is(t, "f64.convert_i64_u")) {
- *out = WASM_INSN_F64_CONVERT_I64_U;
- return 1;
- }
- if (tok_is(t, "f64.promote_f32")) {
- *out = WASM_INSN_F64_PROMOTE_F32;
- return 1;
- }
- if (tok_is(t, "i32.reinterpret_f32")) {
- *out = WASM_INSN_I32_REINTERPRET_F32;
- return 1;
- }
- if (tok_is(t, "i64.reinterpret_f64")) {
- *out = WASM_INSN_I64_REINTERPRET_F64;
- return 1;
- }
- if (tok_is(t, "f32.reinterpret_i32")) {
- *out = WASM_INSN_F32_REINTERPRET_I32;
- return 1;
- }
- if (tok_is(t, "f64.reinterpret_i64")) {
- *out = WASM_INSN_F64_REINTERPRET_I64;
- return 1;
- }
- if (tok_is(t, "i32.extend8_s")) {
- *out = WASM_INSN_I32_EXTEND8_S;
- return 1;
- }
- if (tok_is(t, "i32.extend16_s")) {
- *out = WASM_INSN_I32_EXTEND16_S;
- return 1;
- }
- if (tok_is(t, "i64.extend8_s")) {
- *out = WASM_INSN_I64_EXTEND8_S;
- return 1;
- }
- if (tok_is(t, "i64.extend16_s")) {
- *out = WASM_INSN_I64_EXTEND16_S;
- return 1;
+ if (t.kind != WT_ATOM) return 0;
+ for (WasmInsnKind k = 0; k <= WASM_INSN_TABLE_FILL; ++k) {
+ const WasmInsnInfo* info = wasm_insn_info(k);
+ if (!info) continue;
+ if (tok_is(t, info->mnemonic)) {
+ *out = k;
+ *has_imm = wasm_operand_class_has_imm((WasmOperandClass)info->operand_class);
+ return 1;
+ }
}
- if (tok_is(t, "i64.extend32_s")) {
- *out = WASM_INSN_I64_EXTEND32_S;
- return 1;
+ for (size_t i = 0; i < sizeof(WAT_INSN_ALIASES) / sizeof(WAT_INSN_ALIASES[0]);
+ ++i) {
+ if (tok_is(t, WAT_INSN_ALIASES[i].mnemonic)) {
+ const WasmInsnInfo* info = wasm_insn_info(WAT_INSN_ALIASES[i].kind);
+ *out = WAT_INSN_ALIASES[i].kind;
+ *has_imm =
+ info && wasm_operand_class_has_imm((WasmOperandClass)info->operand_class);
+ return 1;
+ }
}
return 0;
}