Skip to content

Commit

Permalink
Implement SIMD splats using Convert (WebAssembly#274)
Browse files Browse the repository at this point in the history
i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 splats.

Implemented using Convert ast as a splat essentially takes a value of
every other type to V128.
  • Loading branch information
ngzhian authored Jul 27, 2020
1 parent 5247c98 commit 129da6c
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 7 deletions.
13 changes: 9 additions & 4 deletions interpreter/exec/eval_numeric.ml
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,17 @@ end

module V128CvtOp =
struct
(* TODO
open Ast.SimdOp
*)

(* FIXME *)
let cvtop op v = failwith "TODO v128"
let cvtop op v : value =
match op with
| I8x16 Splat -> V128 (V128.I8x16.splat (I32Op.of_value 1 v))
| I16x8 Splat -> V128 (V128.I16x8.splat (I32Op.of_value 1 v))
| I32x4 Splat -> V128 (V128.I32x4.splat (I32Op.of_value 1 v))
| I64x2 Splat -> V128 (V128.I64x2.splat (I64Op.of_value 1 v))
| F32x4 Splat -> V128 (V128.F32x4.splat (F32Op.of_value 1 v))
| F64x2 Splat -> V128 (V128.F64x2.splat (F64Op.of_value 1 v))
| _ -> assert false
end

let eval_extractop extractop v = V128Op.extractop extractop v
Expand Down
14 changes: 13 additions & 1 deletion interpreter/exec/simd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ sig
type t
type lane

val splat : lane -> t
val extract_lane : int -> t -> lane
val abs : t -> t
val neg : t -> t
Expand All @@ -67,6 +68,8 @@ sig
type t
type lane

val splat : lane -> t
val extract_lane : int -> t -> lane
val abs : t -> t
val neg : t -> t
val sqrt : t -> t
Expand All @@ -76,7 +79,6 @@ sig
val div : t -> t -> t
val min : t -> t -> t
val max : t -> t -> t
val extract_lane : int -> t -> lane
end

module type Vec =
Expand Down Expand Up @@ -148,6 +150,7 @@ struct
module MakeFloat (Float : Float.S) (Convert : sig
val to_shape : Rep.t -> Float.t list
val of_shape : Float.t list -> Rep.t
val num_lanes : int
end) : Float with type t = Rep.t and type lane = Float.t =
struct
type t = Rep.t
Expand All @@ -163,16 +166,19 @@ struct
let div = binop Float.div
let min = binop Float.min
let max = binop Float.max
let splat x = Convert.of_shape (List.init Convert.num_lanes (fun i -> x))
let extract_lane i s = List.nth (Convert.to_shape s) i
end

module MakeInt (Int : Int.S) (Convert : sig
val to_shape : Rep.t -> Int.t list
val of_shape : Int.t list -> Rep.t
val num_lanes : int
end) : Int with type t = Rep.t and type lane = Int.t =
struct
type t = Rep.t
type lane = Int.t
let splat x = Convert.of_shape (List.init Convert.num_lanes (fun i -> x))
let extract_lane i s = List.nth (Convert.to_shape s) i
let unop f x = Convert.of_shape (List.map f (Convert.to_shape x))
let binop f x y = Convert.of_shape (List.map2 f (Convert.to_shape x) (Convert.to_shape y))
Expand All @@ -197,31 +203,37 @@ struct
module I8x16 = MakeInt (I8) (struct
let to_shape = Rep.to_i8x16
let of_shape = Rep.of_i8x16
let num_lanes = lanes I8x16
end)

module I16x8 = MakeInt (I16) (struct
let to_shape = Rep.to_i16x8
let of_shape = Rep.of_i16x8
let num_lanes = lanes I16x8
end)

module I32x4 = MakeInt (I32) (struct
let to_shape = Rep.to_i32x4
let of_shape = Rep.of_i32x4
let num_lanes = lanes I32x4
end)

module I64x2 = MakeInt (I64) (struct
let to_shape = Rep.to_i64x2
let of_shape = Rep.of_i64x2
let num_lanes = lanes I64x2
end)

module F32x4 = MakeFloat (F32) (struct
let to_shape = Rep.to_f32x4
let of_shape = Rep.of_f32x4
let num_lanes = lanes F32x4
end)

module F64x2 = MakeFloat (F64) (struct
let to_shape = Rep.to_f64x2
let of_shape = Rep.of_f64x2
let num_lanes = lanes F64x2
end)

end
3 changes: 2 additions & 1 deletion interpreter/syntax/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ struct
type testop = (vtestop, vtestop, vtestop, vtestop, vtestop, vtestop, vtestop) v128op
type ternop = Bitselect
type relop = TodoRelOp
type cvtop = TodoCvtOp
type vcvtop = Splat
type cvtop = (vcvtop, vcvtop, vcvtop, vcvtop, vcvtop, vcvtop, vcvtop) v128op
type extractop = I32x4ExtractLane of int | F32x4ExtractLane of int
end

Expand Down
6 changes: 6 additions & 0 deletions interpreter/syntax/operators.ml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ let v128_or = Binary (V128 (V128Op.V128 V128Op.Or))
let v128_xor = Binary (V128 (V128Op.V128 V128Op.Xor))
let v128_bitselect = Ternary (V128Op.Bitselect)

let i8x16_splat = Convert (V128 (V128Op.I8x16 V128Op.Splat))
let i8x16_neg = Unary (V128 (V128Op.I8x16 V128Op.Neg))
let i8x16_any_true = Test (V128 (V128Op.I8x16 V128Op.AnyTrue))
let i8x16_all_true = Test (V128 (V128Op.I8x16 V128Op.AllTrue))
Expand All @@ -236,6 +237,7 @@ let i8x16_max_s = Binary (V128 (V128Op.I8x16 V128Op.MaxS))
let i8x16_max_u = Binary (V128 (V128Op.I8x16 V128Op.MaxU))
let i8x16_avgr_u = Binary (V128 (V128Op.I8x16 V128Op.AvgrU))

let i16x8_splat = Convert (V128 (V128Op.I16x8 V128Op.Splat))
let i16x8_neg = Unary (V128 (V128Op.I16x8 V128Op.Neg))
let i16x8_any_true = Test (V128 (V128Op.I16x8 V128Op.AnyTrue))
let i16x8_all_true = Test (V128 (V128Op.I16x8 V128Op.AllTrue))
Expand All @@ -249,6 +251,7 @@ let i16x8_max_s = Binary (V128 (V128Op.I16x8 V128Op.MaxS))
let i16x8_max_u = Binary (V128 (V128Op.I16x8 V128Op.MaxU))
let i16x8_avgr_u = Binary (V128 (V128Op.I16x8 V128Op.AvgrU))

let i32x4_splat = Convert (V128 (V128Op.I32x4 V128Op.Splat))
let i32x4_extract_lane imm = ExtractLane (V128Op.I32x4ExtractLane imm)
let i32x4_abs = Unary (V128 (V128Op.I32x4 V128Op.Abs))
let i32x4_neg = Unary (V128 (V128Op.I32x4 V128Op.Neg))
Expand All @@ -262,11 +265,13 @@ let i32x4_max_s = Binary (V128 (V128Op.I32x4 V128Op.MaxS))
let i32x4_max_u = Binary (V128 (V128Op.I32x4 V128Op.MaxU))
let i32x4_mul = Binary (V128 (V128Op.I32x4 V128Op.Mul))

let i64x2_splat = Convert (V128 (V128Op.I64x2 V128Op.Splat))
let i64x2_neg = Unary (V128 (V128Op.I64x2 V128Op.Neg))
let i64x2_add = Binary (V128 (V128Op.I64x2 V128Op.Add))
let i64x2_sub = Binary (V128 (V128Op.I64x2 V128Op.Sub))
let i64x2_mul = Binary (V128 (V128Op.I64x2 V128Op.Mul))

let f32x4_splat = Convert (V128 (V128Op.F32x4 V128Op.Splat))
let f32x4_extract_lane imm = ExtractLane (V128Op.F32x4ExtractLane imm)
let f32x4_abs = Unary (V128 (V128Op.F32x4 V128Op.Abs))
let f32x4_neg = Unary (V128 (V128Op.F32x4 V128Op.Neg))
Expand All @@ -278,6 +283,7 @@ let f32x4_div = Binary (V128 (V128Op.F32x4 V128Op.Div))
let f32x4_min = Binary (V128 (V128Op.F32x4 V128Op.Min))
let f32x4_max = Binary (V128 (V128Op.F32x4 V128Op.Max))

let f64x2_splat = Convert (V128 (V128Op.F64x2 V128Op.Splat))
let f64x2_neg = Unary (V128 (V128Op.F64x2 V128Op.Neg))
let f64x2_sqrt = Unary (V128 (V128Op.F64x2 V128Op.Sqrt))
let f64x2_add = Binary (V128 (V128Op.F64x2 V128Op.Add))
Expand Down
3 changes: 3 additions & 0 deletions interpreter/text/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ rule token = parse
| "global.get" { GLOBAL_GET }
| "global.set" { GLOBAL_SET }

| (simd_shape as s)".splat"
{ SPLAT (simdop s i8x16_splat i16x8_splat i32x4_splat
i64x2_splat f32x4_splat f64x2_splat) }
| (simd_shape as s)".extract_lane"
{ EXTRACT_LANE (fun imm ->
simdop s unimplemented_simd unimplemented_simd i32x4_extract_lane
Expand Down
10 changes: 9 additions & 1 deletion interpreter/valid/valid.ml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,15 @@ let type_cvtop at = function
| PromoteF32 -> F32Type
| DemoteF64 -> error at "invalid conversion"
), F64Type
| Values.V128 cvtop -> failwith "TODO v128"
| Values.V128 cvtop ->
let open V128Op in
(match cvtop with
| I8x16 Splat | I16x8 Splat | I32x4 Splat -> I32Type
| I64x2 Splat -> I64Type
| F32x4 Splat -> F32Type
| F64x2 Splat -> F64Type
| V128 Splat -> error at "invalid conversion"
), V128Type


(* Expressions *)
Expand Down

0 comments on commit 129da6c

Please sign in to comment.