mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 11:07:45 +00:00
LibWasm: Implement all remaining comparison SIMD instructions
This commit is contained in:
parent
b7a8081b0f
commit
56ba869c57
2 changed files with 99 additions and 0 deletions
|
@ -1272,47 +1272,89 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi
|
||||||
case Instructions::f64x2_replace_lane.value():
|
case Instructions::f64x2_replace_lane.value():
|
||||||
return binary_numeric_operation<u128, u128, Operators::VectorReplaceLane<2, double>, double>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
|
return binary_numeric_operation<u128, u128, Operators::VectorReplaceLane<2, double>, double>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
|
||||||
case Instructions::i8x16_eq.value():
|
case Instructions::i8x16_eq.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::Equals>>(configuration);
|
||||||
case Instructions::i8x16_ne.value():
|
case Instructions::i8x16_ne.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::NotEquals>>(configuration);
|
||||||
case Instructions::i8x16_lt_s.value():
|
case Instructions::i8x16_lt_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::LessThan, MakeSigned>>(configuration);
|
||||||
case Instructions::i8x16_lt_u.value():
|
case Instructions::i8x16_lt_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::LessThan, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i8x16_gt_s.value():
|
case Instructions::i8x16_gt_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::GreaterThan, MakeSigned>>(configuration);
|
||||||
case Instructions::i8x16_gt_u.value():
|
case Instructions::i8x16_gt_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::GreaterThan, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i8x16_le_s.value():
|
case Instructions::i8x16_le_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::LessThanOrEquals, MakeSigned>>(configuration);
|
||||||
case Instructions::i8x16_le_u.value():
|
case Instructions::i8x16_le_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::LessThanOrEquals, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i8x16_ge_s.value():
|
case Instructions::i8x16_ge_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::GreaterThanOrEquals, MakeSigned>>(configuration);
|
||||||
case Instructions::i8x16_ge_u.value():
|
case Instructions::i8x16_ge_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::GreaterThanOrEquals, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i16x8_eq.value():
|
case Instructions::i16x8_eq.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::Equals>>(configuration);
|
||||||
case Instructions::i16x8_ne.value():
|
case Instructions::i16x8_ne.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::NotEquals>>(configuration);
|
||||||
case Instructions::i16x8_lt_s.value():
|
case Instructions::i16x8_lt_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::LessThan, MakeSigned>>(configuration);
|
||||||
case Instructions::i16x8_lt_u.value():
|
case Instructions::i16x8_lt_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::LessThan, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i16x8_gt_s.value():
|
case Instructions::i16x8_gt_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::GreaterThan, MakeSigned>>(configuration);
|
||||||
case Instructions::i16x8_gt_u.value():
|
case Instructions::i16x8_gt_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::GreaterThan, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i16x8_le_s.value():
|
case Instructions::i16x8_le_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::LessThanOrEquals, MakeSigned>>(configuration);
|
||||||
case Instructions::i16x8_le_u.value():
|
case Instructions::i16x8_le_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::LessThanOrEquals, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i16x8_ge_s.value():
|
case Instructions::i16x8_ge_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::GreaterThanOrEquals, MakeSigned>>(configuration);
|
||||||
case Instructions::i16x8_ge_u.value():
|
case Instructions::i16x8_ge_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::GreaterThanOrEquals, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i32x4_eq.value():
|
case Instructions::i32x4_eq.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::Equals>>(configuration);
|
||||||
case Instructions::i32x4_ne.value():
|
case Instructions::i32x4_ne.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::NotEquals>>(configuration);
|
||||||
case Instructions::i32x4_lt_s.value():
|
case Instructions::i32x4_lt_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::LessThan, MakeSigned>>(configuration);
|
||||||
case Instructions::i32x4_lt_u.value():
|
case Instructions::i32x4_lt_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::LessThan, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i32x4_gt_s.value():
|
case Instructions::i32x4_gt_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::GreaterThan, MakeSigned>>(configuration);
|
||||||
case Instructions::i32x4_gt_u.value():
|
case Instructions::i32x4_gt_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::GreaterThan, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i32x4_le_s.value():
|
case Instructions::i32x4_le_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::LessThanOrEquals, MakeSigned>>(configuration);
|
||||||
case Instructions::i32x4_le_u.value():
|
case Instructions::i32x4_le_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::LessThanOrEquals, MakeUnsigned>>(configuration);
|
||||||
case Instructions::i32x4_ge_s.value():
|
case Instructions::i32x4_ge_s.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::GreaterThanOrEquals, MakeSigned>>(configuration);
|
||||||
case Instructions::i32x4_ge_u.value():
|
case Instructions::i32x4_ge_u.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::GreaterThanOrEquals, MakeUnsigned>>(configuration);
|
||||||
case Instructions::f32x4_eq.value():
|
case Instructions::f32x4_eq.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::Equals>>(configuration);
|
||||||
case Instructions::f32x4_ne.value():
|
case Instructions::f32x4_ne.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::NotEquals>>(configuration);
|
||||||
case Instructions::f32x4_lt.value():
|
case Instructions::f32x4_lt.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::LessThan>>(configuration);
|
||||||
case Instructions::f32x4_gt.value():
|
case Instructions::f32x4_gt.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::GreaterThan>>(configuration);
|
||||||
case Instructions::f32x4_le.value():
|
case Instructions::f32x4_le.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::LessThanOrEquals>>(configuration);
|
||||||
case Instructions::f32x4_ge.value():
|
case Instructions::f32x4_ge.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::GreaterThanOrEquals>>(configuration);
|
||||||
case Instructions::f64x2_eq.value():
|
case Instructions::f64x2_eq.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::Equals>>(configuration);
|
||||||
case Instructions::f64x2_ne.value():
|
case Instructions::f64x2_ne.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::NotEquals>>(configuration);
|
||||||
case Instructions::f64x2_lt.value():
|
case Instructions::f64x2_lt.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::LessThan>>(configuration);
|
||||||
case Instructions::f64x2_gt.value():
|
case Instructions::f64x2_gt.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::GreaterThan>>(configuration);
|
||||||
case Instructions::f64x2_le.value():
|
case Instructions::f64x2_le.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::LessThanOrEquals>>(configuration);
|
||||||
case Instructions::f64x2_ge.value():
|
case Instructions::f64x2_ge.value():
|
||||||
|
return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::GreaterThanOrEquals>>(configuration);
|
||||||
case Instructions::v128_not.value():
|
case Instructions::v128_not.value():
|
||||||
case Instructions::v128_and.value():
|
case Instructions::v128_and.value():
|
||||||
case Instructions::v128_andnot.value():
|
case Instructions::v128_andnot.value():
|
||||||
|
|
|
@ -267,6 +267,63 @@ struct VectorReplaceLane {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<size_t VectorSize, typename Op, template<typename> typename SetSign = MakeSigned>
|
||||||
|
struct VectorCmpOp {
|
||||||
|
auto operator()(u128 c1, u128 c2) const
|
||||||
|
{
|
||||||
|
using ElementType = NativeIntegralType<128 / VectorSize>;
|
||||||
|
auto result = bit_cast<Native128ByteVectorOf<ElementType, SetSign>>(c1);
|
||||||
|
auto other = bit_cast<Native128ByteVectorOf<ElementType, SetSign>>(c2);
|
||||||
|
Op op;
|
||||||
|
for (size_t i = 0; i < VectorSize; ++i)
|
||||||
|
result[i] = op(result[i], other[i]) ? static_cast<MakeUnsigned<ElementType>>(-1) : 0;
|
||||||
|
return bit_cast<u128>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringView name()
|
||||||
|
{
|
||||||
|
switch (VectorSize) {
|
||||||
|
case 16:
|
||||||
|
return "vec(8x16).cmp"sv;
|
||||||
|
case 8:
|
||||||
|
return "vec(16x8).cmp"sv;
|
||||||
|
case 4:
|
||||||
|
return "vec(32x4).cmp"sv;
|
||||||
|
case 2:
|
||||||
|
return "vec(64x2).cmp"sv;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<size_t VectorSize, typename Op>
|
||||||
|
struct VectorFloatCmpOp {
|
||||||
|
auto operator()(u128 c1, u128 c2) const
|
||||||
|
{
|
||||||
|
auto first = bit_cast<NativeFloatingVectorType<128, VectorSize, NativeFloatingType<128 / VectorSize>>>(c1);
|
||||||
|
auto other = bit_cast<NativeFloatingVectorType<128, VectorSize, NativeFloatingType<128 / VectorSize>>>(c2);
|
||||||
|
using ElementType = NativeIntegralType<128 / VectorSize>;
|
||||||
|
Native128ByteVectorOf<ElementType, MakeUnsigned> result;
|
||||||
|
Op op;
|
||||||
|
for (size_t i = 0; i < VectorSize; ++i)
|
||||||
|
result[i] = op(first[i], other[i]) ? static_cast<ElementType>(-1) : 0;
|
||||||
|
return bit_cast<u128>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringView name()
|
||||||
|
{
|
||||||
|
switch (VectorSize) {
|
||||||
|
case 4:
|
||||||
|
return "vecf(32x4).cmp"sv;
|
||||||
|
case 2:
|
||||||
|
return "vecf(64x2).cmp"sv;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct Minimum {
|
struct Minimum {
|
||||||
template<typename Lhs, typename Rhs>
|
template<typename Lhs, typename Rhs>
|
||||||
auto operator()(Lhs lhs, Rhs rhs) const
|
auto operator()(Lhs lhs, Rhs rhs) const
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue