diff options
author | Max Graey <maxgraey@gmail.com> | 2021-07-15 00:25:39 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-14 14:25:39 -0700 |
commit | b842715392a6e18cfae6bdabce670a1d618611fc (patch) | |
tree | 3af0c298979293a822e0f1c0dc178b2c1a3ce127 | |
parent | b68691e826a46d1b03b27c552b1f5b7f51f92665 (diff) | |
download | binaryen-b842715392a6e18cfae6bdabce670a1d618611fc.tar.gz binaryen-b842715392a6e18cfae6bdabce670a1d618611fc.tar.bz2 binaryen-b842715392a6e18cfae6bdabce670a1d618611fc.zip |
Implement q15MulrSatSI16x8 for interpreter (#3984)
-rw-r--r-- | src/literal.h | 1 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 11 | ||||
-rw-r--r-- | test/spec/simd.wast | 9 |
3 files changed, 19 insertions, 2 deletions
diff --git a/src/literal.h b/src/literal.h index 965ec157c..0b1b6fa90 100644 --- a/src/literal.h +++ b/src/literal.h @@ -644,6 +644,7 @@ private: Literal subSatUI8(const Literal& other) const; Literal subSatSI16(const Literal& other) const; Literal subSatUI16(const Literal& other) const; + Literal q15MulrSatSI16(const Literal& other) const; Literal minInt(const Literal& other) const; Literal maxInt(const Literal& other) const; Literal minUInt(const Literal& other) const; diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index c3a2ddf7a..afaafe5e4 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -1070,6 +1070,14 @@ Literal Literal::subSatUI16(const Literal& other) const { return Literal(sub_sat_u<uint16_t>(geti32(), other.geti32())); } +Literal Literal::q15MulrSatSI16(const Literal& other) const { + int64_t value = + (int64_t(geti32()) * int64_t(other.geti32()) + 0x4000LL) >> 15LL; + int64_t lower = std::numeric_limits<int16_t>::min(); + int64_t upper = std::numeric_limits<int16_t>::max(); + return Literal(int16_t(std::min(std::max(value, lower), upper))); +} + Literal Literal::mul(const Literal& other) const { switch (type.getBasic()) { case Type::i32: @@ -2201,7 +2209,8 @@ Literal Literal::avgrUI16x8(const Literal& other) const { return binary<8, &Literal::getLanesUI16x8, &Literal::avgrUInt>(*this, other); } Literal Literal::q15MulrSatSI16x8(const Literal& other) const { - WASM_UNREACHABLE("TODO: implement Q15 rounding, saturating multiplication"); + return binary<8, &Literal::getLanesSI16x8, &Literal::q15MulrSatSI16>(*this, + other); } Literal Literal::addI32x4(const Literal& other) const { return binary<4, &Literal::getLanesI32x4, &Literal::add>(*this, other); diff --git a/test/spec/simd.wast b/test/spec/simd.wast index 0eda03fc5..9a76fec3b 100644 --- a/test/spec/simd.wast +++ b/test/spec/simd.wast @@ -151,7 +151,7 @@ (func (export "i16x8.max_s") (param $0 v128) (param $1 v128) (result v128) (i16x8.max_s (local.get $0) (local.get $1))) (func (export "i16x8.max_u") (param $0 v128) (param $1 v128) (result v128) (i16x8.max_u (local.get $0) (local.get $1))) (func (export "i16x8.avgr_u") (param $0 v128) (param $1 v128) (result v128) (i16x8.avgr_u (local.get $0) (local.get $1))) - ;; TODO: Q15 rounding, saturating multiplication + (func (export "i16x8.q15mulr_sat_s") (param $0 v128) (param $1 v128) (result v128) (i16x8.q15mulr_sat_s (local.get $0) (local.get $1))) ;; TODO: extending multiplications (func (export "i32x4.abs") (param $0 v128) (result v128) (i32x4.abs (local.get $0))) (func (export "i32x4.neg") (param $0 v128) (result v128) (i32x4.neg (local.get $0))) @@ -783,6 +783,13 @@ ) (v128.const i16x8 384 32641 32768 32768 17280 38912 64640 16384) ) +(assert_return + (invoke "i16x8.q15mulr_sat_s" + (v128.const i16x8 -1 -16383 32765 65535 -32768 65535 -16385 -32768) + (v128.const i16x8 -1 -16384 1 -32768 -32768 1 -16384 -1) + ) + (v128.const i16x8 0 8192 1 1 32767 0 8193 1) +) ;; i32x4 arithmetic (assert_return (invoke "i32x4.abs" (v128.const i32x4 0 1 0x80000000 0x80000001)) (v128.const i32x4 0 1 0x80000000 0x7fffffff)) |