summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/literal.h1
-rw-r--r--src/wasm/literal.cpp11
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);