diff options
author | Ben Smith <binji@chromium.org> | 2020-03-27 14:50:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-27 14:50:35 -0700 |
commit | ae2140ddc6969ef53599fe2fab81818de65db875 (patch) | |
tree | a65f32e9504e5d907be2d2ea50c148a23831d773 /src/interp | |
parent | 1f397a3c829869f23ae0ff3e311d22f12d8c72a9 (diff) | |
download | wabt-ae2140ddc6969ef53599fe2fab81818de65db875.tar.gz wabt-ae2140ddc6969ef53599fe2fab81818de65db875.tar.bz2 wabt-ae2140ddc6969ef53599fe2fab81818de65db875.zip |
Update testsuite (#1381)
* Add i{8x16,16x8,32x4}.abs instructions
* Implement IntAbs in interp-math.h
Diffstat (limited to 'src/interp')
-rw-r--r-- | src/interp/interp-math.h | 12 | ||||
-rw-r--r-- | src/interp/interp.cc | 4 | ||||
-rw-r--r-- | src/interp/istream.cc | 3 |
3 files changed, 19 insertions, 0 deletions
diff --git a/src/interp/interp-math.h b/src/interp/interp-math.h index c3876810..f0ff96ef 100644 --- a/src/interp/interp-math.h +++ b/src/interp/interp-math.h @@ -91,6 +91,18 @@ template <typename T> T WABT_VECTORCALL IntAndNot(T lhs, T rhs) { return lhs & ~ template <typename T> T WABT_VECTORCALL IntAvgr(T lhs, T rhs) { return (lhs + rhs + 1) / 2; } template <typename T> T WABT_VECTORCALL Xchg(T lhs, T rhs) { return rhs; } +// This is a wrapping absolute value function, so a negative number that is not +// representable as a positive number will be unchanged (e.g. abs(-128) = 128). +// +// Note that std::abs() does not have this behavior (e.g. abs(-128) is UB). +// Similarly, using unary minus is also UB. +template <typename T> +T WABT_VECTORCALL IntAbs(T val) { + static_assert(std::is_unsigned<T>::value, "T must be unsigned."); + const auto signbit = T(-1) << (sizeof(T) * 8 - 1); + return (val & signbit) ? ~val + 1 : val; +} + // Because of the integer promotion rules [1], any value of a type T which is // smaller than `int` will be converted to an `int`, as long as `int` can hold // any value of type T. diff --git a/src/interp/interp.cc b/src/interp/interp.cc index 672f5a4f..57b0750f 100644 --- a/src/interp/interp.cc +++ b/src/interp/interp.cc @@ -1603,6 +1603,10 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) { case O::I8X16AvgrU: return DoSimdBinop(IntAvgr<u8>); case O::I16X8AvgrU: return DoSimdBinop(IntAvgr<u16>); + case O::I8X16Abs: return DoSimdUnop(IntAbs<u8>); + case O::I16X8Abs: return DoSimdUnop(IntAbs<u16>); + case O::I32X4Abs: return DoSimdUnop(IntAbs<u32>); + case O::AtomicNotify: case O::I32AtomicWait: case O::I64AtomicWait: diff --git a/src/interp/istream.cc b/src/interp/istream.cc index a45eb57a..ad92ce97 100644 --- a/src/interp/istream.cc +++ b/src/interp/istream.cc @@ -212,6 +212,9 @@ Instr Istream::Read(Offset* offset) const { case Opcode::I8X16Splat: case Opcode::RefIsNull: case Opcode::V128Not: + case Opcode::I8X16Abs: + case Opcode::I16X8Abs: + case Opcode::I32X4Abs: // 0 immediates, 1 operand. instr.kind = InstrKind::Imm_0_Op_1; break; |