From 03ae7fcbfc5cedefd25c2414616cb1d3f77ab51b Mon Sep 17 00:00:00 2001 From: Thomas Lively <7121787+tlively@users.noreply.github.com> Date: Fri, 20 Mar 2020 16:31:16 -0700 Subject: SIMD integer abs and bitmask instructions (#2703) Adds full support for the {i8x16,i16x8,i32x4}.abs instructions merged to the SIMD proposal in https://github.com/WebAssembly/simd/pull/128 as well as the {i8x16,i16x8,i32x4}.bitmask instructions proposed in https://github.com/WebAssembly/simd/pull/201. --- src/wasm/literal.cpp | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'src/wasm/literal.cpp') diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index aa2acdcc1..b740ae520 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -565,9 +565,9 @@ Literal Literal::neg() const { Literal Literal::abs() const { switch (type.getSingle()) { case Type::i32: - return Literal(i32 & 0x7fffffff); + return Literal(std::abs(i32)); case Type::i64: - return Literal(int64_t(i64 & 0x7fffffffffffffffULL)); + return Literal(std::abs(i64)); case Type::f32: return Literal(i32 & 0x7fffffff).castToF32(); case Type::f64: @@ -1442,6 +1442,15 @@ Literal Literal::notV128() const { ones.fill(0xff); return xorV128(Literal(ones.data())); } +Literal Literal::absI8x16() const { + return unary<16, &Literal::getLanesSI8x16, &Literal::abs>(*this); +} +Literal Literal::absI16x8() const { + return unary<8, &Literal::getLanesSI16x8, &Literal::abs>(*this); +} +Literal Literal::absI32x4() const { + return unary<4, &Literal::getLanesI32x4, &Literal::abs>(*this); +} Literal Literal::negI8x16() const { return unary<16, &Literal::getLanesUI8x16, &Literal::neg>(*this); } @@ -1519,24 +1528,45 @@ static Literal all_true(const Literal& val) { return Literal(int32_t(1)); } +template (Literal::*IntoLanes)() const> +static Literal bitmask(const Literal& val) { + uint32_t result = 0; + LaneArray lanes = (val.*IntoLanes)(); + for (size_t i = 0; i < Lanes; ++i) { + if (lanes[i].geti32() & (1 << 31)) { + result = result | (1 << i); + } + } + return Literal(result); +} + Literal Literal::anyTrueI8x16() const { return any_true<16, &Literal::getLanesUI8x16>(*this); } Literal Literal::allTrueI8x16() const { return all_true<16, &Literal::getLanesUI8x16>(*this); } +Literal Literal::bitmaskI8x16() const { + return bitmask<16, &Literal::getLanesSI8x16>(*this); +} Literal Literal::anyTrueI16x8() const { return any_true<8, &Literal::getLanesUI16x8>(*this); } Literal Literal::allTrueI16x8() const { return all_true<8, &Literal::getLanesUI16x8>(*this); } +Literal Literal::bitmaskI16x8() const { + return bitmask<8, &Literal::getLanesSI16x8>(*this); +} Literal Literal::anyTrueI32x4() const { return any_true<4, &Literal::getLanesI32x4>(*this); } Literal Literal::allTrueI32x4() const { return all_true<4, &Literal::getLanesI32x4>(*this); } +Literal Literal::bitmaskI32x4() const { + return bitmask<4, &Literal::getLanesI32x4>(*this); +} Literal Literal::anyTrueI64x2() const { return any_true<2, &Literal::getLanesI64x2>(*this); } -- cgit v1.2.3