summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interp/interp.cc112
-rw-r--r--src/interp/interp.h3
2 files changed, 73 insertions, 42 deletions
diff --git a/src/interp/interp.cc b/src/interp/interp.cc
index f44c4021..822f003d 100644
--- a/src/interp/interp.cc
+++ b/src/interp/interp.cc
@@ -965,6 +965,34 @@ Result Thread::SimdBinop(BinopFunc<R, P> func) {
return PushRep<T>(Bitcast<T>(simd_data_ret));
}
+// {i8, i16, 132, i64, f32, f64}{16, 8, 4, 2}.(eq/ne/lt/le/gt/ge)
+template <typename T, typename L, typename R, typename P>
+Result Thread::SimdRelBinop(BinopFunc<R, P> func) {
+ auto rhs_rep = PopRep<T>();
+ auto lhs_rep = PopRep<T>();
+
+ // Calculate how many Lanes according to input lane data type.
+ constexpr int32_t lanes = sizeof(T) / sizeof(L);
+
+ // Define SIMD data array for Simd add by Lanes.
+ L simd_data_ret[lanes];
+ L simd_data_0[lanes];
+ L simd_data_1[lanes];
+
+ // Convert intput SIMD data to array.
+ memcpy(simd_data_0, &lhs_rep, sizeof(T));
+ memcpy(simd_data_1, &rhs_rep, sizeof(T));
+
+ // Constuct the Simd value by Lane data and Lane nums.
+ for (int32_t i = 0; i < lanes; i++) {
+ simd_data_ret[i] = static_cast<L>(
+ func(simd_data_0[i], simd_data_1[i]) == 0? 0 : -1
+ );
+ }
+
+ return PushRep<T>(Bitcast<T>(simd_data_ret));
+}
+
template <typename R, typename T>
Result Thread::BinopTrap(BinopTrapFunc<R, T> func) {
auto rhs_rep = PopRep<T>();
@@ -2970,171 +2998,171 @@ Result Thread::Run(int num_instructions) {
}
case Opcode::I8X16Eq:
- CHECK_TRAP(SimdBinop<v128, int8_t>(Eq<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int8_t>(Eq<int32_t>));
break;
case Opcode::I16X8Eq:
- CHECK_TRAP(SimdBinop<v128, int16_t>(Eq<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int16_t>(Eq<int32_t>));
break;
case Opcode::I32X4Eq:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Eq<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Eq<int32_t>));
break;
case Opcode::F32X4Eq:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Eq<float>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Eq<float>));
break;
case Opcode::F64X2Eq:
- CHECK_TRAP(SimdBinop<v128, int64_t>(Eq<double>));
+ CHECK_TRAP(SimdRelBinop<v128, int64_t>(Eq<double>));
break;
case Opcode::I8X16Ne:
- CHECK_TRAP(SimdBinop<v128, int8_t>(Ne<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int8_t>(Ne<int32_t>));
break;
case Opcode::I16X8Ne:
- CHECK_TRAP(SimdBinop<v128, int16_t>(Ne<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int16_t>(Ne<int32_t>));
break;
case Opcode::I32X4Ne:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Ne<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Ne<int32_t>));
break;
case Opcode::F32X4Ne:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Ne<float>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Ne<float>));
break;
case Opcode::F64X2Ne:
- CHECK_TRAP(SimdBinop<v128, int64_t>(Ne<double>));
+ CHECK_TRAP(SimdRelBinop<v128, int64_t>(Ne<double>));
break;
case Opcode::I8X16LtS:
- CHECK_TRAP(SimdBinop<v128, int8_t>(Lt<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int8_t>(Lt<int32_t>));
break;
case Opcode::I8X16LtU:
- CHECK_TRAP(SimdBinop<v128, uint8_t>(Lt<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint8_t>(Lt<uint32_t>));
break;
case Opcode::I16X8LtS:
- CHECK_TRAP(SimdBinop<v128, int16_t>(Lt<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int16_t>(Lt<int32_t>));
break;
case Opcode::I16X8LtU:
- CHECK_TRAP(SimdBinop<v128, uint16_t>(Lt<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint16_t>(Lt<uint32_t>));
break;
case Opcode::I32X4LtS:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Lt<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Lt<int32_t>));
break;
case Opcode::I32X4LtU:
- CHECK_TRAP(SimdBinop<v128, uint32_t>(Lt<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint32_t>(Lt<uint32_t>));
break;
case Opcode::F32X4Lt:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Lt<float>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Lt<float>));
break;
case Opcode::F64X2Lt:
- CHECK_TRAP(SimdBinop<v128, int64_t>(Lt<double>));
+ CHECK_TRAP(SimdRelBinop<v128, int64_t>(Lt<double>));
break;
case Opcode::I8X16LeS:
- CHECK_TRAP(SimdBinop<v128, int8_t>(Le<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int8_t>(Le<int32_t>));
break;
case Opcode::I8X16LeU:
- CHECK_TRAP(SimdBinop<v128, uint8_t>(Le<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint8_t>(Le<uint32_t>));
break;
case Opcode::I16X8LeS:
- CHECK_TRAP(SimdBinop<v128, int16_t>(Le<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int16_t>(Le<int32_t>));
break;
case Opcode::I16X8LeU:
- CHECK_TRAP(SimdBinop<v128, uint16_t>(Le<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint16_t>(Le<uint32_t>));
break;
case Opcode::I32X4LeS:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Le<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Le<int32_t>));
break;
case Opcode::I32X4LeU:
- CHECK_TRAP(SimdBinop<v128, uint32_t>(Le<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint32_t>(Le<uint32_t>));
break;
case Opcode::F32X4Le:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Le<float>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Le<float>));
break;
case Opcode::F64X2Le:
- CHECK_TRAP(SimdBinop<v128, int64_t>(Le<double>));
+ CHECK_TRAP(SimdRelBinop<v128, int64_t>(Le<double>));
break;
case Opcode::I8X16GtS:
- CHECK_TRAP(SimdBinop<v128, int8_t>(Gt<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int8_t>(Gt<int32_t>));
break;
case Opcode::I8X16GtU:
- CHECK_TRAP(SimdBinop<v128, uint8_t>(Gt<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint8_t>(Gt<uint32_t>));
break;
case Opcode::I16X8GtS:
- CHECK_TRAP(SimdBinop<v128, int16_t>(Gt<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int16_t>(Gt<int32_t>));
break;
case Opcode::I16X8GtU:
- CHECK_TRAP(SimdBinop<v128, uint16_t>(Gt<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint16_t>(Gt<uint32_t>));
break;
case Opcode::I32X4GtS:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Gt<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Gt<int32_t>));
break;
case Opcode::I32X4GtU:
- CHECK_TRAP(SimdBinop<v128, uint32_t>(Gt<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint32_t>(Gt<uint32_t>));
break;
case Opcode::F32X4Gt:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Gt<float>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Gt<float>));
break;
case Opcode::F64X2Gt:
- CHECK_TRAP(SimdBinop<v128, int64_t>(Gt<double>));
+ CHECK_TRAP(SimdRelBinop<v128, int64_t>(Gt<double>));
break;
case Opcode::I8X16GeS:
- CHECK_TRAP(SimdBinop<v128, int8_t>(Ge<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int8_t>(Ge<int32_t>));
break;
case Opcode::I8X16GeU:
- CHECK_TRAP(SimdBinop<v128, uint8_t>(Ge<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint8_t>(Ge<uint32_t>));
break;
case Opcode::I16X8GeS:
- CHECK_TRAP(SimdBinop<v128, int16_t>(Ge<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int16_t>(Ge<int32_t>));
break;
case Opcode::I16X8GeU:
- CHECK_TRAP(SimdBinop<v128, uint16_t>(Ge<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint16_t>(Ge<uint32_t>));
break;
case Opcode::I32X4GeS:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Ge<int32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Ge<int32_t>));
break;
case Opcode::I32X4GeU:
- CHECK_TRAP(SimdBinop<v128, uint32_t>(Ge<uint32_t>));
+ CHECK_TRAP(SimdRelBinop<v128, uint32_t>(Ge<uint32_t>));
break;
case Opcode::F32X4Ge:
- CHECK_TRAP(SimdBinop<v128, int32_t>(Ge<float>));
+ CHECK_TRAP(SimdRelBinop<v128, int32_t>(Ge<float>));
break;
case Opcode::F64X2Ge:
- CHECK_TRAP(SimdBinop<v128, int64_t>(Ge<double>));
+ CHECK_TRAP(SimdRelBinop<v128, int64_t>(Ge<double>));
break;
case Opcode::F32X4Neg:
diff --git a/src/interp/interp.h b/src/interp/interp.h
index 16653abb..ec484f19 100644
--- a/src/interp/interp.h
+++ b/src/interp/interp.h
@@ -604,6 +604,9 @@ class Thread {
template <typename T, typename L, typename R, typename P = R>
Result SimdBinop(BinopFunc<R, P> func) WABT_WARN_UNUSED;
+ template <typename T, typename L, typename R, typename P = R>
+ Result SimdRelBinop(BinopFunc<R, P> func) WABT_WARN_UNUSED;
+
Environment* env_ = nullptr;
std::vector<Value> value_stack_;
std::vector<IstreamOffset> call_stack_;