diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index 82f70ca3d..5d9664ee8 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -1316,6 +1316,13 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index) return false; break; +#if WASM_ENABLE_SIMD != 0 + case WASM_OP_SELECT_128: + if (!aot_compile_op_select(comp_ctx, func_ctx, true)) + return false; + break; +#endif + #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 case WASM_OP_SELECT_T: { diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index f33ad60e3..e0e5073e6 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1888,6 +1888,28 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, } HANDLE_OP_END(); } +#if WASM_ENABLE_JIT != 0 \ + || WASM_ENABLE_FAST_INTERP != 0 && WASM_ENABLE_SIMD != 0 + HANDLE_OP(WASM_OP_SELECT_128) + { + cond = frame_lp[GET_OFFSET()]; + addr1 = GET_OFFSET(); + addr2 = GET_OFFSET(); + addr_ret = GET_OFFSET(); + + if (!cond) { + if (addr_ret != addr1) + PUT_V128_TO_ADDR(frame_lp + addr_ret, + GET_V128_FROM_ADDR(frame_lp + addr1)); + } + else { + if (addr_ret != addr2) + PUT_V128_TO_ADDR(frame_lp + addr_ret, + GET_V128_FROM_ADDR(frame_lp + addr2)); + } + HANDLE_OP_END(); + } +#endif #if WASM_ENABLE_GC != 0 HANDLE_OP(WASM_OP_SELECT_T) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index fc68e5966..f6f8893a2 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -7295,6 +7295,9 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache, case WASM_OP_SELECT: case WASM_OP_DROP_64: case WASM_OP_SELECT_64: +#if WASM_ENABLE_FAST_INTERP != 0 && WASM_ENABLE_SIMD != 0 + case WASM_OP_SELECT_128: +#endif break; #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 @@ -12770,8 +12773,7 @@ re_scan: case VALUE_TYPE_F64: #if WASM_ENABLE_FAST_INTERP == 0 *(p - 1) = WASM_OP_SELECT_64; -#endif -#if WASM_ENABLE_FAST_INTERP != 0 +#else if (loader_ctx->p_code_compiled) { uint8 opcode_tmp = WASM_OP_SELECT_64; #if WASM_ENABLE_LABELS_AS_VALUES != 0 @@ -12779,8 +12781,7 @@ re_scan: *(void **)(p_code_compiled_tmp - sizeof(void *)) = handle_table[opcode_tmp]; -#else -#if UINTPTR_MAX == UINT64_MAX +#elif UINTPTR_MAX == UINT64_MAX /* emit int32 relative offset in 64-bit target */ int32 offset = @@ -12793,7 +12794,6 @@ re_scan: *(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) = (uint32)(uintptr_t)handle_table[opcode_tmp]; -#endif #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ #else /* else of WASM_ENABLE_LABELS_AS_VALUES */ #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 @@ -12809,6 +12809,39 @@ re_scan: #if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) \ || (WASM_ENABLE_FAST_INTERP != 0) case VALUE_TYPE_V128: +#if WASM_ENABLE_FAST_INTERP == 0 + *(p - 1) = WASM_OP_SELECT_128; +#else + if (loader_ctx->p_code_compiled) { + uint8 opcode_tmp = WASM_OP_SELECT_128; +#if WASM_ENABLE_LABELS_AS_VALUES != 0 +#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 + *(void **)(p_code_compiled_tmp + - sizeof(void *)) = + handle_table[opcode_tmp]; +#elif UINTPTR_MAX == UINT64_MAX + /* emit int32 relative offset in 64-bit target + */ + int32 offset = + (int32)((uint8 *)handle_table[opcode_tmp] + - (uint8 *)handle_table[0]); + *(int32 *)(p_code_compiled_tmp + - sizeof(int32)) = offset; +#else + /* emit uint32 label address in 32-bit target */ + *(uint32 *)(p_code_compiled_tmp + - sizeof(uint32)) = + (uint32)(uintptr_t)handle_table[opcode_tmp]; +#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ +#else /* else of WASM_ENABLE_LABELS_AS_VALUES */ +#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 + *(p_code_compiled_tmp - 1) = opcode_tmp; +#else + *(p_code_compiled_tmp - 2) = opcode_tmp; +#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ +#endif /* end of WASM_ENABLE_LABELS_AS_VALUES */ + } +#endif /* end of WASM_ENABLE_FAST_INTERP */ break; #endif /* (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) || \ (WASM_ENABLE_FAST_INTERP != 0) */ @@ -12906,12 +12939,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) \ - && (WASM_ENABLE_FAST_INTERP == 0)) - set_error_buf(error_buf, error_buf_size, - "SIMD v128 type isn't supported"); - goto fail; +#if WASM_ENABLE_JIT != 0 \ + || WASM_ENABLE_FAST_INTERP != 0 && WASM_ENABLE_SIMD != 0 + opcode_tmp = WASM_OP_SELECT_128; #endif } else { diff --git a/core/iwasm/interpreter/wasm_opcode.h b/core/iwasm/interpreter/wasm_opcode.h index 9660bb123..07e3d9f09 100644 --- a/core/iwasm/interpreter/wasm_opcode.h +++ b/core/iwasm/interpreter/wasm_opcode.h @@ -278,13 +278,14 @@ typedef enum WASMOpcode { DEBUG_OP_BREAK = 0xdc, /* debug break point */ #endif -#if WASM_ENABLE_JIT != 0 \ - || WASM_ENABLE_FAST_INTERP != 0 && WASM_ENABLE_SIMD != 0 +#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_FAST_INTERP != 0 \ + || WASM_ENABLE_WAMR_COMPILER != 0 && WASM_ENABLE_SIMD != 0 EXT_OP_SET_LOCAL_FAST_V128 = 0xdd, EXT_OP_TEE_LOCAL_FAST_V128 = 0xde, EXT_OP_COPY_STACK_TOP_V128 = 0xdf, WASM_OP_GET_GLOBAL_V128 = 0xe0, WASM_OP_SET_GLOBAL_V128 = 0xe1, + WASM_OP_SELECT_128 = 0xe2, #endif /* Post-MVP extend op prefix */ @@ -804,7 +805,8 @@ typedef enum WASMAtomicEXTOpcode { SET_GOTO_TABLE_ELEM(EXT_OP_TEE_LOCAL_FAST_V128), /* 0xde */ \ SET_GOTO_TABLE_ELEM(EXT_OP_COPY_STACK_TOP_V128), /* 0xdf */ \ SET_GOTO_TABLE_ELEM(WASM_OP_GET_GLOBAL_V128), /* 0xe0 */ \ - SET_GOTO_TABLE_ELEM(WASM_OP_SET_GLOBAL_V128), /* 0xe1 */ + SET_GOTO_TABLE_ELEM(WASM_OP_SET_GLOBAL_V128), /* 0xe1 */ \ + SET_GOTO_TABLE_ELEM(WASM_OP_SELECT_128), /* 0xe2 */ #else #define DEF_EXT_V128_HANDLE()