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

[interpreter] Implement f64x2.convert_low_i32x4_{s,u} #473

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions interpreter/binary/decode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ let simd_prefix s =
| 0x50l -> v128_or
| 0x51l -> v128_xor
| 0x52l -> v128_bitselect
| 0x53l -> f64x2_convert_low_i32x4_s
| 0x54l -> f64x2_convert_low_i32x4_u
| 0x55l -> i32x4_trunc_sat_f64x2_s_zero
| 0x56l -> i32x4_trunc_sat_f64x2_u_zero
| 0x57l -> f32x4_demote_f64x2_zero
Expand Down
2 changes: 2 additions & 0 deletions interpreter/binary/encode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,8 @@ let encode m =
| Unary (V128 V128Op.(F32x4 ConvertI32x4U)) -> simd_op 0xfbl
| Unary (V128 V128Op.(F32x4 DemoteF64x2Zero)) -> simd_op 0x57l
| Unary (V128 V128Op.(F64x2 PromoteLowF32x4)) -> simd_op 0x69l
| Unary (V128 V128Op.(F64x2 ConvertI32x4S)) -> simd_op 0x53l
| Unary (V128 V128Op.(F64x2 ConvertI32x4U)) -> simd_op 0x54l
| Unary (V128 _) -> failwith "unimplemented V128 Unary op"

| Binary (I32 I32Op.Add) -> op 0x6a
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 @@ -59,6 +59,8 @@ module SimdOp (SXX : Simd.S) (Value : ValueType with type t = SXX.t) = struct
| F64x2 Trunc -> to_value (SXX.F64x2.trunc (of_value 1 v))
| F64x2 Nearest -> to_value (SXX.F64x2.nearest (of_value 1 v))
| F64x2 PromoteLowF32x4 -> to_value (SXX.F64x2_convert.promote_low_f32x4 (of_value 1 v))
| F64x2 ConvertI32x4S -> to_value (SXX.F64x2_convert.convert_i32x4_s (of_value 1 v))
| F64x2 ConvertI32x4U -> to_value (SXX.F64x2_convert.convert_i32x4_u (of_value 1 v))
| V128 Not -> to_value (SXX.V128.lognot (of_value 1 v))
| _ -> assert false

Expand Down
5 changes: 5 additions & 0 deletions interpreter/exec/simd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ sig

module F64x2_convert : sig
val promote_low_f32x4 : t -> t
val convert_i32x4_s : t -> t
val convert_i32x4_u : t -> t
end
end

Expand Down Expand Up @@ -509,6 +511,9 @@ struct
end

module F64x2_convert = struct
let convert f v = Rep.of_f64x2 (List.map f (Lib.List.take 2 (Rep.to_i32x4 v)))
let convert_i32x4_s = convert F64_convert.convert_i32_s
let convert_i32x4_u = convert F64_convert.convert_i32_u
let promote_low_f32x4 v =
Rep.(of_f64x2 (List.map F64_convert.promote_f32 (Lib.List.take 2 (to_f32x4 v))))
end
Expand Down
2 changes: 2 additions & 0 deletions interpreter/syntax/operators.ml
Original file line number Diff line number Diff line change
Expand Up @@ -478,3 +478,5 @@ let f64x2_abs = Unary (V128 V128Op.(F64x2 Abs))
let f64x2_pmin = Binary (V128 V128Op.(F64x2 Pmin))
let f64x2_pmax = Binary (V128 V128Op.(F64x2 Pmax))
let f64x2_promote_low_f32x4 = Unary (V128 V128Op.(F64x2 PromoteLowF32x4))
let f64x2_convert_low_i32x4_s = Unary (V128 V128Op.(F64x2 ConvertI32x4S))
let f64x2_convert_low_i32x4_u = Unary (V128 V128Op.(F64x2 ConvertI32x4U))
2 changes: 2 additions & 0 deletions interpreter/text/arrange.ml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ struct
| F64x2 Neg -> "f64x2.neg"
| F64x2 Sqrt -> "f64x2.sqrt"
| F64x2 PromoteLowF32x4 -> "f64x2.promote_low_f32x4"
| F64x2 ConvertI32x4S -> "f64x2.convert_low_i32x4_s"
| F64x2 ConvertI32x4U -> "f64x2.convert_low_i32x4_u"
| V128 Not -> "v128.not"
| _ -> failwith "Unimplemented v128 unop"

Expand Down
2 changes: 2 additions & 0 deletions interpreter/text/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ rule token = parse
{ UNARY f32x4_demote_f64x2_zero }
| "f32x4.convert_i32x4_"(sign as s)
{ UNARY (ext s f32x4_convert_i32x4_s f32x4_convert_i32x4_u) }
| "f64x2.convert_low_i32x4_"(sign as s)
{ UNARY (ext s f64x2_convert_low_i32x4_s f64x2_convert_low_i32x4_u) }
| "i8x16.narrow_i16x8_"(sign as s)
{ BINARY (ext s i8x16_narrow_i16x8_s i8x16_narrow_i16x8_u) }
| "i16x8.narrow_i32x4_"(sign as s)
Expand Down
35 changes: 35 additions & 0 deletions test/core/simd/simd_conversions.wast
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
(func (export "f32x4.convert_i32x4_u") (param v128) (result v128)
(f32x4.convert_i32x4_u (local.get 0)))

(func (export "f64x2.convert_low_i32x4_s") (param v128) (result v128)
(f64x2.convert_low_i32x4_s (local.get 0)))
(func (export "f64x2.convert_low_i32x4_u") (param v128) (result v128)
(f64x2.convert_low_i32x4_u (local.get 0)))

;; Integer to integer narrowing
(func (export "i8x16.narrow_i16x8_s") (param v128 v128) (result v128)
(i8x16.narrow_i16x8_s (local.get 0) (local.get 1)))
Expand Down Expand Up @@ -242,6 +247,36 @@
(assert_return (invoke "f32x4.convert_i32x4_u" (v128.const i32x4 0 -1 0x7fffffff 0x80000000))
(v128.const f32x4 0.0 4294967295.0 2147483647.0 2147483648.0))

;; f64x2.convert_i32x4_s
;; constants copied from test/core/conversions.wast.

(assert_return (invoke "f64x2.convert_low_i32x4_s" (v128.const i32x4 1 1 0 0))
(v128.const f64x2 1.0 1.0))
(assert_return (invoke "f64x2.convert_low_i32x4_s" (v128.const i32x4 -1 -1 0 0))
(v128.const f64x2 -1.0 -1.0))
(assert_return (invoke "f64x2.convert_low_i32x4_s" (v128.const i32x4 0 0 0 0))
(v128.const f64x2 0.0 0.0))
(assert_return (invoke "f64x2.convert_low_i32x4_s" (v128.const i32x4 2147483647 2147483647 0 0))
(v128.const f64x2 2147483647 2147483647))
(assert_return (invoke "f64x2.convert_low_i32x4_s" (v128.const i32x4 -2147483648 -2147483648 0 0))
(v128.const f64x2 -2147483648 -2147483648))
(assert_return (invoke "f64x2.convert_low_i32x4_s" (v128.const i32x4 987654321 987654321 0 0))
(v128.const f64x2 987654321 987654321))

;; f64x2.convert_i32x4_u
;; constants copied from test/core/conversions.wast.

(assert_return (invoke "f64x2.convert_low_i32x4_u" (v128.const i32x4 1 1 0 0))
(v128.const f64x2 1.0 1.0))
(assert_return (invoke "f64x2.convert_low_i32x4_u" (v128.const i32x4 0 0 0 0))
(v128.const f64x2 0.0 0.0))
(assert_return (invoke "f64x2.convert_low_i32x4_u" (v128.const i32x4 2147483647 2147483647 0 0))
(v128.const f64x2 2147483647 2147483647))
(assert_return (invoke "f64x2.convert_low_i32x4_u" (v128.const i32x4 -2147483648 -2147483648 0 0))
(v128.const f64x2 2147483648 2147483648))
(assert_return (invoke "f64x2.convert_low_i32x4_u" (v128.const i32x4 0xffffffff 0xffffffff 0 0))
(v128.const f64x2 4294967295.0 4294967295.0))

;; Integer to integer narrowing
;; i8x16.narrow_i16x8_s

Expand Down