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

Commit 301cdbd

Browse files
committed
Implement SIMD load splat and load extend
Add more pack types for SIMD load splat and load extends.
1 parent b7aea06 commit 301cdbd

File tree

8 files changed

+87
-14
lines changed

8 files changed

+87
-14
lines changed

interpreter/binary/encode.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,8 @@ let encode m =
561561
| SimdBitmask V128Op.(I32x4 Bitmask) -> simd_op 0xa4l
562562
| SimdBitmask (_) -> assert false
563563

564+
| _ -> assert false
565+
564566
let const c =
565567
list instr c.it; end_ ()
566568

interpreter/exec/simd.ml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ sig
175175
val widen_low_u : t -> t
176176
val widen_high_u : t -> t
177177
end
178+
module I64x2_convert : sig
179+
val widen_low_s : t -> t
180+
val widen_low_u : t -> t
181+
end
178182
module F32x4_convert : sig
179183
val convert_i32x4_s : t -> t
180184
val convert_i32x4_u : t -> t
@@ -405,6 +409,16 @@ struct
405409
let widen_high_u = widen Lib.List.drop 0xffffl
406410
end
407411

412+
module I64x2_convert = struct
413+
let widen mask x =
414+
Rep.of_i64x2
415+
(List.map
416+
(fun i32 -> Int64.(logand mask (of_int32 i32)))
417+
(Lib.List.take 2 (Rep.to_i32x4 x)))
418+
let widen_low_s = widen 0xffffffffffffffffL
419+
let widen_low_u = widen 0xffffffffL
420+
end
421+
408422
module F32x4_convert = struct
409423
let convert f v = Rep.of_f32x4 (List.map f (Rep.to_i32x4 v))
410424
let convert_i32x4_s = convert F32_convert.convert_i32_s

interpreter/runtime/memory.ml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,31 @@ let extend x n = function
122122
| ZX -> x
123123
| SX -> let sh = 64 - 8 * n in Int64.(shift_right (shift_left x sh) sh)
124124

125+
let load_simd_packed sz ext x =
126+
let b = Bytes.create 16 in
127+
Bytes.set_int64_le b 0 x;
128+
let v = V128.of_bits (Bytes.to_string b) in
129+
match sz, ext with
130+
| (Pack8x8, SX) -> V128 (V128.I16x8_convert.widen_low_s v)
131+
| (Pack8x8, ZX) -> V128 (V128.I16x8_convert.widen_low_u v)
132+
| (Pack16x4, SX) -> V128 (V128.I32x4_convert.widen_low_s v)
133+
| (Pack16x4, ZX) -> V128 (V128.I32x4_convert.widen_low_u v)
134+
| (Pack32x2, SX) -> V128 (V128.I64x2_convert.widen_low_s v)
135+
| (Pack32x2, ZX) -> V128 (V128.I64x2_convert.widen_low_u v)
136+
| (Pack8, ZX) -> V128 (V128.I8x16.splat (I8.of_int_s (Int64.to_int x)))
137+
| (Pack16, ZX) -> V128 (V128.I16x8.splat (I16.of_int_s (Int64.to_int x)))
138+
| (Pack32, ZX) -> V128 (V128.I32x4.splat (I32.of_int_s (Int64.to_int x)))
139+
| (Pack64, ZX) -> V128 (V128.I64x2.splat x)
140+
| _ -> assert false
141+
125142
let load_packed sz ext mem a o t =
126143
assert (packed_size sz <= Types.size t);
127144
let n = packed_size sz in
128145
let x = extend (loadn mem a o n) n ext in
129146
match t with
130147
| I32Type -> I32 (Int64.to_int32 x)
131148
| I64Type -> I64 x
149+
| V128Type -> load_simd_packed sz ext x
132150
| _ -> raise Type
133151

134152
let store_packed sz mem a o v =

interpreter/syntax/operators.ml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,28 @@ let memory_grow = MemoryGrow
218218

219219
(* SIMD *)
220220
let v128_load align offset = Load {ty = V128Type; align; offset; sz = None}
221+
let i16x8_load8x8_s align offset =
222+
Load {ty = V128Type; align; offset; sz = Some (Pack8x8, SX)}
223+
let i16x8_load8x8_u align offset =
224+
Load {ty = V128Type; align; offset; sz = Some (Pack8x8, ZX)}
225+
let i32x4_load16x4_s align offset =
226+
Load {ty = V128Type; align; offset; sz = Some (Pack16x4, SX)}
227+
let i32x4_load16x4_u align offset =
228+
Load {ty = V128Type; align; offset; sz = Some (Pack16x4, ZX)}
229+
let i64x2_load32x2_s align offset =
230+
Load {ty = V128Type; align; offset; sz = Some (Pack32x2, SX)}
231+
let i64x2_load32x2_u align offset =
232+
Load {ty = V128Type; align; offset; sz = Some (Pack32x2, ZX)}
233+
let v8x16_load_splat align offset =
234+
Load {ty= V128Type; align; offset; sz = Some (Pack8, ZX)}
235+
let v16x8_load_splat align offset =
236+
Load {ty= V128Type; align; offset; sz = Some (Pack16, ZX)}
237+
let v32x4_load_splat align offset =
238+
Load {ty= V128Type; align; offset; sz = Some (Pack32, ZX)}
239+
let v64x2_load_splat align offset =
240+
Load {ty= V128Type; align; offset; sz = Some (Pack64, ZX)}
221241
let v128_store align offset = Store {ty = V128Type; align; offset; sz = None}
242+
222243
let v128_not = Unary (V128 (V128Op.V128 V128Op.Not))
223244
let v128_and = Binary (V128 (V128Op.V128 V128Op.And))
224245
let v128_andnot = Binary (V128 (V128Op.V128 V128Op.AndNot))

interpreter/syntax/types.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type extern_type =
1616
| ExternMemoryType of memory_type
1717
| ExternGlobalType of global_type
1818

19-
type pack_size = Pack8 | Pack16 | Pack32
19+
type pack_size = Pack8 | Pack16 | Pack32 | Pack64 | Pack8x8 | Pack16x4 | Pack32x2
2020
type extension = SX | ZX
2121

2222

@@ -31,7 +31,7 @@ let packed_size = function
3131
| Pack8 -> 1
3232
| Pack16 -> 2
3333
| Pack32 -> 4
34-
34+
| Pack64 | Pack8x8 | Pack16x4 | Pack32x2 -> 8
3535

3636
(* Subtyping *)
3737

interpreter/text/arrange.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ let pack_size = function
7777
| Pack8 -> "8"
7878
| Pack16 -> "16"
7979
| Pack32 -> "32"
80+
| Pack64 -> "64"
81+
| Pack8x8 -> "8x8"
82+
| Pack16x4 -> "16x4"
83+
| Pack32x2 -> "32x2"
8084

8185
let extension = function
8286
| SX -> "_s"

interpreter/text/lexer.mll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,20 @@ rule token = parse
288288
(ext s i64_load8_s i64_load8_u (opt a 0))
289289
(ext s i64_load16_s i64_load16_u (opt a 1))
290290
(ext s i64_load32_s i64_load32_u (opt a 2)) o)) }
291+
| "i16x8.load8x8_"(sign as s)
292+
{ LOAD (fun a o -> (ext s i16x8_load8x8_s i16x8_load8x8_u (opt a 3)) o) }
293+
| "i32x4.load16x4_"(sign as s)
294+
{ LOAD (fun a o -> (ext s i32x4_load16x4_s i32x4_load16x4_u (opt a 3)) o) }
295+
| "i64x2.load32x2_"(sign as s)
296+
{ LOAD (fun a o -> (ext s i64x2_load32x2_s i64x2_load32x2_u (opt a 3)) o) }
297+
| "v8x16.load_splat"
298+
{ LOAD (fun a o -> (v8x16_load_splat (opt a 0)) o) }
299+
| "v16x8.load_splat"
300+
{ LOAD (fun a o -> (v16x8_load_splat (opt a 1)) o) }
301+
| "v32x4.load_splat"
302+
{ LOAD (fun a o -> (v32x4_load_splat (opt a 2)) o) }
303+
| "v64x2.load_splat"
304+
{ LOAD (fun a o -> (v64x2_load_splat (opt a 3)) o) }
291305
| (ixx as t)".store"(mem_size as sz)
292306
{ if t = "i32" && sz = "32" then error lexbuf "unknown operator";
293307
STORE (fun a o ->

test/core/simd/simd_align.wast

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
(module quote
106106
"(memory 1) (func (drop (v128.load align=-1 (i32.const 0))))"
107107
)
108-
"alignment must be a power of two"
108+
"unknown operator"
109109
)
110110
(assert_malformed
111111
(module quote
@@ -123,7 +123,7 @@
123123
(module quote
124124
"(memory 1) (func (v128.store align=-1 (i32.const 0) (v128.const i32x4 0 0 0 0)))"
125125
)
126-
"alignment must be a power of two"
126+
"unknown operator"
127127
)
128128
(assert_malformed
129129
(module quote
@@ -141,7 +141,7 @@
141141
(module quote
142142
"(memory 1) (func (result v128) (i16x8.load8x8_s align=-1 (i32.const 0)))"
143143
)
144-
"alignment must be a power of two"
144+
"unknown operator"
145145
)
146146
(assert_malformed
147147
(module quote
@@ -159,7 +159,7 @@
159159
(module quote
160160
"(memory 1) (func (result v128) (i16x8.load8x8_u align=-1 (i32.const 0)))"
161161
)
162-
"alignment must be a power of two"
162+
"unknown operator"
163163
)
164164
(assert_malformed
165165
(module quote
@@ -177,7 +177,7 @@
177177
(module quote
178178
"(memory 1) (func (result v128) (i32x4.load16x4_s align=-1 (i32.const 0)))"
179179
)
180-
"alignment must be a power of two"
180+
"unknown operator"
181181
)
182182
(assert_malformed
183183
(module quote
@@ -195,7 +195,7 @@
195195
(module quote
196196
"(memory 1) (func (result v128) (i32x4.load16x4_u align=-1 (i32.const 0)))"
197197
)
198-
"alignment must be a power of two"
198+
"unknown operator"
199199
)
200200
(assert_malformed
201201
(module quote
@@ -213,7 +213,7 @@
213213
(module quote
214214
"(memory 1) (func (result v128) (i64x2.load32x2_s align=-1 (i32.const 0)))"
215215
)
216-
"alignment must be a power of two"
216+
"unknown operator"
217217
)
218218
(assert_malformed
219219
(module quote
@@ -231,7 +231,7 @@
231231
(module quote
232232
"(memory 1) (func (result v128) (i64x2.load32x2_u align=-1 (i32.const 0)))"
233233
)
234-
"alignment must be a power of two"
234+
"unknown operator"
235235
)
236236
(assert_malformed
237237
(module quote
@@ -249,7 +249,7 @@
249249
(module quote
250250
"(memory 1) (func (result v128) (v8x16.load_splat align=-1 (i32.const 0)))"
251251
)
252-
"alignment must be a power of two"
252+
"unknown operator"
253253
)
254254
(assert_malformed
255255
(module quote
@@ -261,7 +261,7 @@
261261
(module quote
262262
"(memory 1) (func (result v128) (v16x8.load_splat align=-1 (i32.const 0)))"
263263
)
264-
"alignment must be a power of two"
264+
"unknown operator"
265265
)
266266
(assert_malformed
267267
(module quote
@@ -273,7 +273,7 @@
273273
(module quote
274274
"(memory 1) (func (result v128) (v32x4.load_splat align=-1 (i32.const 0)))"
275275
)
276-
"alignment must be a power of two"
276+
"unknown operator"
277277
)
278278
(assert_malformed
279279
(module quote
@@ -291,7 +291,7 @@
291291
(module quote
292292
"(memory 1) (func (result v128) (v64x2.load_splat align=-1 (i32.const 0)))"
293293
)
294-
"alignment must be a power of two"
294+
"unknown operator"
295295
)
296296
(assert_malformed
297297
(module quote

0 commit comments

Comments
 (0)