summaryrefslogtreecommitdiff
path: root/src/interp
diff options
context:
space:
mode:
authorBen Smith <binji@chromium.org>2020-08-31 10:08:33 -0700
committerGitHub <noreply@github.com>2020-08-31 10:08:33 -0700
commitc3b9c32b6165295c536e5884dfcfe8e4bdf7a811 (patch)
treeac4a91256da650a5ec1ba6a072d4c7c9b545a0a7 /src/interp
parentca7890a54b76628327623553cbe34552b5fc53a5 (diff)
downloadwabt-c3b9c32b6165295c536e5884dfcfe8e4bdf7a811.tar.gz
wabt-c3b9c32b6165295c536e5884dfcfe8e4bdf7a811.tar.bz2
wabt-c3b9c32b6165295c536e5884dfcfe8e4bdf7a811.zip
Implement simd bitmask instructions (#1530)
Diffstat (limited to 'src/interp')
-rw-r--r--src/interp/interp.cc16
-rw-r--r--src/interp/interp.h2
-rw-r--r--src/interp/istream.cc3
3 files changed, 21 insertions, 0 deletions
diff --git a/src/interp/interp.cc b/src/interp/interp.cc
index 5e5a6648..3beedcf8 100644
--- a/src/interp/interp.cc
+++ b/src/interp/interp.cc
@@ -1497,6 +1497,7 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) {
case O::I8X16Neg: return DoSimdUnop(IntNeg<u8>);
case O::I8X16AnyTrue: return DoSimdIsTrue<u8x16, 1>();
+ case O::I8X16Bitmask: return DoSimdBitmask<s8x16>();
case O::I8X16AllTrue: return DoSimdIsTrue<u8x16, 16>();
case O::I8X16Shl: return DoSimdShift(IntShl<u8>);
case O::I8X16ShrS: return DoSimdShift(IntShr<s8>);
@@ -1514,6 +1515,7 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) {
case O::I16X8Neg: return DoSimdUnop(IntNeg<u16>);
case O::I16X8AnyTrue: return DoSimdIsTrue<u16x8, 1>();
+ case O::I16X8Bitmask: return DoSimdBitmask<s16x8>();
case O::I16X8AllTrue: return DoSimdIsTrue<u16x8, 8>();
case O::I16X8Shl: return DoSimdShift(IntShl<u16>);
case O::I16X8ShrS: return DoSimdShift(IntShr<s16>);
@@ -1532,6 +1534,7 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) {
case O::I32X4Neg: return DoSimdUnop(IntNeg<u32>);
case O::I32X4AnyTrue: return DoSimdIsTrue<u32x4, 1>();
+ case O::I32X4Bitmask: return DoSimdBitmask<s32x4>();
case O::I32X4AllTrue: return DoSimdIsTrue<u32x4, 4>();
case O::I32X4Shl: return DoSimdShift(IntShl<u32>);
case O::I32X4ShrS: return DoSimdShift(IntShr<s32>);
@@ -2022,6 +2025,19 @@ RunResult Thread::DoSimdIsTrue() {
return RunResult::Ok;
}
+template <typename S>
+RunResult Thread::DoSimdBitmask() {
+ auto val = Pop<S>();
+ u32 result = 0;
+ for (u8 i = 0; i < S::lanes; ++i) {
+ if (val.v[i] < 0) {
+ result |= 1 << i;
+ }
+ }
+ Push(result);
+ return RunResult::Ok;
+}
+
template <typename R, typename T>
RunResult Thread::DoSimdShift(BinopFunc<R, T> f) {
using ST = typename Simd128<T>::Type;
diff --git a/src/interp/interp.h b/src/interp/interp.h
index 5dfd42a9..32f6a73e 100644
--- a/src/interp/interp.h
+++ b/src/interp/interp.h
@@ -1129,6 +1129,8 @@ class Thread : public Object {
RunResult DoSimdBitSelect();
template <typename S, u8 count>
RunResult DoSimdIsTrue();
+ template <typename S>
+ RunResult DoSimdBitmask();
template <typename R, typename T>
RunResult DoSimdShift(BinopFunc<R, T>);
template <typename S, typename T>
diff --git a/src/interp/istream.cc b/src/interp/istream.cc
index 1063a37b..619a9844 100644
--- a/src/interp/istream.cc
+++ b/src/interp/istream.cc
@@ -154,6 +154,7 @@ Instr Istream::Read(Offset* offset) const {
case Opcode::F64X2Sqrt:
case Opcode::I16X8AllTrue:
case Opcode::I16X8AnyTrue:
+ case Opcode::I16X8Bitmask:
case Opcode::I16X8Neg:
case Opcode::I16X8Splat:
case Opcode::I16X8WidenHighI8X16S:
@@ -178,6 +179,7 @@ Instr Istream::Read(Offset* offset) const {
case Opcode::I32WrapI64:
case Opcode::I32X4AllTrue:
case Opcode::I32X4AnyTrue:
+ case Opcode::I32X4Bitmask:
case Opcode::I32X4Neg:
case Opcode::I32X4Splat:
case Opcode::I32X4TruncSatF32X4S:
@@ -208,6 +210,7 @@ Instr Istream::Read(Offset* offset) const {
case Opcode::I64X2Splat:
case Opcode::I8X16AllTrue:
case Opcode::I8X16AnyTrue:
+ case Opcode::I8X16Bitmask:
case Opcode::I8X16Neg:
case Opcode::I8X16Splat:
case Opcode::RefIsNull: