Skip to content

Commit

Permalink
SIMD saturating sub implementation. (#747)
Browse files Browse the repository at this point in the history
  • Loading branch information
lizhengxing authored and binji committed Feb 7, 2018
1 parent f0b0677 commit a74072b
Show file tree
Hide file tree
Showing 7 changed files with 1,596 additions and 1,377 deletions.
4 changes: 4 additions & 0 deletions src/binary-reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,10 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) {
case Opcode::I8X16AddSaturateU:
case Opcode::I16X8AddSaturateS:
case Opcode::I16X8AddSaturateU:
case Opcode::I8X16SubSaturateS:
case Opcode::I8X16SubSaturateU:
case Opcode::I16X8SubSaturateS:
case Opcode::I16X8SubSaturateU:
ERROR_UNLESS_OPCODE_ENABLED(opcode);
CALLBACK(OnBinaryExpr, opcode);
CALLBACK0(OnOpcodeBare);
Expand Down
41 changes: 40 additions & 1 deletion src/interp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,21 @@ ValueTypeRep<T> AddSaturate(ValueTypeRep<T> lhs_rep, ValueTypeRep<T> rhs_rep) {
}
}

template <typename T, typename R>
ValueTypeRep<T> SubSaturate(ValueTypeRep<T> lhs_rep, ValueTypeRep<T> rhs_rep) {
T max = std::numeric_limits<R>::max();
T min = std::numeric_limits<R>::min();
T result = static_cast<T>(lhs_rep) - static_cast<T>(rhs_rep);

if(result < min) {
return ToRep(min);
} else if (result > max) {
return ToRep(max);
} else {
return ToRep(result);
}
}

// {i,f}{32,64}.sub
template <typename T>
ValueTypeRep<T> Sub(ValueTypeRep<T> lhs_rep, ValueTypeRep<T> rhs_rep) {
Expand Down Expand Up @@ -2424,6 +2439,22 @@ Result Thread::Run(int num_instructions) {
case Opcode::I16X8AddSaturateU:
CHECK_TRAP(SimdBinop<v128, uint16_t>(AddSaturate<uint32_t, uint16_t>));
break;

case Opcode::I8X16SubSaturateS:
CHECK_TRAP(SimdBinop<v128, int8_t>(SubSaturate<int32_t, int8_t>));
break;

case Opcode::I8X16SubSaturateU:
CHECK_TRAP(SimdBinop<v128, uint8_t>(SubSaturate<int32_t, uint8_t>));
break;

case Opcode::I16X8SubSaturateS:
CHECK_TRAP(SimdBinop<v128, int16_t>(SubSaturate<int32_t, int16_t>));
break;

case Opcode::I16X8SubSaturateU:
CHECK_TRAP(SimdBinop<v128, uint16_t>(SubSaturate<int32_t, uint16_t>));
break;
// The following opcodes are either never generated or should never be
// executed.
case Opcode::Block:
Expand Down Expand Up @@ -2914,7 +2945,11 @@ void Thread::Trace(Stream* stream) {
case Opcode::I8X16AddSaturateS:
case Opcode::I8X16AddSaturateU:
case Opcode::I16X8AddSaturateS:
case Opcode::I16X8AddSaturateU: {
case Opcode::I16X8AddSaturateU:
case Opcode::I8X16SubSaturateS:
case Opcode::I8X16SubSaturateU:
case Opcode::I16X8SubSaturateS:
case Opcode::I16X8SubSaturateU: {
stream->Writef("%s $0x%08x %08x %08x %08x $0x%08x %08x %08x %08x\n", opcode.GetName(), Pick(2).v128_bits.v[0],
Pick(2).v128_bits.v[1], Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3],Pick(1).v128_bits.v[0],
Pick(1).v128_bits.v[1], Pick(1).v128_bits.v[2], Pick(1).v128_bits.v[3]);
Expand Down Expand Up @@ -3233,6 +3268,10 @@ void Environment::Disassemble(Stream* stream,
case Opcode::I8X16AddSaturateU:
case Opcode::I16X8AddSaturateS:
case Opcode::I16X8AddSaturateU:
case Opcode::I8X16SubSaturateS:
case Opcode::I8X16SubSaturateU:
case Opcode::I16X8SubSaturateS:
case Opcode::I16X8SubSaturateU:
stream->Writef("%s %%[-2], %%[-1]\n", opcode.GetName());
break;

Expand Down
4 changes: 4 additions & 0 deletions src/opcode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ bool Opcode::IsEnabled(const Features& features) const {
case Opcode::I8X16AddSaturateU:
case Opcode::I16X8AddSaturateS:
case Opcode::I16X8AddSaturateU:
case Opcode::I8X16SubSaturateS:
case Opcode::I8X16SubSaturateU:
case Opcode::I16X8SubSaturateS:
case Opcode::I16X8SubSaturateU:
return features.simd_enabled();

// Interpreter opcodes are never "enabled".
Expand Down
4 changes: 4 additions & 0 deletions src/opcode.def
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x27, I8X16AddSaturateS, "i8x16.add
WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x28, I8X16AddSaturateU, "i8x16.add_saturate_u")
WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x29, I16X8AddSaturateS, "i16x8.add_saturate_s")
WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x2a, I16X8AddSaturateU, "i16x8.add_saturate_u")
WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x2b, I8X16SubSaturateS, "i8x16.sub_saturate_s")
WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x2c, I8X16SubSaturateU, "i8x16.sub_saturate_u")
WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x2d, I16X8SubSaturateS, "i16x8.sub_saturate_s")
WABT_OPCODE(V128, V128, V128, ___, 0, 0xfd, 0x2e, I16X8SubSaturateU, "i16x8.sub_saturate_u")


WABT_OPCODE(I32, I32, I32, ___, 4, 0xfe, 0x00, AtomicWake, "atomic.wake")
Expand Down
Loading

0 comments on commit a74072b

Please sign in to comment.