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

Commit 2e2e494

Browse files
authored
Implement v128.load32_zero and v128.load64_zero (#388)
The tests are adapted from load_extend tests.
1 parent 1cfd484 commit 2e2e494

File tree

5 files changed

+169
-2
lines changed

5 files changed

+169
-2
lines changed

interpreter/runtime/memory.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ let load_packed sz ext mem a o t =
133133

134134
let load_simd_packed pack_size simd_load mem a o t =
135135
let n = packed_size pack_size in
136-
assert (n <= Types.size t);
136+
assert (n < Types.size t);
137137
let x = loadn mem a o n in
138-
let b = Bytes.create 16 in
138+
let b = Bytes.make 16 '\x00' in
139139
Bytes.set_int64_le b 0 x;
140140
let v = V128.of_bits (Bytes.to_string b) in
141141
match pack_size, simd_load with
@@ -149,6 +149,8 @@ let load_simd_packed pack_size simd_load mem a o t =
149149
| Pack16, PackSplat -> V128 (V128.I16x8.splat (I16.of_int_s (Int64.to_int x)))
150150
| Pack32, PackSplat -> V128 (V128.I32x4.splat (I32.of_int_s (Int64.to_int x)))
151151
| Pack64, PackSplat -> V128 (V128.I64x2.splat x)
152+
| Pack32, PackZero -> V128 v
153+
| Pack64, PackZero -> V128 v
152154
| _ -> assert false
153155

154156
let store_packed sz mem a o v =

interpreter/syntax/operators.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ let v128_load32_splat align offset =
238238
SimdLoad {ty= V128Type; align; offset; sz = Some (Pack32, PackSplat)}
239239
let v128_load64_splat align offset =
240240
SimdLoad {ty= V128Type; align; offset; sz = Some (Pack64, PackSplat)}
241+
242+
let v128_load32_zero align offset =
243+
SimdLoad {ty= V128Type; align; offset; sz = Some (Pack32, PackZero)}
244+
let v128_load64_zero align offset =
245+
SimdLoad {ty= V128Type; align; offset; sz = Some (Pack64, PackZero)}
246+
241247
let v128_store align offset = SimdStore {ty = V128Type; align; offset; sz = None}
242248

243249
let v128_not = Unary (V128 V128Op.(V128 Not))

interpreter/syntax/types.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type pack_simd =
2323
| Pack8x8 of extension
2424
| Pack16x4 of extension
2525
| Pack32x2 of extension
26+
| PackZero
2627

2728
(* Attributes *)
2829

interpreter/text/lexer.mll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,10 @@ rule token = parse
302302
{ LOAD (fun a o -> (v128_load32_splat (opt a 2)) o) }
303303
| "v128.load64_splat"
304304
{ LOAD (fun a o -> (v128_load64_splat (opt a 3)) o) }
305+
| "v128.load32_zero"
306+
{ LOAD (fun a o -> (v128_load32_zero (opt a 2)) o) }
307+
| "v128.load64_zero"
308+
{ LOAD (fun a o -> (v128_load64_zero (opt a 3)) o) }
305309
| (ixx as t)".store"(mem_size as sz)
306310
{ if t = "i32" && sz = "32" then error lexbuf "unknown operator";
307311
STORE (fun a o ->

test/core/simd/simd_load_zero.wast

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
;; Load and Zero extend test cases
2+
3+
(module
4+
(memory 1)
5+
(data (i32.const 0) "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\80\81\82\83\84\85\86\87\88\89")
6+
(data (i32.const 65520) "\0A\0B\0C\0D\0E\0F\80\81\82\83\84\85\86\87\88\89")
7+
8+
(func (export "v128.load32_zero") (param $0 i32) (result v128)
9+
(v128.load32_zero (local.get $0))
10+
)
11+
(func (export "v128.load64_zero") (param $0 i32) (result v128)
12+
(v128.load64_zero (local.get $0))
13+
)
14+
15+
;; load by a constant amount
16+
(func (export "v128.load32_zero_const0") (result v128)
17+
(v128.load32_zero (i32.const 0))
18+
)
19+
(func (export "v128.load64_zero_const8") (result v128)
20+
(v128.load64_zero (i32.const 8))
21+
)
22+
23+
;; load data with different offset/align arguments
24+
;; i16x8
25+
(func (export "v128.load32_zero_offset0") (param $0 i32) (result v128)
26+
(v128.load32_zero offset=0 (local.get $0))
27+
)
28+
(func (export "v128.load32_zero_align1") (param $0 i32) (result v128)
29+
(v128.load32_zero align=1 (local.get $0))
30+
)
31+
(func (export "v128.load32_zero_offset0_align1") (param $0 i32) (result v128)
32+
(v128.load32_zero offset=0 align=1 (local.get $0))
33+
)
34+
(func (export "v128.load32_zero_offset1_align1") (param $0 i32) (result v128)
35+
(v128.load32_zero offset=1 align=1 (local.get $0))
36+
)
37+
(func (export "v128.load32_zero_offset10_align4") (param $0 i32) (result v128)
38+
(v128.load32_zero offset=10 align=4 (local.get $0))
39+
)
40+
(func (export "v128.load64_zero_offset0") (param $0 i32) (result v128)
41+
(v128.load64_zero offset=0 (local.get $0))
42+
)
43+
(func (export "v128.load64_zero_align1") (param $0 i32) (result v128)
44+
(v128.load64_zero align=1 (local.get $0))
45+
)
46+
(func (export "v128.load64_zero_offset0_align1") (param $0 i32) (result v128)
47+
(v128.load64_zero offset=0 align=1 (local.get $0))
48+
)
49+
(func (export "v128.load64_zero_offset1_align1") (param $0 i32) (result v128)
50+
(v128.load64_zero offset=1 align=1 (local.get $0))
51+
)
52+
(func (export "v128.load64_zero_offset10_align4") (param $0 i32) (result v128)
53+
(v128.load64_zero offset=10 align=4 (local.get $0))
54+
)
55+
(func (export "v128.load64_zero_offset20_align8") (param $0 i32) (result v128)
56+
(v128.load64_zero offset=20 align=8 (local.get $0))
57+
)
58+
)
59+
60+
61+
;; normal
62+
(assert_return (invoke "v128.load32_zero" (i32.const 0)) (v128.const i32x4 0x03020100 0x00000000 0x00000000 0x00000000))
63+
(assert_return (invoke "v128.load64_zero" (i32.const 0)) (v128.const i64x2 0x0706050403020100 0x0000000000000000))
64+
(assert_return (invoke "v128.load32_zero" (i32.const 10)) (v128.const i32x4 0x0D0C0B0A 0x00000000 0x00000000 0x00000000))
65+
(assert_return (invoke "v128.load64_zero" (i32.const 10)) (v128.const i64x2 0x81800F0E0D0C0B0A 0x0000000000000000))
66+
(assert_return (invoke "v128.load32_zero" (i32.const 20)) (v128.const i32x4 0x87868584 0x00000000 0x00000000 0x00000000))
67+
(assert_return (invoke "v128.load64_zero" (i32.const 20)) (v128.const i64x2 0x0000898887868584 0x0000000000000000))
68+
69+
;; load by a constant amount
70+
(assert_return (invoke "v128.load32_zero_const0") (v128.const i32x4 0x03020100 0x00000000 0x00000000 0x00000000))
71+
(assert_return (invoke "v128.load64_zero_const8") (v128.const i64x2 0x0F0E0D0C0B0A0908 0x0000000000000000))
72+
73+
;; load data with different offset/align arguments
74+
;; load32_zero
75+
(assert_return (invoke "v128.load32_zero_offset0" (i32.const 0)) (v128.const i32x4 0x03020100 0x00000000 0x00000000 0x00000000))
76+
(assert_return (invoke "v128.load32_zero_align1" (i32.const 1)) (v128.const i32x4 0x04030201 0x00000000 0x00000000 0x00000000))
77+
(assert_return (invoke "v128.load32_zero_offset0_align1" (i32.const 2)) (v128.const i32x4 0x05040302 0x00000000 0x00000000 0x00000000))
78+
(assert_return (invoke "v128.load32_zero_offset10_align4" (i32.const 3)) (v128.const i32x4 0x800F0E0D 0x00000000 0x00000000 0x00000000))
79+
80+
;; load64_zero
81+
(assert_return (invoke "v128.load64_zero_offset0" (i32.const 0)) (v128.const i64x2 0x0706050403020100 0x0000000000000000))
82+
(assert_return (invoke "v128.load64_zero_align1" (i32.const 1)) (v128.const i64x2 0x0807060504030201 0x0000000000000000))
83+
(assert_return (invoke "v128.load64_zero_offset0_align1" (i32.const 2)) (v128.const i64x2 0x0908070605040302 0x0000000000000000))
84+
(assert_return (invoke "v128.load64_zero_offset10_align4" (i32.const 3)) (v128.const i64x2 0x84838281800F0E0D 0x0000000000000000))
85+
(assert_return (invoke "v128.load64_zero_offset20_align8" (i32.const 4)) (v128.const i64x2 0x0000000000008988 0x0000000000000000))
86+
87+
;; out of bounds memory access
88+
(assert_trap (invoke "v128.load32_zero" (i32.const -1)) "out of bounds memory access")
89+
(assert_trap (invoke "v128.load64_zero" (i32.const -1)) "out of bounds memory access")
90+
91+
(assert_trap (invoke "v128.load32_zero_offset1_align1" (i32.const -1)) "out of bounds memory access")
92+
(assert_trap (invoke "v128.load64_zero_offset1_align1" (i32.const -1)) "out of bounds memory access")
93+
94+
;; type check
95+
(assert_invalid (module (memory 0) (func (result v128) (v128.load32_zero (f32.const 0)))) "type mismatch")
96+
(assert_invalid (module (memory 0) (func (result v128) (v128.load64_zero (f32.const 0)))) "type mismatch")
97+
98+
;; Test operation with empty argument
99+
100+
(assert_invalid
101+
(module (memory 0)
102+
(func $v128.load32_zero-arg-empty (result v128)
103+
(v128.load32_zero)
104+
)
105+
)
106+
"type mismatch"
107+
)
108+
(assert_invalid
109+
(module (memory 0)
110+
(func $v128.load64_zero-arg-empty (result v128)
111+
(v128.load64_zero)
112+
)
113+
)
114+
"type mismatch"
115+
)
116+
117+
;; Unknown operator
118+
119+
(assert_malformed (module quote "(memory 1) (func (drop (i16x8.load16x4_s (i32.const 0))))") "unknown operator")
120+
(assert_malformed (module quote "(memory 1) (func (drop (i16x8.load16x4_u (i32.const 0))))") "unknown operator")
121+
(assert_malformed (module quote "(memory 1) (func (drop (i32x4.load32x2_s (i32.const 0))))") "unknown operator")
122+
(assert_malformed (module quote "(memory 1) (func (drop (i32x4.load32x2_u (i32.const 0))))") "unknown operator")
123+
(assert_malformed (module quote "(memory 1) (func (drop (i64x2.load64x1_s (i32.const 0))))") "unknown operator")
124+
(assert_malformed (module quote "(memory 1) (func (drop (i64x2.load64x1_u (i32.const 0))))") "unknown operator")
125+
126+
;; combination
127+
(module
128+
(memory 1)
129+
(data (i32.const 0) "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\80\81\82\83\84\85\86\87\88\89")
130+
(func (export "v128.load32_zero-in-block") (result v128)
131+
(block (result v128) (block (result v128) (v128.load32_zero (i32.const 0))))
132+
)
133+
(func (export "v128.load64_zero-in-block") (result v128)
134+
(block (result v128) (block (result v128) (v128.load64_zero (i32.const 1))))
135+
)
136+
(func (export "v128.load32_zero-as-br-value") (result v128)
137+
(block (result v128) (br 0 (v128.load32_zero (i32.const 6))))
138+
)
139+
(func (export "v128.load64_zero-as-br-value") (result v128)
140+
(block (result v128) (br 0 (v128.load64_zero (i32.const 7))))
141+
)
142+
(func (export "v128.load32_zero-extract_lane_s-operand") (result i32)
143+
(i32x4.extract_lane 0 (v128.load32_zero (i32.const 12)))
144+
)
145+
(func (export "v128.load64_zero-extract_lane_s-operand") (result i64)
146+
(i64x2.extract_lane 0 (v128.load64_zero (i32.const 13)))
147+
)
148+
)
149+
(assert_return (invoke "v128.load32_zero-in-block") (v128.const i32x4 0x03020100 0x00000000 0x00000000 0x00000000))
150+
(assert_return (invoke "v128.load64_zero-in-block") (v128.const i64x2 0x0807060504030201 0x0000000000000000))
151+
(assert_return (invoke "v128.load32_zero-as-br-value") (v128.const i32x4 0x09080706 0x00000000 0x00000000 0x00000000))
152+
(assert_return (invoke "v128.load64_zero-as-br-value") (v128.const i64x2 0x0E0D0C0B0A090807 0x0000000000000000))
153+
(assert_return (invoke "v128.load32_zero-extract_lane_s-operand") (i32.const 0x0F0E0D0C))
154+
(assert_return (invoke "v128.load64_zero-extract_lane_s-operand") (i64.const 0x84838281800F0E0D))

0 commit comments

Comments
 (0)