diff options
author | Max Graey <maxgraey@gmail.com> | 2021-07-28 22:09:01 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-28 12:09:01 -0700 |
commit | 5aab7956eab367c12af1aadb052f67f40667e3ef (patch) | |
tree | 896e696a819289f559aa02da6429658787f4d0e4 /src/wasm/literal.cpp | |
parent | 8670f15676b3c6406d6e82327a7258c7c4d08b43 (diff) | |
download | binaryen-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.cpp | 48 |
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(); |