protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

commit 09546329b09f6e7fbbfc47a8240efcfb3a0a9d08
parent 5b3ba00987a8f2b4a8ef4f802d0857da971ac9c7
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 18 Jul 2021 11:35:23 -0700

add some more instrs

Diffstat:
Msrc/wasm.c | 244++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/wasm.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 287 insertions(+), 20 deletions(-)

diff --git a/src/wasm.c b/src/wasm.c @@ -501,6 +501,64 @@ static char *instr_name(enum instr_tag tag) case i_i64_shr_u: return "i64_shr_u"; case i_i64_rotl: return "i64_rotl"; case i_i64_rotr: return "i64_rotr"; + case i_f32_abs: return "f32_abs"; + case i_f32_neg: return "f32_neg"; + case i_f32_ceil: return "f32_ceil"; + case i_f32_floor: return "f32_floor"; + case i_f32_trunc: return "f32_trunc"; + case i_f32_nearest: return "f32_nearest"; + case i_f32_sqrt: return "f32_sqrt"; + case i_f32_add: return "f32_add"; + case i_f32_sub: return "f32_sub"; + case i_f32_mul: return "f32_mul"; + case i_f32_div: return "f32_div"; + case i_f32_min: return "f32_min"; + case i_f32_max: return "f32_max"; + case i_f32_copysign: return "f32_copysign"; + case i_f64_abs: return "f64_abs"; + case i_f64_neg: return "f64_neg"; + case i_f64_ceil: return "f64_ceil"; + case i_f64_floor: return "f64_floor"; + case i_f64_trunc: return "f64_trunc"; + case i_f64_nearest: return "f64_nearest"; + case i_f64_sqrt: return "f64_sqrt"; + case i_f64_add: return "f64_add"; + case i_f64_sub: return "f64_sub"; + case i_f64_mul: return "f64_mul"; + case i_f64_div: return "f64_div"; + case i_f64_min: return "f64_min"; + case i_f64_max: return "f64_max"; + case i_f64_copysign: return "f64_copysign"; + case i_i32_wrap_i64: return "i32_wrap_i64"; + case i_i32_trunc_f32_s: return "i32_trunc_f32_s"; + case i_i32_trunc_f32_u: return "i32_trunc_f32_u"; + case i_i32_trunc_f64_s: return "i32_trunc_f64_s"; + case i_i32_trunc_f64_u: return "i32_trunc_f64_u"; + case i_i64_extend_i32_s: return "i64_extend_i32_s"; + case i_i64_extend_i32_u: return "i64_extend_i32_u"; + case i_i64_trunc_f32_s: return "i64_trunc_f32_s"; + case i_i64_trunc_f32_u: return "i64_trunc_f32_u"; + case i_i64_trunc_f64_s: return "i64_trunc_f64_s"; + case i_i64_trunc_f64_u: return "i64_trunc_f64_u"; + case i_f32_convert_i32_s: return "f32_convert_i32_s"; + case i_f32_convert_i32_u: return "f32_convert_i32_u"; + case i_f32_convert_i64_s: return "f32_convert_i64_s"; + case i_f32_convert_i64_u: return "f32_convert_i64_u"; + case i_f32_demote_f64: return "f32_demote_f64"; + case i_f64_convert_i32_s: return "f64_convert_i32_s"; + case i_f64_convert_i32_u: return "f64_convert_i32_u"; + case i_f64_convert_i64_s: return "f64_convert_i64_s"; + case i_f64_convert_i64_u: return "f64_convert_i64_u"; + case i_f64_promote_f32: return "f64_promote_f32"; + case i_i32_reinterpret_f32: return "i32_reinterpret_f32"; + case i_i64_reinterpret_f64: return "i64_reinterpret_f64"; + case i_f32_reinterpret_i32: return "f32_reinterpret_i32"; + case i_f64_reinterpret_i64: return "f64_reinterpret_i64"; + case i_i32_extend8_s: return "i32_extend8_s"; + case i_i32_extend16_s: return "i32_extend16_s"; + case i_i64_extend8_s: return "i64_extend8_s"; + case i_i64_extend16_s: return "i64_extend16_s"; + case i_i64_extend32_s: return "i64_extend32_s"; } snprintf(unk, sizeof(unk), "0x%02x", tag); @@ -1603,7 +1661,7 @@ static int parse_instrs_until(struct expr_parser *p, u8 stop_instr, "parse %s instr (0x%x)", instr_name(tag), tag); } - if (tag == stop_instr || + if (tag == stop_instr || (stop_instr == i_if && (tag == i_else || tag == i_end))) { debug("parse_instrs_until ending\n"); *instr_len = p->code->p - *parsed_instrs; @@ -3092,6 +3150,64 @@ static int parse_instr(struct expr_parser *p, u8 tag, struct instr *op) case i_i64_shr_u: case i_i64_rotl: case i_i64_rotr: + case i_f32_abs: + case i_f32_neg: + case i_f32_ceil: + case i_f32_floor: + case i_f32_trunc: + case i_f32_nearest: + case i_f32_sqrt: + case i_f32_add: + case i_f32_sub: + case i_f32_mul: + case i_f32_div: + case i_f32_min: + case i_f32_max: + case i_f32_copysign: + case i_f64_abs: + case i_f64_neg: + case i_f64_ceil: + case i_f64_floor: + case i_f64_trunc: + case i_f64_nearest: + case i_f64_sqrt: + case i_f64_add: + case i_f64_sub: + case i_f64_mul: + case i_f64_div: + case i_f64_min: + case i_f64_max: + case i_f64_copysign: + case i_i32_wrap_i64: + case i_i32_trunc_f32_s: + case i_i32_trunc_f32_u: + case i_i32_trunc_f64_s: + case i_i32_trunc_f64_u: + case i_i64_extend_i32_s: + case i_i64_extend_i32_u: + case i_i64_trunc_f32_s: + case i_i64_trunc_f32_u: + case i_i64_trunc_f64_s: + case i_i64_trunc_f64_u: + case i_f32_convert_i32_s: + case i_f32_convert_i32_u: + case i_f32_convert_i64_s: + case i_f32_convert_i64_u: + case i_f32_demote_f64: + case i_f64_convert_i32_s: + case i_f64_convert_i32_u: + case i_f64_convert_i64_s: + case i_f64_convert_i64_u: + case i_f64_promote_f32: + case i_i32_reinterpret_f32: + case i_i64_reinterpret_f64: + case i_f32_reinterpret_i32: + case i_f64_reinterpret_i64: + case i_i32_extend8_s: + case i_i32_extend16_s: + case i_i64_extend8_s: + case i_i64_extend16_s: + case i_i64_extend32_s: return 1; } @@ -3458,7 +3574,7 @@ static int interp_store(struct wasm_interp *interp, struct memarg *memarg, return interp_error(interp, "memory target"); } - if (N != 0) { + if (N != 0) { if (!wrap_val(&c, N)) { return interp_error(interp, "implement wrap val (truncate?) for %s", @@ -3565,26 +3681,54 @@ static INLINE int interp_memory_size(struct wasm_interp *interp, u8 memidx) return 1; } -static int interp_shl(struct wasm_interp *interp, enum valtype typ) +static INLINE int interp_i32_mul(struct wasm_interp *interp) { struct val lhs, rhs, c; - if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, typ))) { + if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32))) { return interp_error(interp, "gt_u prep"); } - switch (typ) { - case val_i32: - c.i32 = lhs.i32 << rhs.i32; - break; - case val_i64: - c.i64 = lhs.i64 << rhs.i64; - break; - default: - return interp_error(interp, "todo: shl for %s", - valtype_name(typ)); + c.i32 = lhs.i32 * rhs.i32; + + return stack_pushval(interp, &c); +} + +static INLINE int interp_i32_or(struct wasm_interp *interp) +{ + struct val lhs, rhs, c; + + if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32))) { + return interp_error(interp, "gt_u prep"); + } + + c.i32 = lhs.i32 | rhs.i32; + + return stack_pushval(interp, &c); +} + +static INLINE int interp_i32_and(struct wasm_interp *interp) +{ + struct val lhs, rhs, c; + + if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32))) { + return interp_error(interp, "gt_u prep"); } + c.i32 = lhs.i32 & rhs.i32; + + return stack_pushval(interp, &c); +} + +static int interp_i32_shl(struct wasm_interp *interp) +{ + struct val lhs, rhs, c; + + if (unlikely(!interp_prep_binop(interp, &lhs, &rhs, &c, val_i32))) { + return interp_error(interp, "gt_u prep"); + } + + c.i32 = lhs.i32 << rhs.i32; return stack_pushval(interp, &c); } @@ -3607,11 +3751,11 @@ static void print_linestack(struct cursor *stack) printf("\n"); } -static const char *show_instr(struct instr *instr) +static const char *show_instr(struct instr *instr) { struct cursor buf; - static char buffer[64]; - static char tmp[32]; + static char buffer[64]; + static char tmp[32]; int len, i; buffer[sizeof(buffer)-1] = 0; @@ -3677,7 +3821,7 @@ static const char *show_instr(struct instr *instr) case i_i64_store8: case i_i64_store16: case i_i64_store32: - sprintf(tmp, "%d:%d", instr->memarg.offset, instr->memarg.align); + sprintf(tmp, "%d %d", instr->memarg.offset, instr->memarg.align); cursor_push_str(&buf, tmp); break; @@ -3769,6 +3913,64 @@ static const char *show_instr(struct instr *instr) case i_i64_shr_u: case i_i64_rotl: case i_i64_rotr: + case i_f32_abs: + case i_f32_neg: + case i_f32_ceil: + case i_f32_floor: + case i_f32_trunc: + case i_f32_nearest: + case i_f32_sqrt: + case i_f32_add: + case i_f32_sub: + case i_f32_mul: + case i_f32_div: + case i_f32_min: + case i_f32_max: + case i_f32_copysign: + case i_f64_abs: + case i_f64_neg: + case i_f64_ceil: + case i_f64_floor: + case i_f64_trunc: + case i_f64_nearest: + case i_f64_sqrt: + case i_f64_add: + case i_f64_sub: + case i_f64_mul: + case i_f64_div: + case i_f64_min: + case i_f64_max: + case i_f64_copysign: + case i_i32_wrap_i64: + case i_i32_trunc_f32_s: + case i_i32_trunc_f32_u: + case i_i32_trunc_f64_s: + case i_i32_trunc_f64_u: + case i_i64_extend_i32_s: + case i_i64_extend_i32_u: + case i_i64_trunc_f32_s: + case i_i64_trunc_f32_u: + case i_i64_trunc_f64_s: + case i_i64_trunc_f64_u: + case i_f32_convert_i32_s: + case i_f32_convert_i32_u: + case i_f32_convert_i64_s: + case i_f32_convert_i64_u: + case i_f32_demote_f64: + case i_f64_convert_i32_s: + case i_f64_convert_i32_u: + case i_f64_convert_i64_s: + case i_f64_convert_i64_u: + case i_f64_promote_f32: + case i_i32_reinterpret_f32: + case i_i64_reinterpret_f64: + case i_f32_reinterpret_i32: + case i_f64_reinterpret_i64: + case i_i32_extend8_s: + case i_i32_extend16_s: + case i_i64_extend8_s: + case i_i64_extend16_s: + case i_i64_extend32_s: break; } @@ -3802,11 +4004,13 @@ static int interp_instr(struct wasm_interp *interp, struct instr *instr) case i_i32_add: return interp_i32_add(interp); case i_i32_sub: return interp_i32_sub(interp); case i_i32_const: return interp_i32_const(interp, instr->integer); - case i_i32_gt_u: return interp_gt(interp, val_i32, 0); case i_i32_lt_s: return interp_lt(interp, val_i32, 1); case i_i32_lt_u: return interp_lt(interp, val_i32, 0); - case i_i32_shl: return interp_shl(interp, val_i32); + case i_i32_shl: return interp_i32_shl(interp); + case i_i32_or: return interp_i32_or(interp); + case i_i32_and: return interp_i32_and(interp); + case i_i32_mul: return interp_i32_mul(interp); case i_i32_store: return interp_store(interp, &instr->memarg, val_i32, 0); case i_i32_store8: return interp_store(interp, &instr->memarg, val_i32, 8); diff --git a/src/wasm.h b/src/wasm.h @@ -382,6 +382,69 @@ enum instr_tag { i_i64_rotl = 0x89, i_i64_rotr = 0x8A, + i_f32_abs = 0x8b, + i_f32_neg = 0x8c, + i_f32_ceil = 0x8d, + i_f32_floor = 0x8e, + i_f32_trunc = 0x8f, + i_f32_nearest = 0x90, + i_f32_sqrt = 0x91, + i_f32_add = 0x92, + i_f32_sub = 0x93, + i_f32_mul = 0x94, + i_f32_div = 0x95, + i_f32_min = 0x96, + i_f32_max = 0x97, + i_f32_copysign = 0x98, + + i_f64_abs = 0x99, + i_f64_neg = 0x9a, + i_f64_ceil = 0x9b, + i_f64_floor = 0x9c, + i_f64_trunc = 0x9d, + i_f64_nearest = 0x9e, + i_f64_sqrt = 0x9f, + i_f64_add = 0xa0, + i_f64_sub = 0xa1, + i_f64_mul = 0xa2, + i_f64_div = 0xa3, + i_f64_min = 0xa4, + i_f64_max = 0xa5, + i_f64_copysign = 0xa6, + + i_i32_wrap_i64 = 0xa7, + i_i32_trunc_f32_s = 0xa8, + i_i32_trunc_f32_u = 0xa9, + i_i32_trunc_f64_s = 0xaa, + i_i32_trunc_f64_u = 0xab, + i_i64_extend_i32_s = 0xac, + i_i64_extend_i32_u = 0xad, + i_i64_trunc_f32_s = 0xae, + i_i64_trunc_f32_u = 0xaf, + i_i64_trunc_f64_s = 0xb0, + i_i64_trunc_f64_u = 0xb1, + i_f32_convert_i32_s = 0xb2, + i_f32_convert_i32_u = 0xb3, + i_f32_convert_i64_s = 0xb4, + i_f32_convert_i64_u = 0xb5, + i_f32_demote_f64 = 0xb6, + i_f64_convert_i32_s = 0xb7, + i_f64_convert_i32_u = 0xb8, + i_f64_convert_i64_s = 0xb9, + i_f64_convert_i64_u = 0xba, + i_f64_promote_f32 = 0xbb, + + i_i32_reinterpret_f32 = 0xbc, + i_i64_reinterpret_f64 = 0xbd, + i_f32_reinterpret_i32 = 0xbe, + i_f64_reinterpret_i64 = 0xbf, + + i_i32_extend8_s = 0xc0, + i_i32_extend16_s = 0xc1, + i_i64_extend8_s = 0xc2, + i_i64_extend16_s = 0xc3, + i_i64_extend32_s = 0xc4, + /* TODO: more instrs */ };