Commit 72f3270b authored by Zhi An Ng's avatar Zhi An Ng Committed by Commit Bot

[wasm-simd][x64][liftoff] Implement extended multiply

For i64x2.ext_mul and i16x8.ext_mul, we can simply call the
macro-assembler functions.

For i32x4.ext_mul, the macro-assembler requires that dst == src1 if AVX
is not supported, so we add a helper function to do that check, and make
sure dst == src1 before calling into macro-assembler.

Bug: v8:11262
Change-Id: Iff8e99967f4ab157021d0706e0142df894468142
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2603765Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71903}
parent 45bdd8fd
...@@ -3159,25 +3159,28 @@ void LiftoffAssembler::emit_i16x8_max_u(LiftoffRegister dst, ...@@ -3159,25 +3159,28 @@ void LiftoffAssembler::emit_i16x8_max_u(LiftoffRegister dst,
void LiftoffAssembler::emit_i16x8_extmul_low_i8x16_s(LiftoffRegister dst, void LiftoffAssembler::emit_i16x8_extmul_low_i8x16_s(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i16x8.extmul_low_i8x16_s unsupported"); I16x8ExtMul(dst.fp(), src1.fp(), src2.fp(), /*low=*/true, /*is_signed=*/true);
} }
void LiftoffAssembler::emit_i16x8_extmul_low_i8x16_u(LiftoffRegister dst, void LiftoffAssembler::emit_i16x8_extmul_low_i8x16_u(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i16x8.extmul_low_i8x16_u unsupported"); I16x8ExtMul(dst.fp(), src1.fp(), src2.fp(), /*low=*/true,
/*is_signed=*/false);
} }
void LiftoffAssembler::emit_i16x8_extmul_high_i8x16_s(LiftoffRegister dst, void LiftoffAssembler::emit_i16x8_extmul_high_i8x16_s(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i16x8.extmul_high_i8x16_s unsupported"); I16x8ExtMul(dst.fp(), src1.fp(), src2.fp(), /*low=*/false,
/*is_signed=*/true);
} }
void LiftoffAssembler::emit_i16x8_extmul_high_i8x16_u(LiftoffRegister dst, void LiftoffAssembler::emit_i16x8_extmul_high_i8x16_u(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i16x8_extmul_high_i8x16_u unsupported"); I16x8ExtMul(dst.fp(), src1.fp(), src2.fp(), /*low=*/false,
/*is_signed=*/false);
} }
void LiftoffAssembler::emit_i32x4_neg(LiftoffRegister dst, void LiftoffAssembler::emit_i32x4_neg(LiftoffRegister dst,
...@@ -3297,28 +3300,56 @@ void LiftoffAssembler::emit_i32x4_dot_i16x8_s(LiftoffRegister dst, ...@@ -3297,28 +3300,56 @@ void LiftoffAssembler::emit_i32x4_dot_i16x8_s(LiftoffRegister dst,
this, dst, lhs, rhs); this, dst, lhs, rhs);
} }
namespace liftoff {
// Helper function to check for register aliasing, AVX support, and moves
// registers around before calling the actual macro-assembler function.
inline void I32x4ExtMulHelper(LiftoffAssembler* assm, XMMRegister dst,
XMMRegister src1, XMMRegister src2, bool low,
bool is_signed) {
// I32x4ExtMul requires dst == src1 if AVX is not supported.
if (CpuFeatures::IsSupported(AVX) || dst == src1) {
assm->I32x4ExtMul(dst, src1, src2, low, is_signed);
} else if (dst != src2) {
// dst != src1 && dst != src2
assm->movaps(dst, src1);
assm->I32x4ExtMul(dst, dst, src2, low, is_signed);
} else {
// dst == src2
// Extended multiplication is commutative,
assm->movaps(dst, src2);
assm->I32x4ExtMul(dst, dst, src1, low, is_signed);
}
}
} // namespace liftoff
void LiftoffAssembler::emit_i32x4_extmul_low_i16x8_s(LiftoffRegister dst, void LiftoffAssembler::emit_i32x4_extmul_low_i16x8_s(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i32x4_extmul_low_i16x8_s unsupported"); liftoff::I32x4ExtMulHelper(this, dst.fp(), src1.fp(), src2.fp(), /*low=*/true,
/*is_signed=*/true);
} }
void LiftoffAssembler::emit_i32x4_extmul_low_i16x8_u(LiftoffRegister dst, void LiftoffAssembler::emit_i32x4_extmul_low_i16x8_u(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i32x4_extmul_low_i16x8_u unsupported"); liftoff::I32x4ExtMulHelper(this, dst.fp(), src1.fp(), src2.fp(), /*low=*/true,
/*is_signed=*/false);
} }
void LiftoffAssembler::emit_i32x4_extmul_high_i16x8_s(LiftoffRegister dst, void LiftoffAssembler::emit_i32x4_extmul_high_i16x8_s(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i32x4_extmul_high_i16x8_s unsupported"); liftoff::I32x4ExtMulHelper(this, dst.fp(), src1.fp(), src2.fp(),
/*low=*/false,
/*is_signed=*/true);
} }
void LiftoffAssembler::emit_i32x4_extmul_high_i16x8_u(LiftoffRegister dst, void LiftoffAssembler::emit_i32x4_extmul_high_i16x8_u(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i32x4_extmul_high_i16x8_u unsupported"); liftoff::I32x4ExtMulHelper(this, dst.fp(), src1.fp(), src2.fp(),
/*low=*/false,
/*is_signed=*/false);
} }
void LiftoffAssembler::emit_i64x2_neg(LiftoffRegister dst, void LiftoffAssembler::emit_i64x2_neg(LiftoffRegister dst,
...@@ -3413,25 +3444,28 @@ void LiftoffAssembler::emit_i64x2_mul(LiftoffRegister dst, LiftoffRegister lhs, ...@@ -3413,25 +3444,28 @@ void LiftoffAssembler::emit_i64x2_mul(LiftoffRegister dst, LiftoffRegister lhs,
void LiftoffAssembler::emit_i64x2_extmul_low_i32x4_s(LiftoffRegister dst, void LiftoffAssembler::emit_i64x2_extmul_low_i32x4_s(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i64x2_extmul_low_i32x4_s unsupported"); I64x2ExtMul(dst.fp(), src1.fp(), src2.fp(), /*low=*/true, /*is_signed=*/true);
} }
void LiftoffAssembler::emit_i64x2_extmul_low_i32x4_u(LiftoffRegister dst, void LiftoffAssembler::emit_i64x2_extmul_low_i32x4_u(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i64x2_extmul_low_i32x4_u unsupported"); I64x2ExtMul(dst.fp(), src1.fp(), src2.fp(), /*low=*/true,
/*is_signed=*/false);
} }
void LiftoffAssembler::emit_i64x2_extmul_high_i32x4_s(LiftoffRegister dst, void LiftoffAssembler::emit_i64x2_extmul_high_i32x4_s(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i64x2_extmul_high_i32x4_s unsupported"); I64x2ExtMul(dst.fp(), src1.fp(), src2.fp(), /*low=*/false,
/*is_signed=*/true);
} }
void LiftoffAssembler::emit_i64x2_extmul_high_i32x4_u(LiftoffRegister dst, void LiftoffAssembler::emit_i64x2_extmul_high_i32x4_u(LiftoffRegister dst,
LiftoffRegister src1, LiftoffRegister src1,
LiftoffRegister src2) { LiftoffRegister src2) {
bailout(kSimd, "i64x2_extmul_high_i32x4_u unsupported"); I64x2ExtMul(dst.fp(), src1.fp(), src2.fp(), /*low=*/false,
/*is_signed=*/false);
} }
void LiftoffAssembler::emit_f32x4_abs(LiftoffRegister dst, void LiftoffAssembler::emit_f32x4_abs(LiftoffRegister dst,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment