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

Commit b638fe3

Browse files
committed
[interpreter] Add i64x2.eq and i64x2.ne
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.
1 parent 40b255f commit b638fe3

File tree

9 files changed

+189
-4
lines changed

9 files changed

+189
-4
lines changed

interpreter/binary/decode.ml

+2
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,13 @@ let simd_prefix s =
385385
| 0xb8l -> i32x4_max_s
386386
| 0xb9l -> i32x4_max_u
387387
| 0xbal -> i32x4_dot_i16x8_s
388+
| 0xc0l -> i64x2_eq
388389
| 0xc1l -> i64x2_neg
389390
| 0xcbl -> i64x2_shl
390391
| 0xccl -> i64x2_shr_s
391392
| 0xcdl -> i64x2_shr_u
392393
| 0xcel -> i64x2_add
394+
| 0xd0l -> i64x2_ne
393395
| 0xd1l -> i64x2_sub
394396
| 0xd5l -> i64x2_mul
395397
| 0xd8l -> f32x4_ceil

interpreter/binary/encode.ml

+2
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,8 @@ let encode m =
488488
| Binary (V128 V128Op.(I64x2 Add)) -> simd_op 0xcel
489489
| Binary (V128 V128Op.(I64x2 Sub)) -> simd_op 0xd1l
490490
| Binary (V128 V128Op.(I64x2 Mul)) -> simd_op 0xd5l
491+
| Binary (V128 V128Op.(I64x2 Eq)) -> simd_op 0xc0l
492+
| Binary (V128 V128Op.(I64x2 Ne)) -> simd_op 0xd0l
491493
| Binary (V128 V128Op.(F32x4 Eq)) -> simd_op 0x41l
492494
| Binary (V128 V128Op.(F32x4 Ne)) -> simd_op 0x42l
493495
| Binary (V128 V128Op.(F32x4 Lt)) -> simd_op 0x43l

interpreter/exec/eval_simd.ml

+2
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ module SimdOp (SXX : Simd.S) (Value : ValueType with type t = SXX.t) = struct
119119
| I32x4 GeS -> SXX.I32x4.ge_s
120120
| I32x4 GeU -> SXX.I32x4.ge_u
121121
| I32x4 DotI16x8S -> SXX.I32x4_convert.dot_i16x8_s
122+
| I64x2 Eq -> SXX.I64x2.eq
123+
| I64x2 Ne -> SXX.I64x2.ne
122124
| I64x2 Add -> SXX.I64x2.add
123125
| I64x2 Sub -> SXX.I64x2.sub
124126
| I64x2 Mul -> SXX.I64x2.mul

interpreter/syntax/operators.ml

+2
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,8 @@ let i32x4_dot_i16x8_s = Binary (V128 V128Op.(I32x4 DotI16x8S))
379379
let i64x2_splat = Convert (V128 V128Op.(I64x2 Splat))
380380
let i64x2_extract_lane imm = SimdExtract (V128Op.I64x2 (ZX, imm))
381381
let i64x2_replace_lane imm = SimdReplace (V128Op.I64x2 imm)
382+
let i64x2_eq = Binary (V128 V128Op.(I64x2 Eq))
383+
let i64x2_ne = Binary (V128 V128Op.(I64x2 Ne))
382384
let i64x2_neg = Unary (V128 V128Op.(I64x2 Neg))
383385
let i64x2_add = Binary (V128 V128Op.(I64x2 Add))
384386
let i64x2_sub = Binary (V128 V128Op.(I64x2 Sub))

interpreter/text/arrange.ml

+2
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ struct
269269
| I32x4 LeU -> "i32x4.le_u"
270270
| I32x4 GeS -> "i32x4.ge_s"
271271
| I32x4 GeU -> "i32x4.ge_u"
272+
| I64x2 Eq -> "i64x2.eq"
273+
| I64x2 Ne -> "i64x2.ne"
272274
| I8x16 NarrowS -> "i8x16.narrow_i16x8_s"
273275
| I8x16 NarrowU -> "i8x16.narrow_i16x8_u"
274276
| I8x16 Add -> "i8x16.add"

interpreter/text/lexer.mll

+2-4
Original file line numberDiff line numberDiff line change
@@ -458,11 +458,9 @@ rule token = parse
458458
| "output" { OUTPUT }
459459

460460
| (simd_shape as s)".eq"
461-
{ except ["i64x2"] s lexbuf;
462-
BINARY (simdop s i8x16_eq i16x8_eq i32x4_eq unreachable f32x4_eq f64x2_eq) }
461+
{ BINARY (simdop s i8x16_eq i16x8_eq i32x4_eq i64x2_eq f32x4_eq f64x2_eq) }
463462
| (simd_shape as s)".ne"
464-
{ except ["i64x2"] s lexbuf;
465-
BINARY (simdop s i8x16_ne i16x8_ne i32x4_ne unreachable f32x4_ne f64x2_ne) }
463+
{ BINARY (simdop s i8x16_ne i16x8_ne i32x4_ne i64x2_ne f32x4_ne f64x2_ne) }
466464
| (simd_int_shape as s)".lt_s"
467465
{ except ["i64x2"] s lexbuf;
468466
BINARY (simd_int_op s i8x16_lt_s i16x8_lt_s i32x4_lt_s unreachable) }

test/core/simd/meta/gen_tests.py

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
'simd_i8x16_cmp',
1414
'simd_i16x8_cmp',
1515
'simd_i32x4_cmp',
16+
'simd_i64x2_cmp',
1617
'simd_f32x4_cmp',
1718
'simd_f64x2_cmp',
1819
'simd_i8x16_arith',

test/core/simd/meta/simd_i64x2_cmp.py

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python3
2+
3+
from simd_compare import SimdCmpCase
4+
5+
6+
# Generate i64x2 test case
7+
class Simdi64x2CmpCase(SimdCmpCase):
8+
LANE_TYPE = 'i64x2'
9+
10+
BINARY_OPS = ['eq', 'ne']
11+
12+
# Override this since i64x2 does not support as many comparison instructions.
13+
CASE_TXT = """
14+
;; Test all the {lane_type} comparison operators on major boundary values and all special values.
15+
16+
(module
17+
(func (export "eq") (param $x v128) (param $y v128) (result v128) ({lane_type}.eq (local.get $x) (local.get $y)))
18+
(func (export "ne") (param $x v128) (param $y v128) (result v128) ({lane_type}.ne (local.get $x) (local.get $y)))
19+
)
20+
21+
{normal_case}
22+
23+
;; Type check
24+
25+
(assert_invalid (module (func (result v128) ({lane_type}.eq (i32.const 0) (f32.const 0)))) "type mismatch")
26+
(assert_invalid (module (func (result v128) ({lane_type}.ne (i32.const 0) (f32.const 0)))) "type mismatch")
27+
"""
28+
29+
def get_case_data(self):
30+
forms = ['i64x2'] * 3
31+
case_data = []
32+
33+
case_data.append(['#', 'eq'])
34+
case_data.append(['#', 'i64x2.eq (i64x2) (i64x2)'])
35+
case_data.append(['eq', ['0xFFFFFFFFFFFFFFFF', '0xFFFFFFFFFFFFFFFF'], '-1', forms])
36+
case_data.append(['eq', ['0x0000000000000000', '0x0000000000000000'], '-1', forms])
37+
case_data.append(['eq', ['0xF0F0F0F0F0F0F0F0', '0xF0F0F0F0F0F0F0F0'], '-1', forms])
38+
case_data.append(['eq', ['0x0F0F0F0F0F0F0F0F', '0x0F0F0F0F0F0F0F0F'], '-1', forms])
39+
case_data.append(['eq', [['0xFFFFFFFFFFFFFFFF', '0x0000000000000000'], ['0xFFFFFFFFFFFFFFFF', '0x0000000000000000']], '-1', forms])
40+
case_data.append(['eq', [['0x0000000000000000', '0xFFFFFFFFFFFFFFFF'], ['0x0000000000000000', '0xFFFFFFFFFFFFFFFF']], '-1', forms])
41+
case_data.append(['eq', [['0x03020100', '0x11100904', '0x1A0B0A12', '0xFFABAA1B'],
42+
['0x03020100', '0x11100904', '0x1A0B0A12', '0xFFABAA1B']], '-1', forms])
43+
case_data.append(['eq', ['0xFFFFFFFFFFFFFFFF', '0x0FFFFFFFFFFFFFFF'], '0', forms])
44+
case_data.append(['eq', ['0x1', '0x2'], '0', forms])
45+
46+
case_data.append(['#', 'ne'])
47+
case_data.append(['#', 'i64x2.ne (i64x2) (i64x2)'])
48+
49+
# hex vs hex
50+
case_data.append(['#', 'hex vs hex'])
51+
case_data.append(['ne', ['0xFFFFFFFFFFFFFFFF', '0xFFFFFFFFFFFFFFFF'], '0', forms])
52+
case_data.append(['ne', ['0x0000000000000000', '0x0000000000000000'], '0', forms])
53+
case_data.append(['ne', ['0xF0F0F0F0F0F0F0F0', '0xF0F0F0F0F0F0F0F0'], '0', forms])
54+
case_data.append(['ne', ['0x0F0F0F0F0F0F0F0F', '0x0F0F0F0F0F0F0F0F'], '0', forms])
55+
case_data.append(['ne', [['0xFFFFFFFFFFFFFFFF', '0x0000000000000000'], ['0xFFFFFFFFFFFFFFFF', '0x0000000000000000']], '0', forms])
56+
case_data.append(['ne', [['0x0000000000000000', '0xFFFFFFFFFFFFFFFF'], ['0x0000000000000000', '0xFFFFFFFFFFFFFFFF']], '0', forms])
57+
case_data.append(['ne', [['0x03020100', '0x11100904', '0x1A0B0A12', '0xFFABAA1B'],
58+
['0x03020100', '0x11100904', '0x1A0B0A12', '0xFFABAA1B']], '0', forms])
59+
60+
return case_data
61+
62+
63+
def gen_test_cases():
64+
i64x2 = Simdi64x2CmpCase()
65+
i64x2.gen_test_cases()
66+
67+
68+
if __name__ == '__main__':
69+
i64x2 = Simdi64x2CmpCase()
70+
i64x2.gen_test_cases()

test/core/simd/simd_i64x2_cmp.wast

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
2+
;; Test all the i64x2 comparison operators on major boundary values and all special values.
3+
4+
(module
5+
(func (export "eq") (param $x v128) (param $y v128) (result v128) (i64x2.eq (local.get $x) (local.get $y)))
6+
(func (export "ne") (param $x v128) (param $y v128) (result v128) (i64x2.ne (local.get $x) (local.get $y)))
7+
)
8+
9+
10+
;; eq
11+
12+
;; i64x2.eq (i64x2) (i64x2)
13+
(assert_return (invoke "eq" (v128.const i64x2 0xFFFFFFFFFFFFFFFF 0xFFFFFFFFFFFFFFFF)
14+
(v128.const i64x2 0xFFFFFFFFFFFFFFFF 0xFFFFFFFFFFFFFFFF))
15+
(v128.const i64x2 -1 -1))
16+
(assert_return (invoke "eq" (v128.const i64x2 0x0000000000000000 0x0000000000000000)
17+
(v128.const i64x2 0x0000000000000000 0x0000000000000000))
18+
(v128.const i64x2 -1 -1))
19+
(assert_return (invoke "eq" (v128.const i64x2 0xF0F0F0F0F0F0F0F0 0xF0F0F0F0F0F0F0F0)
20+
(v128.const i64x2 0xF0F0F0F0F0F0F0F0 0xF0F0F0F0F0F0F0F0))
21+
(v128.const i64x2 -1 -1))
22+
(assert_return (invoke "eq" (v128.const i64x2 0x0F0F0F0F0F0F0F0F 0x0F0F0F0F0F0F0F0F)
23+
(v128.const i64x2 0x0F0F0F0F0F0F0F0F 0x0F0F0F0F0F0F0F0F))
24+
(v128.const i64x2 -1 -1))
25+
(assert_return (invoke "eq" (v128.const i64x2 0xFFFFFFFFFFFFFFFF 0x0000000000000000)
26+
(v128.const i64x2 0xFFFFFFFFFFFFFFFF 0x0000000000000000))
27+
(v128.const i64x2 -1 -1))
28+
(assert_return (invoke "eq" (v128.const i64x2 0x0000000000000000 0xFFFFFFFFFFFFFFFF)
29+
(v128.const i64x2 0x0000000000000000 0xFFFFFFFFFFFFFFFF))
30+
(v128.const i64x2 -1 -1))
31+
(assert_return (invoke "eq" (v128.const i64x2 0x03020100 0x11100904)
32+
(v128.const i64x2 0x03020100 0x11100904))
33+
(v128.const i64x2 -1 -1))
34+
(assert_return (invoke "eq" (v128.const i64x2 0xFFFFFFFFFFFFFFFF 0xFFFFFFFFFFFFFFFF)
35+
(v128.const i64x2 0x0FFFFFFFFFFFFFFF 0x0FFFFFFFFFFFFFFF))
36+
(v128.const i64x2 0 0))
37+
(assert_return (invoke "eq" (v128.const i64x2 0x1 0x1)
38+
(v128.const i64x2 0x2 0x2))
39+
(v128.const i64x2 0 0))
40+
41+
;; ne
42+
43+
;; i64x2.ne (i64x2) (i64x2)
44+
45+
;; hex vs hex
46+
(assert_return (invoke "ne" (v128.const i64x2 0xFFFFFFFF 0xFFFFFFFF)
47+
(v128.const i64x2 0xFFFFFFFF 0xFFFFFFFF))
48+
(v128.const i64x2 0 0))
49+
(assert_return (invoke "ne" (v128.const i64x2 0x00000000 0x00000000)
50+
(v128.const i64x2 0x00000000 0x00000000))
51+
(v128.const i64x2 0 0))
52+
(assert_return (invoke "ne" (v128.const i64x2 0xF0F0F0F0 0xF0F0F0F0)
53+
(v128.const i64x2 0xF0F0F0F0 0xF0F0F0F0))
54+
(v128.const i64x2 0 0))
55+
(assert_return (invoke "ne" (v128.const i64x2 0x0F0F0F0F 0x0F0F0F0F)
56+
(v128.const i64x2 0x0F0F0F0F 0x0F0F0F0F))
57+
(v128.const i64x2 0 0))
58+
(assert_return (invoke "ne" (v128.const i64x2 0xFFFFFFFF 0x00000000)
59+
(v128.const i64x2 0xFFFFFFFF 0x00000000))
60+
(v128.const i64x2 0 0))
61+
(assert_return (invoke "ne" (v128.const i64x2 0x00000000 0xFFFFFFFF)
62+
(v128.const i64x2 0x00000000 0xFFFFFFFF))
63+
(v128.const i64x2 0 0))
64+
(assert_return (invoke "ne" (v128.const i64x2 0x03020100 0x11100904)
65+
(v128.const i64x2 0x03020100 0x11100904))
66+
(v128.const i64x2 0 0))
67+
68+
;; Type check
69+
70+
(assert_invalid (module (func (result v128) (i64x2.eq (i32.const 0) (f32.const 0)))) "type mismatch")
71+
(assert_invalid (module (func (result v128) (i64x2.ne (i32.const 0) (f32.const 0)))) "type mismatch")
72+
73+
;; Test operation with empty argument
74+
75+
(assert_invalid
76+
(module
77+
(func $i64x2.eq-1st-arg-empty (result v128)
78+
(i64x2.eq (v128.const i64x2 0 0))
79+
)
80+
)
81+
"type mismatch"
82+
)
83+
(assert_invalid
84+
(module
85+
(func $i64x2.eq-arg-empty (result v128)
86+
(i64x2.eq)
87+
)
88+
)
89+
"type mismatch"
90+
)
91+
(assert_invalid
92+
(module
93+
(func $i64x2.ne-1st-arg-empty (result v128)
94+
(i64x2.ne (v128.const i64x2 0 0))
95+
)
96+
)
97+
"type mismatch"
98+
)
99+
(assert_invalid
100+
(module
101+
(func $i64x2.ne-arg-empty (result v128)
102+
(i64x2.ne)
103+
)
104+
)
105+
"type mismatch"
106+
)

0 commit comments

Comments
 (0)