diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index fb2c79408..0b89edf5e 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -37,6 +37,10 @@ extern "C" { do { \ *(int64 *)(addr) = (int64)(value); \ } while (0) +#define PUT_V128_TO_ADDR(addr, value) \ + do { \ + *(V128 *)(addr) = (value); \ + } while (0) #define PUT_F64_TO_ADDR(addr, value) \ do { \ *(float64 *)(addr) = (float64)(value); \ @@ -49,6 +53,7 @@ extern "C" { #define GET_I64_FROM_ADDR(addr) (*(int64 *)(addr)) #define GET_F64_FROM_ADDR(addr) (*(float64 *)(addr)) #define GET_REF_FROM_ADDR(addr) (*(void **)(addr)) +#define GET_V128_FROM_ADDR(addr) (*(V128 *)(addr)) /* For STORE opcodes */ #define STORE_I64 PUT_I64_TO_ADDR @@ -83,6 +88,15 @@ STORE_U8(void *addr, uint8_t value) #else /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */ +#define PUT_V128_TO_ADDR(addr, value) \ + do { \ + uint32 *addr_u32 = (uint32 *)(addr); \ + addr_u32[0] = (value).i32x4[0]; \ + addr_u32[1] = (value).i32x4[1]; \ + addr_u32[2] = (value).i32x4[2]; \ + addr_u32[3] = (value).i32x4[3]; \ + } while (0) + #define PUT_I64_TO_ADDR(addr, value) \ do { \ uint32 *addr_u32 = (uint32 *)(addr); \ @@ -124,6 +138,17 @@ STORE_U8(void *addr, uint8_t value) } while (0) #endif +static inline V128 +GET_V128_FROM_ADDR(uint32 *addr) +{ + V128 ret; + ret.i32x4[0] = addr[0]; + ret.i32x4[1] = addr[1]; + ret.i32x4[2] = addr[2]; + ret.i32x4[3] = addr[3]; + return ret; +} + static inline int64 GET_I64_FROM_ADDR(uint32 *addr) { diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 1d7ca8f90..fdd05e544 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -433,6 +433,8 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) (type) GET_I64_FROM_ADDR(frame_lp + *(int16 *)(frame_ip + off)) #define GET_OPERAND_F64(type, off) \ (type) GET_F64_FROM_ADDR(frame_lp + *(int16 *)(frame_ip + off)) +#define GET_OPERAND_V128(off) \ + GET_V128_FROM_ADDR(frame_lp + *(int16 *)(frame_ip + off)) #define GET_OPERAND_REF(type, off) \ (type) GET_REF_FROM_ADDR(frame_lp + *(int16 *)(frame_ip + off)) @@ -5642,7 +5644,37 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #endif goto call_func_from_entry; } +#if WASM_ENABLE_SIMD != 0 + HANDLE_OP(WASM_OP_SIMD_PREFIX) + { + GET_OPCODE(); + switch (opcode) { + case SIMD_v128_const: + { + uint8 *orig_ip = frame_ip; + + frame_ip += sizeof(V128); + addr_ret = GET_OFFSET(); + + PUT_V128_TO_ADDR(frame_lp + addr_ret, *(V128 *)orig_ip); + break; + } + case SIMD_v128_any_true: + { + V128 value = GET_OPERAND_V128(0); + frame_ip += 2; + addr_ret = GET_OFFSET(); + frame_lp[addr_ret] = + value.i64x2[0] != 0 || value.i64x2[1] != 0; + break; + } + default: + wasm_set_exception(module, "unsupported SIMD opcode"); + } + HANDLE_OP_END(); + } +#endif HANDLE_OP(WASM_OP_CALL) { #if WASM_ENABLE_THREAD_MGR != 0 diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index ff3501e3d..5005fc63b 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -307,7 +307,8 @@ is_byte_a_type(uint8 type) } #if WASM_ENABLE_SIMD != 0 -#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) +#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ + || (WASM_ENABLE_FAST_INTERP != 0) static V128 read_i8x16(uint8 *p_buf, char *error_buf, uint32 error_buf_size) { @@ -320,7 +321,8 @@ read_i8x16(uint8 *p_buf, char *error_buf, uint32 error_buf_size) return result; } -#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) */ +#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) || \ + (WASM_ENABLE_FAST_INTERP != 0) */ #endif /* end of WASM_ENABLE_SIMD */ static void * @@ -707,7 +709,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end, goto fail; break; #if WASM_ENABLE_SIMD != 0 -#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) +#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ + || (WASM_ENABLE_FAST_INTERP != 0) /* v128.const */ case INIT_EXPR_TYPE_V128_CONST: { @@ -736,7 +739,8 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end, #endif break; } -#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) */ +#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) || \ + (WASM_ENABLE_FAST_INTERP != 0) */ #endif /* end of WASM_ENABLE_SIMD */ #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 @@ -4105,7 +4109,8 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, return false; } #if WASM_ENABLE_SIMD != 0 -#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) +#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ + || (WASM_ENABLE_FAST_INTERP != 0) /* TODO: check func type, if it has v128 param or result, report error */ #endif @@ -7566,7 +7571,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache, } #if WASM_ENABLE_SIMD != 0 -#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) +#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ + || (WASM_ENABLE_FAST_INTERP != 0) case WASM_OP_SIMD_PREFIX: { uint32 opcode1; @@ -7659,7 +7665,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache, } break; } -#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) */ +#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) || \ + (WASM_ENABLE_FAST_INTERP != 0) */ #endif /* end of WASM_ENABLE_SIMD */ #if WASM_ENABLE_SHARED_MEMORY != 0 @@ -9903,7 +9910,8 @@ check_memory_access_align(uint8 opcode, uint32 align, char *error_buf, } #if WASM_ENABLE_SIMD != 0 -#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) +#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ + || (WASM_ENABLE_FAST_INTERP != 0) static bool check_simd_memory_access_align(uint8 opcode, uint32 align, char *error_buf, uint32 error_buf_size) @@ -12120,10 +12128,20 @@ re_scan: #endif } #if WASM_ENABLE_SIMD != 0 -#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) +#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ + || (WASM_ENABLE_FAST_INTERP != 0) else if (*(loader_ctx->frame_ref - 1) == VALUE_TYPE_V128) { loader_ctx->frame_ref -= 4; loader_ctx->stack_cell_num -= 4; +#if WASM_ENABLE_FAST_INTERP != 0 + skip_label(); + loader_ctx->frame_offset -= 4; + if ((*(loader_ctx->frame_offset) + > loader_ctx->start_dynamic_offset) + && (*(loader_ctx->frame_offset) + < loader_ctx->max_dynamic_offset)) + loader_ctx->dynamic_offset -= 4; +#endif } #endif #endif @@ -12210,10 +12228,12 @@ re_scan: #endif /* end of WASM_ENABLE_FAST_INTERP */ break; #if WASM_ENABLE_SIMD != 0 -#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) +#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ + || (WASM_ENABLE_FAST_INTERP != 0) case VALUE_TYPE_V128: break; -#endif /* (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) */ +#endif /* (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) || \ + (WASM_ENABLE_FAST_INTERP != 0) */ #endif /* WASM_ENABLE_SIMD != 0 */ default: { @@ -12308,8 +12328,9 @@ re_scan: uint8 opcode_tmp = WASM_OP_SELECT; if (type == VALUE_TYPE_V128) { -#if (WASM_ENABLE_SIMD == 0) \ - || ((WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)) +#if (WASM_ENABLE_SIMD == 0) \ + || ((WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0) \ + && (WASM_ENABLE_FAST_INTERP == 0)) set_error_buf(error_buf, error_buf_size, "SIMD v128 type isn't supported"); goto fail; @@ -14870,7 +14891,8 @@ re_scan: } #if WASM_ENABLE_SIMD != 0 -#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) +#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ + || (WASM_ENABLE_FAST_INTERP != 0) case WASM_OP_SIMD_PREFIX: { uint32 opcode1; @@ -14882,6 +14904,10 @@ re_scan: read_leb_uint32(p, p_end, opcode1); +#if WASM_ENABLE_FAST_INTERP != 0 + emit_byte(loader_ctx, opcode1); +#endif + /* follow the order of enum WASMSimdEXTOpcode in wasm_opcode.h */ switch (opcode1) { @@ -14938,7 +14964,13 @@ re_scan: /* basic operation */ case SIMD_v128_const: { + uint64 high, low; CHECK_BUF1(p, p_end, 16); +#if WASM_ENABLE_FAST_INTERP != 0 + wasm_runtime_read_v128(p, &high, &low); + emit_uint64(loader_ctx, high); + emit_uint64(loader_ctx, low); +#endif p += 16; PUSH_V128(); break; @@ -15524,7 +15556,8 @@ re_scan: } break; } -#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) */ +#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) || \ + (WASM_ENABLE_FAST_INTERP != 0) */ #endif /* end of WASM_ENABLE_SIMD */ #if WASM_ENABLE_SHARED_MEMORY != 0 diff --git a/core/iwasm/interpreter/wasm_opcode.h b/core/iwasm/interpreter/wasm_opcode.h index 76647454b..1424840e7 100644 --- a/core/iwasm/interpreter/wasm_opcode.h +++ b/core/iwasm/interpreter/wasm_opcode.h @@ -782,7 +782,8 @@ typedef enum WASMAtomicEXTOpcode { #define SET_GOTO_TABLE_ELEM(opcode) [opcode] = HANDLE_OPCODE(opcode) -#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_SIMD != 0 +#if (WASM_ENABLE_JIT != 0 || WASM_ENABLE_FAST_INTERP != 0) \ + && WASM_ENABLE_SIMD != 0 #define SET_GOTO_TABLE_SIMD_PREFIX_ELEM() \ SET_GOTO_TABLE_ELEM(WASM_OP_SIMD_PREFIX), #else