diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index 8839c1d06..703814a9f 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -399,6 +399,8 @@ let simd_prefix s = | 0xa2l -> i64x2_abs | 0xa3l -> i32x4_all_true | 0xa4l -> i32x4_bitmask + | 0xa5l -> i32x4_extadd_pairwise_i16x8_s + | 0xa6l -> i32x4_extadd_pairwise_i16x8_u | 0xa7l -> i32x4_widen_low_i16x8_s | 0xa8l -> i32x4_widen_high_i16x8_s | 0xa9l -> i32x4_widen_low_i16x8_u @@ -420,6 +422,8 @@ let simd_prefix s = | 0xbfl -> i32x4_extmul_high_i16x8_u | 0xc0l -> i64x2_eq | 0xc1l -> i64x2_neg + | 0xc2l -> i16x8_extadd_pairwise_i8x16_s + | 0xc3l -> i16x8_extadd_pairwise_i8x16_u | 0xc4l -> i64x2_bitmask | 0xc7l -> i64x2_widen_low_i32x4_s | 0xc8l -> i64x2_widen_high_i32x4_s diff --git a/interpreter/binary/encode.ml b/interpreter/binary/encode.ml index f84c78af9..72f2e9ca1 100644 --- a/interpreter/binary/encode.ml +++ b/interpreter/binary/encode.ml @@ -354,12 +354,16 @@ let encode m = | Unary (V128 V128Op.(I16x8 WidenHighS)) -> simd_op 0x88l | Unary (V128 V128Op.(I16x8 WidenLowU)) -> simd_op 0x89l | Unary (V128 V128Op.(I16x8 WidenHighU)) -> simd_op 0x8al + | Unary (V128 V128Op.(I16x8 ExtAddPairwiseS)) -> simd_op 0xc2l + | Unary (V128 V128Op.(I16x8 ExtAddPairwiseU)) -> simd_op 0xc3l | Unary (V128 V128Op.(I32x4 Abs)) -> simd_op 0xa0l | Unary (V128 V128Op.(I32x4 Neg)) -> simd_op 0xa1l | Unary (V128 V128Op.(I32x4 WidenLowS)) -> simd_op 0xa7l | Unary (V128 V128Op.(I32x4 WidenHighS)) -> simd_op 0xa8l | Unary (V128 V128Op.(I32x4 WidenLowU)) -> simd_op 0xa9l | Unary (V128 V128Op.(I32x4 WidenHighU)) -> simd_op 0xaal + | Unary (V128 V128Op.(I32x4 ExtAddPairwiseS)) -> simd_op 0xa5l + | Unary (V128 V128Op.(I32x4 ExtAddPairwiseU)) -> simd_op 0xa6l | Unary (V128 V128Op.(I64x2 Abs)) -> simd_op 0xa2l | Unary (V128 V128Op.(I64x2 Neg)) -> simd_op 0xc1l | Unary (V128 V128Op.(I64x2 WidenLowS)) -> simd_op 0xc7l diff --git a/interpreter/exec/eval_simd.ml b/interpreter/exec/eval_simd.ml index 4b1a555a6..f227ea840 100644 --- a/interpreter/exec/eval_simd.ml +++ b/interpreter/exec/eval_simd.ml @@ -23,6 +23,8 @@ module SimdOp (SXX : Simd.S) (Value : ValueType with type t = SXX.t) = struct | I16x8 WidenHighS -> to_value (SXX.I16x8_convert.widen_high_s (of_value 1 v)) | I16x8 WidenLowU -> to_value (SXX.I16x8_convert.widen_low_u (of_value 1 v)) | I16x8 WidenHighU -> to_value (SXX.I16x8_convert.widen_high_u (of_value 1 v)) + | I16x8 ExtAddPairwiseS -> to_value (SXX.I16x8_convert.extadd_pairwise_s (of_value 1 v)) + | I16x8 ExtAddPairwiseU -> to_value (SXX.I16x8_convert.extadd_pairwise_u (of_value 1 v)) | I32x4 Abs -> to_value (SXX.I32x4.abs (of_value 1 v)) | I32x4 Neg -> to_value (SXX.I32x4.neg (of_value 1 v)) | I32x4 WidenLowS -> to_value (SXX.I32x4_convert.widen_low_s (of_value 1 v)) @@ -35,6 +37,8 @@ module SimdOp (SXX : Simd.S) (Value : ValueType with type t = SXX.t) = struct to_value (SXX.I32x4_convert.trunc_sat_f64x2_s_zero (of_value 1 v)) | I32x4 TruncSatF64x2UZero -> to_value (SXX.I32x4_convert.trunc_sat_f64x2_u_zero (of_value 1 v)) + | I32x4 ExtAddPairwiseS -> to_value (SXX.I32x4_convert.extadd_pairwise_s (of_value 1 v)) + | I32x4 ExtAddPairwiseU -> to_value (SXX.I32x4_convert.extadd_pairwise_u (of_value 1 v)) | I64x2 Abs -> to_value (SXX.I64x2.abs (of_value 1 v)) | I64x2 Neg -> to_value (SXX.I64x2.neg (of_value 1 v)) | I64x2 WidenLowS -> to_value (SXX.I64x2_convert.widen_low_s (of_value 1 v)) diff --git a/interpreter/exec/simd.ml b/interpreter/exec/simd.ml index 3fec3045d..37d5ee504 100644 --- a/interpreter/exec/simd.ml +++ b/interpreter/exec/simd.ml @@ -183,6 +183,8 @@ sig val extmul_high_s : t -> t -> t val extmul_low_u : t -> t -> t val extmul_high_u : t -> t -> t + val extadd_pairwise_s : t -> t + val extadd_pairwise_u : t -> t end module I32x4_convert : sig val trunc_sat_f32x4_s : t -> t @@ -198,6 +200,8 @@ sig val extmul_high_s : t -> t -> t val extmul_low_u : t -> t -> t val extmul_high_u : t -> t -> t + val extadd_pairwise_s : t -> t + val extadd_pairwise_u : t -> t end module I64x2_convert : sig val widen_low_s : t -> t @@ -436,17 +440,23 @@ struct let narrow_s = narrow Rep.to_i32x4 Rep.of_i16x8 I16.saturate_s let narrow_u = narrow Rep.to_i32x4 Rep.of_i16x8 I16.saturate_u - let widen take_or_drop mask x = - Rep.of_i16x8 (List.map (Int32.logand mask) (take_or_drop 8 (Rep.to_i8x16 x))) - let widen_low_s = widen Lib.List.take 0xffffffffl - let widen_high_s = widen Lib.List.drop 0xffffffffl - let widen_low_u = widen Lib.List.take 0xffl - let widen_high_u = widen Lib.List.drop 0xffl + let ext_s = Int32.logand 0xffffffffl + let ext_u = Int32.logand 0xffl + + let widen take_or_drop ext x = Rep.of_i16x8 (List.map ext (take_or_drop 8 (Rep.to_i8x16 x))) + let widen_low_s = widen Lib.List.take ext_s + let widen_high_s = widen Lib.List.drop ext_s + let widen_low_u = widen Lib.List.take ext_u + let widen_high_u = widen Lib.List.drop ext_u let extmul_low_s x y = I16x8.mul (widen_low_s x) (widen_low_s y) let extmul_high_s x y = I16x8.mul (widen_high_s x) (widen_high_s y) let extmul_low_u x y = I16x8.mul (widen_low_u x) (widen_low_u y) let extmul_high_u x y = I16x8.mul (widen_high_u x) (widen_high_u y) + + let extadd ext x y = Int32.add (ext x) (ext y) + let extadd_pairwise_s x = Rep.of_i16x8 (Lib.List.pairwise (extadd ext_s) (Rep.to_i8x16 x)) + let extadd_pairwise_u x = Rep.of_i16x8 (Lib.List.pairwise (extadd ext_u) (Rep.to_i8x16 x)) end module I32x4_convert = struct @@ -459,12 +469,15 @@ struct let trunc_sat_f64x2_s_zero = convert_zero I32_convert.trunc_sat_f64_s let trunc_sat_f64x2_u_zero = convert_zero I32_convert.trunc_sat_f64_u - let widen take_or_drop mask x = - Rep.of_i32x4 (List.map (Int32.logand mask) (take_or_drop 4 (Rep.to_i16x8 x))) - let widen_low_s = widen Lib.List.take 0xffffffffl - let widen_high_s = widen Lib.List.drop 0xffffffffl - let widen_low_u = widen Lib.List.take 0xffffl - let widen_high_u = widen Lib.List.drop 0xffffl + let ext_s = Int32.logand 0xffffffffl + let ext_u = Int32.logand 0xffffl + + let widen take_or_drop ext x = + Rep.of_i32x4 (List.map ext (take_or_drop 4 (Rep.to_i16x8 x))) + let widen_low_s = widen Lib.List.take ext_s + let widen_high_s = widen Lib.List.drop ext_s + let widen_low_u = widen Lib.List.take ext_u + let widen_high_u = widen Lib.List.drop ext_u let dot_i16x8_s x y = let xs = Rep.to_i16x8 x in @@ -481,6 +494,10 @@ struct let extmul_high_s x y = I32x4.mul (widen_high_s x) (widen_high_s y) let extmul_low_u x y = I32x4.mul (widen_low_u x) (widen_low_u y) let extmul_high_u x y = I32x4.mul (widen_high_u x) (widen_high_u y) + + let extadd ext x y = Int32.add (ext x) (ext y) + let extadd_pairwise_s x = Rep.of_i32x4 (Lib.List.pairwise (extadd ext_s) (Rep.to_i16x8 x)) + let extadd_pairwise_u x = Rep.of_i32x4 (Lib.List.pairwise (extadd ext_u) (Rep.to_i16x8 x)) end module I64x2_convert = struct diff --git a/interpreter/syntax/ast.ml b/interpreter/syntax/ast.ml index 934fca825..23f83bb9b 100644 --- a/interpreter/syntax/ast.ml +++ b/interpreter/syntax/ast.ml @@ -51,6 +51,7 @@ struct type iunop = Abs | Neg | TruncSatF32x4S | TruncSatF32x4U | WidenLowS | WidenLowU | WidenHighS | WidenHighU | Popcnt | TruncSatF64x2SZero | TruncSatF64x2UZero + | ExtAddPairwiseS | ExtAddPairwiseU type ibinop = Add | Sub | MinS | MinU | MaxS | MaxU | Mul | AvgrU | Eq | Ne | LtS | LtU | LeS | LeU | GtS | GtU | GeS | GeU | Swizzle | Shuffle of int list | NarrowS | NarrowU diff --git a/interpreter/syntax/operators.ml b/interpreter/syntax/operators.ml index 828186a58..80b01ed74 100644 --- a/interpreter/syntax/operators.ml +++ b/interpreter/syntax/operators.ml @@ -355,6 +355,8 @@ let i16x8_extmul_high_i8x16_s = Binary (V128 V128Op.(I16x8 ExtMulHighS)) let i16x8_extmul_low_i8x16_u = Binary (V128 V128Op.(I16x8 ExtMulLowU)) let i16x8_extmul_high_i8x16_u = Binary (V128 V128Op.(I16x8 ExtMulHighU)) let i16x8_q15mulr_sat_s = Binary (V128 V128Op.(I16x8 Q15MulRSatS)) +let i16x8_extadd_pairwise_i8x16_s = Unary (V128 V128Op.(I16x8 ExtAddPairwiseS)) +let i16x8_extadd_pairwise_i8x16_u = Unary (V128 V128Op.(I16x8 ExtAddPairwiseU)) let i32x4_splat = Convert (V128 V128Op.(I32x4 Splat)) let i32x4_extract_lane imm = SimdExtract (V128Op.I32x4 (ZX, imm)) @@ -396,6 +398,8 @@ let i32x4_extmul_low_i16x8_s = Binary (V128 V128Op.(I32x4 ExtMulLowS)) let i32x4_extmul_high_i16x8_s = Binary (V128 V128Op.(I32x4 ExtMulHighS)) let i32x4_extmul_low_i16x8_u = Binary (V128 V128Op.(I32x4 ExtMulLowU)) let i32x4_extmul_high_i16x8_u = Binary (V128 V128Op.(I32x4 ExtMulHighU)) +let i32x4_extadd_pairwise_i16x8_s = Unary (V128 V128Op.(I32x4 ExtAddPairwiseS)) +let i32x4_extadd_pairwise_i16x8_u = Unary (V128 V128Op.(I32x4 ExtAddPairwiseU)) let i64x2_splat = Convert (V128 V128Op.(I64x2 Splat)) let i64x2_extract_lane imm = SimdExtract (V128Op.I64x2 (ZX, imm)) diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index 8e39925b9..29b57e596 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -210,6 +210,8 @@ struct | I16x8 WidenHighS -> "i16x8.widen_high_i8x16_s" | I16x8 WidenLowU -> "i16x8.widen_low_i8x16_u" | I16x8 WidenHighU -> "i16x8.widen_high_i8x16_u" + | I16x8 ExtAddPairwiseS -> "i16x8.extadd_pairwise_i8x16_s" + | I16x8 ExtAddPairwiseU -> "i16x8.extadd_pairwise_i8x16_u" | I32x4 Abs -> "i32x4.abs" | I32x4 Neg -> "i32x4.neg" | I32x4 WidenLowS -> "i32x4.widen_low_i16x8_s" @@ -220,6 +222,8 @@ struct | I32x4 TruncSatF32x4U -> "i32x4.trunc_sat_f32x4_u" | I32x4 TruncSatF64x2SZero -> "i32x4.trunc_sat_f64x2_s_zero" | I32x4 TruncSatF64x2UZero -> "i32x4.trunc_sat_f64x2_u_zero" + | I32x4 ExtAddPairwiseS -> "i32x4.extadd_pairwise_i16x8_s" + | I32x4 ExtAddPairwiseU -> "i32x4.extadd_pairwise_i16x8_u" | I64x2 Abs -> "i64x2.abs" | I64x2 Neg -> "i64x2.neg" | I64x2 WidenLowS -> "i64x2.widen_low_i32x4_s" diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index 52670cdcd..116e55c55 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -604,6 +604,11 @@ rule token = parse | "i16x8.q15mulr_sat_s" { BINARY i16x8_q15mulr_sat_s } + | "i16x8.extadd_pairwise_i8x16_"(sign as s) + { UNARY (ext s i16x8_extadd_pairwise_i8x16_s i16x8_extadd_pairwise_i8x16_u) } + | "i32x4.extadd_pairwise_i16x8_"(sign as s) + { UNARY (ext s i32x4_extadd_pairwise_i16x8_s i32x4_extadd_pairwise_i16x8_u) } + | (simd_shape as s) { SIMD_SHAPE (simd_shape s) } | name as s { VAR s } diff --git a/interpreter/util/lib.ml b/interpreter/util/lib.ml index eb6eff259..24cc5ff9a 100644 --- a/interpreter/util/lib.ml +++ b/interpreter/util/lib.ml @@ -105,6 +105,11 @@ struct let rec concat_map f = function | [] -> [] | x::xs -> f x @ concat_map f xs + + let rec pairwise f = function + | [] -> [] + | x1::x2::xs -> f x1 x2 :: pairwise f xs + | _ -> failwith "pairwise" end module List32 = diff --git a/interpreter/util/lib.mli b/interpreter/util/lib.mli index f9c918265..496955d58 100644 --- a/interpreter/util/lib.mli +++ b/interpreter/util/lib.mli @@ -22,6 +22,7 @@ sig val index_where : ('a -> bool) -> 'a list -> int option val map_filter : ('a -> 'b option) -> 'a list -> 'b list val concat_map : ('a -> 'b list) -> 'a list -> 'b list + val pairwise : ('a -> 'a -> 'b) -> 'a list -> 'b list end module List32 : diff --git a/test/core/simd/meta/README.md b/test/core/simd/meta/README.md index 6ae6747b5..835e1bba9 100644 --- a/test/core/simd/meta/README.md +++ b/test/core/simd/meta/README.md @@ -22,11 +22,28 @@ Currently it only support following simd test files generation. - 'simd_i16x8_sat_arith.wast' - 'simd_f32x4.wast' - 'simd_f64x2.wast' -- 'simd_f32x4_rounding' -- 'simd_f64x2_rounding' -- 'simd_f32x4_pmin_pmax' -- 'simd_f64x2_pmin_pmax' -- 'simd_i32x4_dot_i16x8' +- 'simd_f32x4_rounding.wast' +- 'simd_f64x2_rounding.wast' +- 'simd_f32x4_pmin_pmax.wast' +- 'simd_f64x2_pmin_pmax.wast' +- 'simd_i32x4_dot_i16x8.wast' +- 'simd_load8_lane.wast' +- 'simd_load16_lane.wast' +- 'simd_load32_lane.wast' +- 'simd_load64_lane.wast, +- 'simd_store8_lane.wast' +- 'simd_store16_lane.wast' +- 'simd_store32_lane.wast' +- 'simd_store64_lane.wast, +- 'simd_i16x8_extmul_i8x16.wast' +- 'simd_i32x4_extmul_i16x8.wast' +- 'simd_i64x2_extmul_i32x4.wast' +- 'simd_int_to_int_widen.wast' +- 'simd_i32x4_trunc_sat_f32x4.wast' +- 'simd_i32x4_trunc_sat_f64x2.wast' +- 'simd_i16x8_q15mulr_sat_s.wast', +- 'simd_i16x8_extadd_pairwise_i8x16.wast', +- 'simd_i32x4_extadd_pairwise_i16x8.wast', Usage: diff --git a/test/core/simd/meta/gen_tests.py b/test/core/simd/meta/gen_tests.py index 453404550..9e8dc95b1 100644 --- a/test/core/simd/meta/gen_tests.py +++ b/test/core/simd/meta/gen_tests.py @@ -38,6 +38,7 @@ 'simd_int_to_int_widen', 'simd_int_trunc_sat_float', 'simd_i16x8_q15mulr_sat_s', + 'simd_extadd_pairwise', ) diff --git a/test/core/simd/meta/simd_extadd_pairwise.py b/test/core/simd/meta/simd_extadd_pairwise.py new file mode 100644 index 000000000..8a398414d --- /dev/null +++ b/test/core/simd/meta/simd_extadd_pairwise.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +from simd_arithmetic import SimdArithmeticCase, i16 +from simd_integer_op import ArithmeticOp + + +class SimdExtAddPairwise(SimdArithmeticCase): + BINARY_OPS = () + + def unary_op(self, x, signed): + # For test data we always splat a single value to the + # entire v128, so doubling the input works. + return ArithmeticOp.get_valid_value(x, self.src_lane, signed=signed) * 2 + + @property + def hex_unary_op_test_data(self): + return [] + + @property + def unary_test_data(self): + return [ + (self.normal_unary_op_test_data, [self.SRC_LANE_TYPE,self.LANE_TYPE]), + ] + + def get_case_data(self): + case_data = [] + for op in self.UNARY_OPS: + op_name = self.op_name(op) + case_data.append(['#', op_name]) + for data_group, v128_forms in self.unary_test_data: + for data in data_group: + case_data.append([op_name, [str(data)], + str(self.unary_op(data, op.endswith('s'))), + v128_forms]) + return case_data + + def get_combine_cases(self): + return '' + + def gen_test_cases(self): + wast_filename = '../simd_{}_extadd_pairwise_{}.wast'.format(self.LANE_TYPE, self.SRC_LANE_TYPE) + with open(wast_filename, 'w') as fp: + fp.write(self.get_all_cases()) + +class SimdI16x8ExtAddPairwise(SimdExtAddPairwise): + UNARY_OPS = ('extadd_pairwise_i8x16_s','extadd_pairwise_i8x16_u') + LANE_TYPE = 'i16x8' + SRC_LANE_TYPE = 'i8x16' + +class SimdI32x4ExtAddPairwise(SimdExtAddPairwise): + UNARY_OPS = ('extadd_pairwise_i16x8_s','extadd_pairwise_i16x8_u') + LANE_TYPE = 'i32x4' + SRC_LANE_TYPE = 'i16x8' + +def gen_test_cases(): + simd_i16x8_arith = SimdI16x8ExtAddPairwise() + simd_i32x4_arith = SimdI32x4ExtAddPairwise() + simd_i16x8_arith.gen_test_cases() + simd_i32x4_arith.gen_test_cases() + +if __name__ == '__main__': + gen_test_cases() diff --git a/test/core/simd/simd_i16x8_extadd_pairwise_i8x16.wast b/test/core/simd/simd_i16x8_extadd_pairwise_i8x16.wast new file mode 100644 index 000000000..c2267de9c --- /dev/null +++ b/test/core/simd/simd_i16x8_extadd_pairwise_i8x16.wast @@ -0,0 +1,68 @@ +;; Tests for i16x8 arithmetic operations on major boundary values and all special values. + + +(module + (func (export "i16x8.extadd_pairwise_i8x16_s") (param v128) (result v128) (i16x8.extadd_pairwise_i8x16_s (local.get 0))) + (func (export "i16x8.extadd_pairwise_i8x16_u") (param v128) (result v128) (i16x8.extadd_pairwise_i8x16_u (local.get 0))) +) + + +;; i16x8.extadd_pairwise_i8x16_s +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_s" (v128.const i8x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)) + (v128.const i16x8 0 0 0 0 0 0 0 0)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_s" (v128.const i8x16 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)) + (v128.const i16x8 2 2 2 2 2 2 2 2)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_s" (v128.const i8x16 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i16x8 -2 -2 -2 -2 -2 -2 -2 -2)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_s" (v128.const i8x16 126 126 126 126 126 126 126 126 126 126 126 126 126 126 126 126)) + (v128.const i16x8 252 252 252 252 252 252 252 252)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_s" (v128.const i8x16 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127)) + (v128.const i16x8 -254 -254 -254 -254 -254 -254 -254 -254)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_s" (v128.const i8x16 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128)) + (v128.const i16x8 -256 -256 -256 -256 -256 -256 -256 -256)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_s" (v128.const i8x16 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127)) + (v128.const i16x8 254 254 254 254 254 254 254 254)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_s" (v128.const i8x16 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255)) + (v128.const i16x8 -2 -2 -2 -2 -2 -2 -2 -2)) + +;; i16x8.extadd_pairwise_i8x16_u +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_u" (v128.const i8x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)) + (v128.const i16x8 0 0 0 0 0 0 0 0)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_u" (v128.const i8x16 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)) + (v128.const i16x8 2 2 2 2 2 2 2 2)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_u" (v128.const i8x16 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i16x8 510 510 510 510 510 510 510 510)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_u" (v128.const i8x16 126 126 126 126 126 126 126 126 126 126 126 126 126 126 126 126)) + (v128.const i16x8 252 252 252 252 252 252 252 252)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_u" (v128.const i8x16 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127 -127)) + (v128.const i16x8 258 258 258 258 258 258 258 258)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_u" (v128.const i8x16 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128 -128)) + (v128.const i16x8 256 256 256 256 256 256 256 256)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_u" (v128.const i8x16 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127 127)) + (v128.const i16x8 254 254 254 254 254 254 254 254)) +(assert_return (invoke "i16x8.extadd_pairwise_i8x16_u" (v128.const i8x16 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255)) + (v128.const i16x8 510 510 510 510 510 510 510 510)) + +;; type check +(assert_invalid (module (func (result v128) (i16x8.extadd_pairwise_i8x16_s (i32.const 0)))) "type mismatch") +(assert_invalid (module (func (result v128) (i16x8.extadd_pairwise_i8x16_u (i32.const 0)))) "type mismatch") + +;; Test operation with empty argument + +(assert_invalid + (module + (func $i16x8.extadd_pairwise_i8x16_s-arg-empty (result v128) + (i16x8.extadd_pairwise_i8x16_s) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func $i16x8.extadd_pairwise_i8x16_u-arg-empty (result v128) + (i16x8.extadd_pairwise_i8x16_u) + ) + ) + "type mismatch" +) + diff --git a/test/core/simd/simd_i32x4_extadd_pairwise_i16x8.wast b/test/core/simd/simd_i32x4_extadd_pairwise_i16x8.wast new file mode 100644 index 000000000..2d1682d40 --- /dev/null +++ b/test/core/simd/simd_i32x4_extadd_pairwise_i16x8.wast @@ -0,0 +1,68 @@ +;; Tests for i32x4 arithmetic operations on major boundary values and all special values. + + +(module + (func (export "i32x4.extadd_pairwise_i16x8_s") (param v128) (result v128) (i32x4.extadd_pairwise_i16x8_s (local.get 0))) + (func (export "i32x4.extadd_pairwise_i16x8_u") (param v128) (result v128) (i32x4.extadd_pairwise_i16x8_u (local.get 0))) +) + + +;; i32x4.extadd_pairwise_i16x8_s +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_s" (v128.const i16x8 0 0 0 0 0 0 0 0)) + (v128.const i32x4 0 0 0 0)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_s" (v128.const i16x8 1 1 1 1 1 1 1 1)) + (v128.const i32x4 2 2 2 2)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_s" (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 -2 -2 -2 -2)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_s" (v128.const i16x8 32766 32766 32766 32766 32766 32766 32766 32766)) + (v128.const i32x4 65532 65532 65532 65532)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_s" (v128.const i16x8 -32767 -32767 -32767 -32767 -32767 -32767 -32767 -32767)) + (v128.const i32x4 -65534 -65534 -65534 -65534)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_s" (v128.const i16x8 -32768 -32768 -32768 -32768 -32768 -32768 -32768 -32768)) + (v128.const i32x4 -65536 -65536 -65536 -65536)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_s" (v128.const i16x8 32767 32767 32767 32767 32767 32767 32767 32767)) + (v128.const i32x4 65534 65534 65534 65534)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_s" (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535)) + (v128.const i32x4 -2 -2 -2 -2)) + +;; i32x4.extadd_pairwise_i16x8_u +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_u" (v128.const i16x8 0 0 0 0 0 0 0 0)) + (v128.const i32x4 0 0 0 0)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_u" (v128.const i16x8 1 1 1 1 1 1 1 1)) + (v128.const i32x4 2 2 2 2)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_u" (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 131070 131070 131070 131070)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_u" (v128.const i16x8 32766 32766 32766 32766 32766 32766 32766 32766)) + (v128.const i32x4 65532 65532 65532 65532)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_u" (v128.const i16x8 -32767 -32767 -32767 -32767 -32767 -32767 -32767 -32767)) + (v128.const i32x4 65538 65538 65538 65538)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_u" (v128.const i16x8 -32768 -32768 -32768 -32768 -32768 -32768 -32768 -32768)) + (v128.const i32x4 65536 65536 65536 65536)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_u" (v128.const i16x8 32767 32767 32767 32767 32767 32767 32767 32767)) + (v128.const i32x4 65534 65534 65534 65534)) +(assert_return (invoke "i32x4.extadd_pairwise_i16x8_u" (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535)) + (v128.const i32x4 131070 131070 131070 131070)) + +;; type check +(assert_invalid (module (func (result v128) (i32x4.extadd_pairwise_i16x8_s (i32.const 0)))) "type mismatch") +(assert_invalid (module (func (result v128) (i32x4.extadd_pairwise_i16x8_u (i32.const 0)))) "type mismatch") + +;; Test operation with empty argument + +(assert_invalid + (module + (func $i32x4.extadd_pairwise_i16x8_s-arg-empty (result v128) + (i32x4.extadd_pairwise_i16x8_s) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func $i32x4.extadd_pairwise_i16x8_u-arg-empty (result v128) + (i32x4.extadd_pairwise_i16x8_u) + ) + ) + "type mismatch" +) +