summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/literal.h4
-rw-r--r--src/wasm-interpreter.h8
-rw-r--r--src/wasm/literal.cpp25
-rw-r--r--test/spec/simd.wast30
4 files changed, 62 insertions, 5 deletions
diff --git a/src/literal.h b/src/literal.h
index 28e6f03cf..3d4562f77 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -612,6 +612,10 @@ public:
Literal floorF64x2() const;
Literal truncF64x2() const;
Literal nearestF64x2() const;
+ Literal extAddPairwiseToSI16x8() const;
+ Literal extAddPairwiseToUI16x8() const;
+ Literal extAddPairwiseToSI32x4() const;
+ Literal extAddPairwiseToUI32x4() const;
Literal truncSatToSI32x4() const;
Literal truncSatToUI32x4() const;
Literal convertSToF32x4() const;
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 872d90603..13a3f2876 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -530,13 +530,13 @@ public:
case NearestVecF64x2:
return value.nearestF64x2();
case ExtAddPairwiseSVecI8x16ToI16x8:
- WASM_UNREACHABLE("unimp");
+ return value.extAddPairwiseToSI16x8();
case ExtAddPairwiseUVecI8x16ToI16x8:
- WASM_UNREACHABLE("unimp");
+ return value.extAddPairwiseToUI16x8();
case ExtAddPairwiseSVecI16x8ToI32x4:
- WASM_UNREACHABLE("unimp");
+ return value.extAddPairwiseToSI32x4();
case ExtAddPairwiseUVecI16x8ToI32x4:
- WASM_UNREACHABLE("unimp");
+ return value.extAddPairwiseToUI32x4();
case TruncSatSVecF32x4ToVecI32x4:
return value.truncSatToSI32x4();
case TruncSatUVecF32x4ToVecI32x4:
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 7e36097c2..9b2171a74 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -1809,6 +1809,31 @@ Literal Literal::truncF64x2() const {
Literal Literal::nearestF64x2() const {
return unary<2, &Literal::getLanesF64x2, &Literal::nearbyint>(*this);
}
+
+template<int Lanes, typename LaneFrom, typename LaneTo>
+static Literal extAddPairwise(const Literal& vec) {
+ LaneArray<Lanes* 2> lanes = getLanes<LaneFrom, Lanes * 2>(vec);
+ LaneArray<Lanes> result;
+ for (size_t i = 0; i < Lanes; i++) {
+ result[i] = Literal((LaneTo)(LaneFrom)lanes[i * 2 + 0].geti32() +
+ (LaneTo)(LaneFrom)lanes[i * 2 + 1].geti32());
+ }
+ return Literal(result);
+}
+
+Literal Literal::extAddPairwiseToSI16x8() const {
+ return extAddPairwise<8, int8_t, int16_t>(*this);
+}
+Literal Literal::extAddPairwiseToUI16x8() const {
+ return extAddPairwise<8, uint8_t, int16_t>(*this);
+}
+Literal Literal::extAddPairwiseToSI32x4() const {
+ return extAddPairwise<4, int16_t, int32_t>(*this);
+}
+Literal Literal::extAddPairwiseToUI32x4() const {
+ return extAddPairwise<4, uint16_t, uint32_t>(*this);
+}
+
Literal Literal::truncSatToSI32x4() const {
return unary<4, &Literal::getLanesF32x4, &Literal::truncSatToSI32>(*this);
}
diff --git a/test/spec/simd.wast b/test/spec/simd.wast
index aa9ed48ba..d246cfdd0 100644
--- a/test/spec/simd.wast
+++ b/test/spec/simd.wast
@@ -217,7 +217,10 @@
(func (export "f64x2.floor") (param $0 v128) (result v128) (f64x2.floor (local.get $0)))
(func (export "f64x2.trunc") (param $0 v128) (result v128) (f64x2.trunc (local.get $0)))
(func (export "f64x2.nearest") (param $0 v128) (result v128) (f64x2.nearest (local.get $0)))
- ;; TODO: Extending pairwise adds once they have interpreter support
+ (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)))
+ (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)))
(func (export "i32x4.trunc_sat_f32x4_s") (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_s (local.get $0)))
(func (export "i32x4.trunc_sat_f32x4_u") (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_u (local.get $0)))
(func (export "f32x4.convert_i32x4_s") (param $0 v128) (result v128) (f32x4.convert_i32x4_s (local.get $0)))
@@ -1015,6 +1018,31 @@
(assert_return (invoke "f64x2.nearest" (v128.const f64x2 1.5 -1.5)) (v128.const f64x2 2 -2))
(assert_return (invoke "f64x2.nearest" (v128.const f64x2 4.2 -4.2)) (v128.const f64x2 4 -4))
+(assert_return
+ (invoke "i16x8.extadd_pairwise_i8x16_s"
+ (v128.const i8x16 -1 -1 -127 -127 -128 -128 127 127 255 255 1 1 0 0 126 126)
+ )
+ (v128.const i16x8 -2 -254 -256 254 -2 2 0 252)
+)
+(assert_return
+ (invoke "i16x8.extadd_pairwise_i8x16_u"
+ (v128.const i8x16 0 0 1 1 -1 -1 126 126 -127 -127 -128 -128 127 127 255 255)
+ )
+ (v128.const i16x8 0 2 510 252 258 256 254 510)
+)
+(assert_return
+ (invoke "i32x4.extadd_pairwise_i16x8_s"
+ (v128.const i16x8 32766 32766 -32767 -32767 65535 65535 -1 -1)
+ )
+ (v128.const i32x4 65532 -65534 -2 -2)
+)
+(assert_return
+ (invoke "i32x4.extadd_pairwise_i16x8_u"
+ (v128.const i16x8 -1 -1 -32767 -32767 -32768 -32768 65535 65535)
+ )
+ (v128.const i32x4 131070 65538 65536 131070)
+)
+
;; conversions
(assert_return (invoke "i32x4.trunc_sat_f32x4_s" (v128.const f32x4 42 nan infinity -infinity)) (v128.const i32x4 42 0 2147483647 -2147483648))
(assert_return (invoke "i32x4.trunc_sat_f32x4_u" (v128.const f32x4 42 nan infinity -infinity)) (v128.const i32x4 42 0 4294967295 0))