Explorar o código

implement local and function calls for v128 in the fast interpreter

Maks Litskevich hai 1 ano
pai
achega
474acd72e3

+ 55 - 3
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,
@@ -3536,6 +3541,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                 HANDLE_OP_END();
             }
 
+#if WASM_ENABLE_SIMDE != 0
+            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();
+            }
+#endif
             HANDLE_OP(WASM_OP_GET_GLOBAL)
             {
                 global_idx = read_uint32(frame_ip);
@@ -4884,6 +4907,28 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
                 HANDLE_OP_END();
             }
+#if WASM_ENABLE_SIMDE != 0
+            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) {
+                    if (*FRAME_REF(addr1)) {
+                        CLEAR_FRAME_REF(addr1);
+                        SET_FRAME_REF(addr2);
+                    }
+                }
+#endif
+
+                HANDLE_OP_END();
+            }
+#endif
 
             HANDLE_OP(EXT_OP_COPY_STACK_VALUES)
             {
@@ -6079,8 +6124,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),  \
@@ -6946,6 +6991,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                     }
                     case SIMD_i32x4_add:
                     {
+
                         SIMD_DOUBLE_OP(simde_wasm_i32x4_add);
                         break;
                     }
@@ -7480,8 +7526,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,

+ 12 - 1
core/iwasm/interpreter/wasm_loader.c

@@ -12944,10 +12944,21 @@ re_scan:
                             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);
                         }
+#if WASM_ENABLE_SIMDE != 0
+                        else if (local_type == VALUE_TYPE_V128) {
+                            emit_label(EXT_OP_SET_LOCAL_FAST_V128);
+                            emit_byte(loader_ctx, (uint8)local_offset);
+                        }
+#endif
+                        else {
+                            set_error_buf(error_buf, error_buf_size,
+                                          "unknown local type");
+                            goto fail;
+                        }
                         POP_OFFSET_TYPE(local_type);
                     }
                 }

+ 18 - 1
core/iwasm/interpreter/wasm_opcode.h

@@ -278,6 +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_SIMDE != 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,
+#endif
+
     /* Post-MVP extend op prefix */
     WASM_OP_GC_PREFIX = 0xfb,
     WASM_OP_MISC_PREFIX = 0xfc,
@@ -790,6 +798,15 @@ typedef enum WASMAtomicEXTOpcode {
 #define SET_GOTO_TABLE_SIMD_PREFIX_ELEM()
 #endif
 
+#if (WASM_ENABLE_FAST_INTERP != 0 && WASM_ENABLE_SIMDE != 0) \
+    && WASM_ENABLE_SIMD != 0
+#define DEF_EXT_V128_HANDLE()                            \
+    SET_GOTO_TABLE_ELEM(EXT_OP_SET_LOCAL_FAST_V128),     \
+        SET_GOTO_TABLE_ELEM(EXT_OP_TEE_LOCAL_FAST_V128), \
+        SET_GOTO_TABLE_ELEM(EXT_OP_COPY_STACK_TOP_V128),
+#else
+#define DEF_EXT_V128_HANDLE()
+#endif
 /*
  * Macro used to generate computed goto tables for the C interpreter.
  */
@@ -1021,7 +1038,7 @@ typedef enum WASMAtomicEXTOpcode {
         SET_GOTO_TABLE_ELEM(WASM_OP_MISC_PREFIX),    /* 0xfc */ \
         SET_GOTO_TABLE_SIMD_PREFIX_ELEM()            /* 0xfd */ \
         SET_GOTO_TABLE_ELEM(WASM_OP_ATOMIC_PREFIX),  /* 0xfe */ \
-        DEF_DEBUG_BREAK_HANDLE()                                \
+        DEF_DEBUG_BREAK_HANDLE() DEF_EXT_V128_HANDLE()          \
     };
 
 #ifdef __cplusplus