Skip to content

Commit

Permalink
Add V128 comparison operations
Browse files Browse the repository at this point in the history
Tested using
```
(module
  (import "wasi_snapshot_preview1" "proc_exit" (func $proc_exit (param i32)))

  (memory (export "memory") 1)

  (func $assert_true (param v128)
    local.get 0
    v128.any_true
    i32.eqz
    if
      unreachable
    end
  )

  (func $main (export "_start")
    ;; Test v128.not
    v128.const i8x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    v128.not
    v128.const i8x16 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
    i8x16.eq
    call $assert_true

    ;; Test v128.and
    v128.const i8x16 255 255 255 255 0 0 0 0 255 255 255 255 0 0 0 0
    v128.const i8x16 255 255 0 0 255 255 0 0 255 255 0 0 255 255 0 0
    v128.and
    v128.const i8x16 255 255 0 0 0 0 0 0 255 255 0 0 0 0 0 0
    i8x16.eq
    call $assert_true

    ;; Test v128.andnot
    v128.const i8x16 255 255 255 255 0 0 0 0 255 255 255 255 0 0 0 0
    v128.const i8x16 255 255 0 0 255 255 0 0 255 255 0 0 255 255 0 0
    v128.andnot
    v128.const i8x16 0 0 255 255 0 0 0 0 0 0 255 255 0 0 0 0
    i8x16.eq
    call $assert_true

    ;; Test v128.or
    v128.const i8x16 255 255 0 0 0 0 255 255 255 255 0 0 0 0 255 0
    v128.const i8x16 0 0 255 255 255 255 0 0 0 0 255 255 255 255 0 0
    v128.or
    v128.const i8x16 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0
    i8x16.eq
    call $assert_true

    ;; Test v128.xor
    v128.const i8x16 255 255 0 0 255 255 0 0 255 255 0 0 255 255 0 0
    v128.const i8x16 255 255 255 255 0 0 0 0 255 255 255 255 0 0 0 0
    v128.xor
    v128.const i8x16 0 0 255 255 255 255 0 0 0 0 255 255 255 255 0 0
    i8x16.eq
    call $assert_true

    i32.const 0
    call $proc_exit
  )
)
```
  • Loading branch information
James Marsh committed Oct 15, 2024
1 parent 189a92c commit 77c66d4
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
3 changes: 2 additions & 1 deletion core/iwasm/common/wasm_loader_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ is_valid_value_type(uint8 type)
bool
is_valid_value_type_for_interpreter(uint8 value_type)
{
#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)
/*
* Note: regardless of WASM_ENABLE_SIMD, our interpreters don't have
* SIMD implemented. It's safer to reject v128, especially for the
Expand Down
78 changes: 77 additions & 1 deletion core/iwasm/interpreter/wasm_interp_fast.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,8 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)

#define POP_F64() (GET_F64_FROM_ADDR(frame_lp + GET_OFFSET()))

#define POP_V128() (GET_V128_FROM_ADDR(frame_lp + GET_OFFSET()))

#define POP_REF() \
(opnd_off = GET_OFFSET(), CLEAR_FRAME_REF((unsigned)(opnd_off)), \
GET_REF_FROM_ADDR(frame_lp + opnd_off))
Expand Down Expand Up @@ -5720,6 +5722,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,

/* i8x16 comparison operations */
case SIMD_i8x16_eq:
{
V128 v1 = POP_V128();
V128 v2 = POP_V128();
int i;
addr_ret = GET_OFFSET();

V128 result;
for (i = 0; i < 16; i++) {
result.i8x16[i] =
v1.i8x16[i] == v2.i8x16[i] ? 0xff : 0;
}
PUT_V128_TO_ADDR(frame_lp + addr_ret, result);
break;
}
case SIMD_i8x16_ne:
case SIMD_i8x16_lt_s:
case SIMD_i8x16_lt_u:
Expand Down Expand Up @@ -5790,12 +5806,56 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
break;
}

/* v128 comparison operations */
/* v128 bitwise operations */
#define SIMD_V128_BITWISE_OP_COMMON(result_expr_0, result_expr_1) \
do { \
V128 result; \
result.i64x2[0] = (result_expr_0); \
result.i64x2[1] = (result_expr_1); \
addr_ret = GET_OFFSET(); \
PUT_V128_TO_ADDR(frame_lp + addr_ret, result); \
} while (0)

case SIMD_v128_not:
{
V128 value = POP_V128();
SIMD_V128_BITWISE_OP_COMMON(~value.i64x2[0],
~value.i64x2[1]);
break;
}
case SIMD_v128_and:
{
V128 v2 = POP_V128();
V128 v1 = POP_V128();
SIMD_V128_BITWISE_OP_COMMON(v1.i64x2[0] & v2.i64x2[0],
v1.i64x2[1] & v2.i64x2[1]);
break;
}
case SIMD_v128_andnot:
{
V128 v2 = POP_V128();
V128 v1 = POP_V128();
SIMD_V128_BITWISE_OP_COMMON(
v1.i64x2[0] & (~v2.i64x2[0]),
v1.i64x2[1] & (~v2.i64x2[1]));
break;
}
case SIMD_v128_or:
{
V128 v2 = POP_V128();
V128 v1 = POP_V128();
SIMD_V128_BITWISE_OP_COMMON(v1.i64x2[0] | v2.i64x2[0],
v1.i64x2[1] | v2.i64x2[1]);
break;
}
case SIMD_v128_xor:
{
V128 v2 = POP_V128();
V128 v1 = POP_V128();
SIMD_V128_BITWISE_OP_COMMON(v1.i64x2[0] ^ v2.i64x2[0],
v1.i64x2[1] ^ v2.i64x2[1]);
break;
}
case SIMD_v128_bitselect:
{
wasm_set_exception(module, "unsupported SIMD opcode");
Expand Down Expand Up @@ -5840,6 +5900,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
case SIMD_i8x16_neg:
case SIMD_i8x16_popcnt:
case SIMD_i8x16_all_true:
{
V128 v = POP_V128();
uint8_t *bytes = (uint8_t *)&v;
bool all_true = true;

for (int i = 0; i < 16; i++) {
if (bytes[i] == 0) {
all_true = false;
break;
}
}

PUSH_I32(all_true ? 1 : 0);
break;
}

case SIMD_i8x16_bitmask:
case SIMD_i8x16_narrow_i16x8_s:
case SIMD_i8x16_narrow_i16x8_u:
Expand Down

0 comments on commit 77c66d4

Please sign in to comment.