Skip to content
This repository has been archived by the owner on Dec 22, 2021. It is now read-only.

Commit

Permalink
[interpreter] Add i64x2.eq and i64x2.ne
Browse files Browse the repository at this point in the history
These instructions were added in #381 and #411 respectively.

The binary opcodes for these are still not finalized, I'm using what V8
is using for now.
  • Loading branch information
ngzhian committed Feb 3, 2021
1 parent 40b255f commit b638fe3
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 4 deletions.
2 changes: 2 additions & 0 deletions interpreter/binary/decode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,13 @@ let simd_prefix s =
| 0xb8l -> i32x4_max_s
| 0xb9l -> i32x4_max_u
| 0xbal -> i32x4_dot_i16x8_s
| 0xc0l -> i64x2_eq
| 0xc1l -> i64x2_neg
| 0xcbl -> i64x2_shl
| 0xccl -> i64x2_shr_s
| 0xcdl -> i64x2_shr_u
| 0xcel -> i64x2_add
| 0xd0l -> i64x2_ne
| 0xd1l -> i64x2_sub
| 0xd5l -> i64x2_mul
| 0xd8l -> f32x4_ceil
Expand Down
2 changes: 2 additions & 0 deletions interpreter/binary/encode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ let encode m =
| Binary (V128 V128Op.(I64x2 Add)) -> simd_op 0xcel
| Binary (V128 V128Op.(I64x2 Sub)) -> simd_op 0xd1l
| Binary (V128 V128Op.(I64x2 Mul)) -> simd_op 0xd5l
| Binary (V128 V128Op.(I64x2 Eq)) -> simd_op 0xc0l
| Binary (V128 V128Op.(I64x2 Ne)) -> simd_op 0xd0l
| Binary (V128 V128Op.(F32x4 Eq)) -> simd_op 0x41l
| Binary (V128 V128Op.(F32x4 Ne)) -> simd_op 0x42l
| Binary (V128 V128Op.(F32x4 Lt)) -> simd_op 0x43l
Expand Down
2 changes: 2 additions & 0 deletions interpreter/exec/eval_simd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ module SimdOp (SXX : Simd.S) (Value : ValueType with type t = SXX.t) = struct
| I32x4 GeS -> SXX.I32x4.ge_s
| I32x4 GeU -> SXX.I32x4.ge_u
| I32x4 DotI16x8S -> SXX.I32x4_convert.dot_i16x8_s
| I64x2 Eq -> SXX.I64x2.eq
| I64x2 Ne -> SXX.I64x2.ne
| I64x2 Add -> SXX.I64x2.add
| I64x2 Sub -> SXX.I64x2.sub
| I64x2 Mul -> SXX.I64x2.mul
Expand Down
2 changes: 2 additions & 0 deletions interpreter/syntax/operators.ml
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ let i32x4_dot_i16x8_s = Binary (V128 V128Op.(I32x4 DotI16x8S))
let i64x2_splat = Convert (V128 V128Op.(I64x2 Splat))
let i64x2_extract_lane imm = SimdExtract (V128Op.I64x2 (ZX, imm))
let i64x2_replace_lane imm = SimdReplace (V128Op.I64x2 imm)
let i64x2_eq = Binary (V128 V128Op.(I64x2 Eq))
let i64x2_ne = Binary (V128 V128Op.(I64x2 Ne))
let i64x2_neg = Unary (V128 V128Op.(I64x2 Neg))
let i64x2_add = Binary (V128 V128Op.(I64x2 Add))
let i64x2_sub = Binary (V128 V128Op.(I64x2 Sub))
Expand Down
2 changes: 2 additions & 0 deletions interpreter/text/arrange.ml
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ struct
| I32x4 LeU -> "i32x4.le_u"
| I32x4 GeS -> "i32x4.ge_s"
| I32x4 GeU -> "i32x4.ge_u"
| I64x2 Eq -> "i64x2.eq"
| I64x2 Ne -> "i64x2.ne"
| I8x16 NarrowS -> "i8x16.narrow_i16x8_s"
| I8x16 NarrowU -> "i8x16.narrow_i16x8_u"
| I8x16 Add -> "i8x16.add"
Expand Down
6 changes: 2 additions & 4 deletions interpreter/text/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -458,11 +458,9 @@ rule token = parse
| "output" { OUTPUT }

| (simd_shape as s)".eq"
{ except ["i64x2"] s lexbuf;
BINARY (simdop s i8x16_eq i16x8_eq i32x4_eq unreachable f32x4_eq f64x2_eq) }
{ BINARY (simdop s i8x16_eq i16x8_eq i32x4_eq i64x2_eq f32x4_eq f64x2_eq) }
| (simd_shape as s)".ne"
{ except ["i64x2"] s lexbuf;
BINARY (simdop s i8x16_ne i16x8_ne i32x4_ne unreachable f32x4_ne f64x2_ne) }
{ BINARY (simdop s i8x16_ne i16x8_ne i32x4_ne i64x2_ne f32x4_ne f64x2_ne) }
| (simd_int_shape as s)".lt_s"
{ except ["i64x2"] s lexbuf;
BINARY (simd_int_op s i8x16_lt_s i16x8_lt_s i32x4_lt_s unreachable) }
Expand Down
1 change: 1 addition & 0 deletions test/core/simd/meta/gen_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
'simd_i8x16_cmp',
'simd_i16x8_cmp',
'simd_i32x4_cmp',
'simd_i64x2_cmp',
'simd_f32x4_cmp',
'simd_f64x2_cmp',
'simd_i8x16_arith',
Expand Down
70 changes: 70 additions & 0 deletions test/core/simd/meta/simd_i64x2_cmp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3

from simd_compare import SimdCmpCase


# Generate i64x2 test case
class Simdi64x2CmpCase(SimdCmpCase):
LANE_TYPE = 'i64x2'

BINARY_OPS = ['eq', 'ne']

# Override this since i64x2 does not support as many comparison instructions.
CASE_TXT = """
;; Test all the {lane_type} comparison operators on major boundary values and all special values.
(module
(func (export "eq") (param $x v128) (param $y v128) (result v128) ({lane_type}.eq (local.get $x) (local.get $y)))
(func (export "ne") (param $x v128) (param $y v128) (result v128) ({lane_type}.ne (local.get $x) (local.get $y)))
)
{normal_case}
;; Type check
(assert_invalid (module (func (result v128) ({lane_type}.eq (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result v128) ({lane_type}.ne (i32.const 0) (f32.const 0)))) "type mismatch")
"""

def get_case_data(self):
forms = ['i64x2'] * 3
case_data = []

case_data.append(['#', 'eq'])
case_data.append(['#', 'i64x2.eq (i64x2) (i64x2)'])
case_data.append(['eq', ['0xFFFFFFFFFFFFFFFF', '0xFFFFFFFFFFFFFFFF'], '-1', forms])
case_data.append(['eq', ['0x0000000000000000', '0x0000000000000000'], '-1', forms])
case_data.append(['eq', ['0xF0F0F0F0F0F0F0F0', '0xF0F0F0F0F0F0F0F0'], '-1', forms])
case_data.append(['eq', ['0x0F0F0F0F0F0F0F0F', '0x0F0F0F0F0F0F0F0F'], '-1', forms])
case_data.append(['eq', [['0xFFFFFFFFFFFFFFFF', '0x0000000000000000'], ['0xFFFFFFFFFFFFFFFF', '0x0000000000000000']], '-1', forms])
case_data.append(['eq', [['0x0000000000000000', '0xFFFFFFFFFFFFFFFF'], ['0x0000000000000000', '0xFFFFFFFFFFFFFFFF']], '-1', forms])
case_data.append(['eq', [['0x03020100', '0x11100904', '0x1A0B0A12', '0xFFABAA1B'],
['0x03020100', '0x11100904', '0x1A0B0A12', '0xFFABAA1B']], '-1', forms])
case_data.append(['eq', ['0xFFFFFFFFFFFFFFFF', '0x0FFFFFFFFFFFFFFF'], '0', forms])
case_data.append(['eq', ['0x1', '0x2'], '0', forms])

case_data.append(['#', 'ne'])
case_data.append(['#', 'i64x2.ne (i64x2) (i64x2)'])

# hex vs hex
case_data.append(['#', 'hex vs hex'])
case_data.append(['ne', ['0xFFFFFFFFFFFFFFFF', '0xFFFFFFFFFFFFFFFF'], '0', forms])
case_data.append(['ne', ['0x0000000000000000', '0x0000000000000000'], '0', forms])
case_data.append(['ne', ['0xF0F0F0F0F0F0F0F0', '0xF0F0F0F0F0F0F0F0'], '0', forms])
case_data.append(['ne', ['0x0F0F0F0F0F0F0F0F', '0x0F0F0F0F0F0F0F0F'], '0', forms])
case_data.append(['ne', [['0xFFFFFFFFFFFFFFFF', '0x0000000000000000'], ['0xFFFFFFFFFFFFFFFF', '0x0000000000000000']], '0', forms])
case_data.append(['ne', [['0x0000000000000000', '0xFFFFFFFFFFFFFFFF'], ['0x0000000000000000', '0xFFFFFFFFFFFFFFFF']], '0', forms])
case_data.append(['ne', [['0x03020100', '0x11100904', '0x1A0B0A12', '0xFFABAA1B'],
['0x03020100', '0x11100904', '0x1A0B0A12', '0xFFABAA1B']], '0', forms])

return case_data


def gen_test_cases():
i64x2 = Simdi64x2CmpCase()
i64x2.gen_test_cases()


if __name__ == '__main__':
i64x2 = Simdi64x2CmpCase()
i64x2.gen_test_cases()
106 changes: 106 additions & 0 deletions test/core/simd/simd_i64x2_cmp.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

;; Test all the i64x2 comparison operators on major boundary values and all special values.

(module
(func (export "eq") (param $x v128) (param $y v128) (result v128) (i64x2.eq (local.get $x) (local.get $y)))
(func (export "ne") (param $x v128) (param $y v128) (result v128) (i64x2.ne (local.get $x) (local.get $y)))
)


;; eq

;; i64x2.eq (i64x2) (i64x2)
(assert_return (invoke "eq" (v128.const i64x2 0xFFFFFFFFFFFFFFFF 0xFFFFFFFFFFFFFFFF)
(v128.const i64x2 0xFFFFFFFFFFFFFFFF 0xFFFFFFFFFFFFFFFF))
(v128.const i64x2 -1 -1))
(assert_return (invoke "eq" (v128.const i64x2 0x0000000000000000 0x0000000000000000)
(v128.const i64x2 0x0000000000000000 0x0000000000000000))
(v128.const i64x2 -1 -1))
(assert_return (invoke "eq" (v128.const i64x2 0xF0F0F0F0F0F0F0F0 0xF0F0F0F0F0F0F0F0)
(v128.const i64x2 0xF0F0F0F0F0F0F0F0 0xF0F0F0F0F0F0F0F0))
(v128.const i64x2 -1 -1))
(assert_return (invoke "eq" (v128.const i64x2 0x0F0F0F0F0F0F0F0F 0x0F0F0F0F0F0F0F0F)
(v128.const i64x2 0x0F0F0F0F0F0F0F0F 0x0F0F0F0F0F0F0F0F))
(v128.const i64x2 -1 -1))
(assert_return (invoke "eq" (v128.const i64x2 0xFFFFFFFFFFFFFFFF 0x0000000000000000)
(v128.const i64x2 0xFFFFFFFFFFFFFFFF 0x0000000000000000))
(v128.const i64x2 -1 -1))
(assert_return (invoke "eq" (v128.const i64x2 0x0000000000000000 0xFFFFFFFFFFFFFFFF)
(v128.const i64x2 0x0000000000000000 0xFFFFFFFFFFFFFFFF))
(v128.const i64x2 -1 -1))
(assert_return (invoke "eq" (v128.const i64x2 0x03020100 0x11100904)
(v128.const i64x2 0x03020100 0x11100904))
(v128.const i64x2 -1 -1))
(assert_return (invoke "eq" (v128.const i64x2 0xFFFFFFFFFFFFFFFF 0xFFFFFFFFFFFFFFFF)
(v128.const i64x2 0x0FFFFFFFFFFFFFFF 0x0FFFFFFFFFFFFFFF))
(v128.const i64x2 0 0))
(assert_return (invoke "eq" (v128.const i64x2 0x1 0x1)
(v128.const i64x2 0x2 0x2))
(v128.const i64x2 0 0))

;; ne

;; i64x2.ne (i64x2) (i64x2)

;; hex vs hex
(assert_return (invoke "ne" (v128.const i64x2 0xFFFFFFFF 0xFFFFFFFF)
(v128.const i64x2 0xFFFFFFFF 0xFFFFFFFF))
(v128.const i64x2 0 0))
(assert_return (invoke "ne" (v128.const i64x2 0x00000000 0x00000000)
(v128.const i64x2 0x00000000 0x00000000))
(v128.const i64x2 0 0))
(assert_return (invoke "ne" (v128.const i64x2 0xF0F0F0F0 0xF0F0F0F0)
(v128.const i64x2 0xF0F0F0F0 0xF0F0F0F0))
(v128.const i64x2 0 0))
(assert_return (invoke "ne" (v128.const i64x2 0x0F0F0F0F 0x0F0F0F0F)
(v128.const i64x2 0x0F0F0F0F 0x0F0F0F0F))
(v128.const i64x2 0 0))
(assert_return (invoke "ne" (v128.const i64x2 0xFFFFFFFF 0x00000000)
(v128.const i64x2 0xFFFFFFFF 0x00000000))
(v128.const i64x2 0 0))
(assert_return (invoke "ne" (v128.const i64x2 0x00000000 0xFFFFFFFF)
(v128.const i64x2 0x00000000 0xFFFFFFFF))
(v128.const i64x2 0 0))
(assert_return (invoke "ne" (v128.const i64x2 0x03020100 0x11100904)
(v128.const i64x2 0x03020100 0x11100904))
(v128.const i64x2 0 0))

;; Type check

(assert_invalid (module (func (result v128) (i64x2.eq (i32.const 0) (f32.const 0)))) "type mismatch")
(assert_invalid (module (func (result v128) (i64x2.ne (i32.const 0) (f32.const 0)))) "type mismatch")

;; Test operation with empty argument

(assert_invalid
(module
(func $i64x2.eq-1st-arg-empty (result v128)
(i64x2.eq (v128.const i64x2 0 0))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $i64x2.eq-arg-empty (result v128)
(i64x2.eq)
)
)
"type mismatch"
)
(assert_invalid
(module
(func $i64x2.ne-1st-arg-empty (result v128)
(i64x2.ne (v128.const i64x2 0 0))
)
)
"type mismatch"
)
(assert_invalid
(module
(func $i64x2.ne-arg-empty (result v128)
(i64x2.ne)
)
)
"type mismatch"
)

0 comments on commit b638fe3

Please sign in to comment.