From 0df0fe7a36ac86215f42b59b50b8b2c71212e8a0 Mon Sep 17 00:00:00 2001 From: Maks Litskevich Date: Fri, 3 Jan 2025 11:00:05 +0000 Subject: [PATCH] implement local and function calls for v128 in the fast interpreter --- core/iwasm/interpreter/wasm_interp_fast.c | 55 +++++++++++++- core/iwasm/interpreter/wasm_loader.c | 11 ++- core/iwasm/interpreter/wasm_opcode.h | 92 ++++++++++++----------- 3 files changed, 111 insertions(+), 47 deletions(-) diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 4e6dc00228..95e4e79b91 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1699,6 +1699,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, GET_OPERAND(uint64, I64, off)); ret_offset += 2; } + else if (ret_types[ret_idx] == VALUE_TYPE_V128) { + PUT_V128_TO_ADDR(prev_frame->lp + ret_offset, + GET_OPERAND_V128(off)); + ret_offset += 4; + } #if WASM_ENABLE_GC != 0 else if (wasm_is_type_reftype(ret_types[ret_idx])) { PUT_REF_TO_ADDR(prev_frame->lp + ret_offset, @@ -3535,6 +3540,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, frame_ip += 2; HANDLE_OP_END(); } + HANDLE_OP(EXT_OP_SET_LOCAL_FAST_V128) + HANDLE_OP(EXT_OP_TEE_LOCAL_FAST_V128) + { + /* clang-format off */ +#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 + local_offset = *frame_ip++; +#else + local_offset = *frame_ip; + frame_ip += 2; +#endif + /* clang-format on */ + PUT_V128_TO_ADDR((uint32 *)(frame_lp + local_offset), + GET_OPERAND_V128(0)); + frame_ip += 2; + HANDLE_OP_END(); + } HANDLE_OP(WASM_OP_GET_GLOBAL) { @@ -4872,6 +4893,27 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, PUT_I64_TO_ADDR(frame_lp + addr2, GET_I64_FROM_ADDR(frame_lp + addr1)); +#if WASM_ENABLE_GC != 0 + /* Ignore constants because they are not reference */ + if (addr1 >= 0) { + if (*FRAME_REF(addr1)) { + CLEAR_FRAME_REF(addr1); + SET_FRAME_REF(addr2); + } + } +#endif + + HANDLE_OP_END(); + } + + HANDLE_OP(EXT_OP_COPY_STACK_TOP_V128) + { + addr1 = GET_OFFSET(); + addr2 = GET_OFFSET(); + + PUT_V128_TO_ADDR(frame_lp + addr2, + GET_V128_FROM_ADDR(frame_lp + addr1)); + #if WASM_ENABLE_GC != 0 /* Ignore constants because they are not reference */ if (addr1 >= 0) { @@ -6081,8 +6123,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #define SIMD_DOUBLE_OP(simde_func) \ do { \ - V128 v1 = POP_V128(); \ V128 v2 = POP_V128(); \ + V128 v1 = POP_V128(); \ addr_ret = GET_OFFSET(); \ \ simde_v128_t simde_result = simde_func(SIMD_V128_TO_SIMDE_V128(v1), \ @@ -6920,6 +6962,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, } case SIMD_i32x4_add: { + SIMD_DOUBLE_OP(simde_wasm_i32x4_add); break; } @@ -7454,8 +7497,14 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, } for (i = 0; i < cur_func->param_count; i++) { - if (cur_func->param_types[i] == VALUE_TYPE_I64 - || cur_func->param_types[i] == VALUE_TYPE_F64) { + if (cur_func->param_types[i] == VALUE_TYPE_V128) { + PUT_V128_TO_ADDR( + outs_area->lp, + GET_OPERAND_V128(2 * (cur_func->param_count - i - 1))); + outs_area->lp += 4; + } + else if (cur_func->param_types[i] == VALUE_TYPE_I64 + || cur_func->param_types[i] == VALUE_TYPE_F64) { PUT_I64_TO_ADDR( outs_area->lp, GET_OPERAND(uint64, I64, diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index a39dff89dc..4e89a7c5f5 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -12944,10 +12944,19 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_label(EXT_OP_SET_LOCAL_FAST); emit_byte(loader_ctx, (uint8)local_offset); } - else { + else if (is_64bit_type(local_type)) { emit_label(EXT_OP_SET_LOCAL_FAST_I64); emit_byte(loader_ctx, (uint8)local_offset); } + else if (local_type == VALUE_TYPE_V128) { + emit_label(EXT_OP_SET_LOCAL_FAST_V128); + emit_byte(loader_ctx, (uint8)local_offset); + } + else { + set_error_buf(error_buf, error_buf_size, + "unknown local type"); + goto fail; + } POP_OFFSET_TYPE(local_type); } } diff --git a/core/iwasm/interpreter/wasm_opcode.h b/core/iwasm/interpreter/wasm_opcode.h index 75d30c9b31..bde5488a6c 100644 --- a/core/iwasm/interpreter/wasm_opcode.h +++ b/core/iwasm/interpreter/wasm_opcode.h @@ -250,32 +250,35 @@ typedef enum WASMOpcode { /* extend op code */ EXT_OP_GET_LOCAL_FAST = 0xc7, EXT_OP_SET_LOCAL_FAST_I64 = 0xc8, - EXT_OP_SET_LOCAL_FAST = 0xc9, - EXT_OP_TEE_LOCAL_FAST = 0xca, - EXT_OP_TEE_LOCAL_FAST_I64 = 0xcb, - EXT_OP_COPY_STACK_TOP = 0xcc, - EXT_OP_COPY_STACK_TOP_I64 = 0xcd, - EXT_OP_COPY_STACK_VALUES = 0xce, - - WASM_OP_IMPDEP = 0xcf, - - WASM_OP_REF_NULL = 0xd0, /* ref.null */ - WASM_OP_REF_IS_NULL = 0xd1, /* ref.is_null */ - WASM_OP_REF_FUNC = 0xd2, /* ref.func */ - WASM_OP_REF_EQ = 0xd3, /* ref.eq */ - WASM_OP_REF_AS_NON_NULL = 0xd4, /* ref.as_non_null */ - WASM_OP_BR_ON_NULL = 0xd5, /* br_on_null */ - WASM_OP_BR_ON_NON_NULL = 0xd6, /* br_on_non_null */ - - EXT_OP_BLOCK = 0xd7, /* block with blocktype */ - EXT_OP_LOOP = 0xd8, /* loop with blocktype */ - EXT_OP_IF = 0xd9, /* if with blocktype */ - EXT_OP_BR_TABLE_CACHE = 0xda, /* br_table from cache */ - - EXT_OP_TRY = 0xdb, /* try block with blocktype */ + EXT_OP_SET_LOCAL_FAST_V128 = 0xc9, + EXT_OP_SET_LOCAL_FAST = 0xca, + EXT_OP_TEE_LOCAL_FAST = 0xcb, + EXT_OP_TEE_LOCAL_FAST_I64 = 0xcc, + EXT_OP_TEE_LOCAL_FAST_V128 = 0xcd, + EXT_OP_COPY_STACK_TOP = 0xce, + EXT_OP_COPY_STACK_TOP_I64 = 0xcf, + EXT_OP_COPY_STACK_TOP_V128 = 0xd0, + EXT_OP_COPY_STACK_VALUES = 0xd1, + + WASM_OP_IMPDEP = 0xd2, + + WASM_OP_REF_NULL = 0xd3, /* ref.null */ + WASM_OP_REF_IS_NULL = 0xd4, /* ref.is_null */ + WASM_OP_REF_FUNC = 0xd5, /* ref.func */ + WASM_OP_REF_EQ = 0xd6, /* ref.eq */ + WASM_OP_REF_AS_NON_NULL = 0xd7, /* ref.as_non_null */ + WASM_OP_BR_ON_NULL = 0xd8, /* br_on_null */ + WASM_OP_BR_ON_NON_NULL = 0xd9, /* br_on_non_null */ + + EXT_OP_BLOCK = 0xda, /* block with blocktype */ + EXT_OP_LOOP = 0xdb, /* loop with blocktype */ + EXT_OP_IF = 0xdc, /* if with blocktype */ + EXT_OP_BR_TABLE_CACHE = 0xdd, /* br_table from cache */ + + EXT_OP_TRY = 0xde, /* try block with blocktype */ #if WASM_ENABLE_DEBUG_INTERP != 0 - DEBUG_OP_BREAK = 0xdc, /* debug break point */ + DEBUG_OP_BREAK = 0xdf, /* debug break point */ #endif /* Post-MVP extend op prefix */ @@ -998,25 +1001,28 @@ typedef enum WASMAtomicEXTOpcode { HANDLE_OPCODE(WASM_OP_SELECT_64), /* 0xc6 */ \ HANDLE_OPCODE(EXT_OP_GET_LOCAL_FAST), /* 0xc7 */ \ HANDLE_OPCODE(EXT_OP_SET_LOCAL_FAST_I64), /* 0xc8 */ \ - HANDLE_OPCODE(EXT_OP_SET_LOCAL_FAST), /* 0xc9 */ \ - HANDLE_OPCODE(EXT_OP_TEE_LOCAL_FAST), /* 0xca */ \ - HANDLE_OPCODE(EXT_OP_TEE_LOCAL_FAST_I64), /* 0xcb */ \ - HANDLE_OPCODE(EXT_OP_COPY_STACK_TOP), /* 0xcc */ \ - HANDLE_OPCODE(EXT_OP_COPY_STACK_TOP_I64), /* 0xcd */ \ - HANDLE_OPCODE(EXT_OP_COPY_STACK_VALUES), /* 0xce */ \ - HANDLE_OPCODE(WASM_OP_IMPDEP), /* 0xcf */ \ - HANDLE_OPCODE(WASM_OP_REF_NULL), /* 0xd0 */ \ - HANDLE_OPCODE(WASM_OP_REF_IS_NULL), /* 0xd1 */ \ - HANDLE_OPCODE(WASM_OP_REF_FUNC), /* 0xd2 */ \ - HANDLE_OPCODE(WASM_OP_REF_EQ), /* 0xd3 */ \ - HANDLE_OPCODE(WASM_OP_REF_AS_NON_NULL), /* 0xd4 */ \ - HANDLE_OPCODE(WASM_OP_BR_ON_NULL), /* 0xd5 */ \ - HANDLE_OPCODE(WASM_OP_BR_ON_NON_NULL), /* 0xd6 */ \ - HANDLE_OPCODE(EXT_OP_BLOCK), /* 0xd7 */ \ - HANDLE_OPCODE(EXT_OP_LOOP), /* 0xd8 */ \ - HANDLE_OPCODE(EXT_OP_IF), /* 0xd9 */ \ - HANDLE_OPCODE(EXT_OP_BR_TABLE_CACHE), /* 0xda */ \ - HANDLE_OPCODE(EXT_OP_TRY), /* 0xdb */ \ + HANDLE_OPCODE(EXT_OP_SET_LOCAL_FAST_V128), /* 0xc9 */ \ + HANDLE_OPCODE(EXT_OP_SET_LOCAL_FAST), /* 0xca */ \ + HANDLE_OPCODE(EXT_OP_TEE_LOCAL_FAST), /* 0xcb */ \ + HANDLE_OPCODE(EXT_OP_TEE_LOCAL_FAST_I64), /* 0xcc */ \ + HANDLE_OPCODE(EXT_OP_TEE_LOCAL_FAST_V128), /* 0xcd */ \ + HANDLE_OPCODE(EXT_OP_COPY_STACK_TOP), /* 0xce */ \ + HANDLE_OPCODE(EXT_OP_COPY_STACK_TOP_I64), /* 0xcf */ \ + HANDLE_OPCODE(EXT_OP_COPY_STACK_TOP_V128), /* 0xd0 */ \ + HANDLE_OPCODE(EXT_OP_COPY_STACK_VALUES), /* 0xd1 */ \ + HANDLE_OPCODE(WASM_OP_IMPDEP), /* 0xd2 */ \ + HANDLE_OPCODE(WASM_OP_REF_NULL), /* 0xd3 */ \ + HANDLE_OPCODE(WASM_OP_REF_IS_NULL), /* 0xd4 */ \ + HANDLE_OPCODE(WASM_OP_REF_FUNC), /* 0xd5 */ \ + HANDLE_OPCODE(WASM_OP_REF_EQ), /* 0xd6 */ \ + HANDLE_OPCODE(WASM_OP_REF_AS_NON_NULL), /* 0xd7 */ \ + HANDLE_OPCODE(WASM_OP_BR_ON_NULL), /* 0xd8 */ \ + HANDLE_OPCODE(WASM_OP_BR_ON_NON_NULL), /* 0xd9 */ \ + HANDLE_OPCODE(EXT_OP_BLOCK), /* 0xda */ \ + HANDLE_OPCODE(EXT_OP_LOOP), /* 0xdb */ \ + HANDLE_OPCODE(EXT_OP_IF), /* 0xdc */ \ + HANDLE_OPCODE(EXT_OP_BR_TABLE_CACHE), /* 0xdd */ \ + HANDLE_OPCODE(EXT_OP_TRY), /* 0xde */ \ SET_GOTO_TABLE_ELEM(WASM_OP_GC_PREFIX), /* 0xfb */ \ SET_GOTO_TABLE_ELEM(WASM_OP_MISC_PREFIX), /* 0xfc */ \ SET_GOTO_TABLE_SIMD_PREFIX_ELEM() /* 0xfd */ \