diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/literal.h | 1 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 11 |
2 files changed, 11 insertions, 1 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); |