summaryrefslogtreecommitdiff
path: root/src/wasm/literal.cpp
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2021-07-28 22:09:01 +0300
committerGitHub <noreply@github.com>2021-07-28 12:09:01 -0700
commit5aab7956eab367c12af1aadb052f67f40667e3ef (patch)
tree896e696a819289f559aa02da6429658787f4d0e4 /src/wasm/literal.cpp
parent8670f15676b3c6406d6e82327a7258c7c4d08b43 (diff)
downloadbinaryen-5aab7956eab367c12af1aadb052f67f40667e3ef.tar.gz
binaryen-5aab7956eab367c12af1aadb052f67f40667e3ef.tar.bz2
binaryen-5aab7956eab367c12af1aadb052f67f40667e3ef.zip
[Simd] Implement extra convert, trunc, demote and promote ops for interpreter (#4023)
Diffstat (limited to 'src/wasm/literal.cpp')
-rw-r--r--src/wasm/literal.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index b6618219d..c7a9ca844 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -2388,6 +2388,16 @@ Literal extend(const Literal& vec) {
return Literal(result);
}
+template<LaneOrder Side> Literal extendF32(const Literal& vec) {
+ LaneArray<4> lanes = vec.getLanesF32x4();
+ LaneArray<2> result;
+ for (size_t i = 0; i < 2; ++i) {
+ size_t idx = (Side == LaneOrder::Low) ? i : i + 2;
+ result[i] = Literal((double)lanes[idx].getf32());
+ }
+ return Literal(result);
+}
+
Literal Literal::extendLowSToI16x8() const {
return extend<8, int8_t, int16_t, LaneOrder::Low>(*this);
}
@@ -2475,6 +2485,44 @@ Literal Literal::extMulHighUI64x2(const Literal& other) const {
return extMul<2, uint32_t, uint64_t, LaneOrder::High>(*this, other);
}
+Literal Literal::convertLowSToF64x2() const {
+ return extend<2, int32_t, double, LaneOrder::Low>(*this);
+}
+Literal Literal::convertLowUToF64x2() const {
+ return extend<2, uint32_t, double, LaneOrder::Low>(*this);
+}
+
+template<int Lanes,
+ LaneArray<Lanes / 2> (Literal::*IntoLanes)() const,
+ Literal (Literal::*UnaryOp)(void) const>
+static Literal unary_zero(const Literal& val) {
+ LaneArray<Lanes / 2> lanes = (val.*IntoLanes)();
+ LaneArray<Lanes> result;
+ for (size_t i = 0; i < Lanes / 2; ++i) {
+ result[i] = (lanes[i].*UnaryOp)();
+ }
+ for (size_t i = Lanes / 2; i < Lanes; ++i) {
+ result[i] = Literal::makeZero(lanes[0].type);
+ }
+ return Literal(result);
+}
+
+Literal Literal::truncSatZeroSToI32x4() const {
+ return unary_zero<4, &Literal::getLanesF64x2, &Literal::truncSatToSI32>(
+ *this);
+}
+Literal Literal::truncSatZeroUToI32x4() const {
+ return unary_zero<4, &Literal::getLanesF64x2, &Literal::truncSatToUI32>(
+ *this);
+}
+
+Literal Literal::demoteZeroToF32x4() const {
+ return unary_zero<4, &Literal::getLanesF64x2, &Literal::demote>(*this);
+}
+Literal Literal::promoteLowToF64x2() const {
+ return extendF32<LaneOrder::Low>(*this);
+}
+
Literal Literal::swizzleI8x16(const Literal& other) const {
auto lanes = getLanesUI8x16();
auto indices = other.getLanesUI8x16();