diff options
author | Ben Smith <binji@chromium.org> | 2020-08-31 10:08:33 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-31 10:08:33 -0700 |
commit | c3b9c32b6165295c536e5884dfcfe8e4bdf7a811 (patch) | |
tree | ac4a91256da650a5ec1ba6a072d4c7c9b545a0a7 /src/interp | |
parent | ca7890a54b76628327623553cbe34552b5fc53a5 (diff) | |
download | wabt-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.cc | 16 | ||||
-rw-r--r-- | src/interp/interp.h | 2 | ||||
-rw-r--r-- | src/interp/istream.cc | 3 |
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: |