Commit 99a361ee authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][liftoff] Implement i64x2 shr_s and shr_u

Implementation for x64 and ia32.

Bug: v8:9909
Change-Id: Id494d292fe8ab464e07f4b9520d1c251d355615a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2198456
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67808}
parent 1bda8d9b
......@@ -2307,6 +2307,28 @@ void LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
liftoff::GetSimd128Register(lhs), rhs & 63);
}
void LiftoffAssembler::emit_i64x2_shr_s(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i64x2_shr_s");
}
void LiftoffAssembler::emit_i64x2_shri_s(LiftoffRegister dst,
LiftoffRegister lhs, int32_t rhs) {
bailout(kSimd, "i64x2_shri_s");
}
void LiftoffAssembler::emit_i64x2_shr_u(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i64x2_shr_u");
}
void LiftoffAssembler::emit_i64x2_shri_u(LiftoffRegister dst,
LiftoffRegister lhs, int32_t rhs) {
bailout(kSimd, "i64x2_shri_u");
}
void LiftoffAssembler::emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
vadd(Neon64, liftoff::GetSimd128Register(dst),
......
......@@ -1278,6 +1278,28 @@ void LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
Shl(dst.fp().V2D(), lhs.fp().V2D(), rhs & 63);
}
void LiftoffAssembler::emit_i64x2_shr_s(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i64x2_shr_s");
}
void LiftoffAssembler::emit_i64x2_shri_s(LiftoffRegister dst,
LiftoffRegister lhs, int32_t rhs) {
bailout(kSimd, "i64x2_shri_s");
}
void LiftoffAssembler::emit_i64x2_shr_u(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i64x2_shr_u");
}
void LiftoffAssembler::emit_i64x2_shri_u(LiftoffRegister dst,
LiftoffRegister lhs, int32_t rhs) {
bailout(kSimd, "i64x2_shri_u");
}
void LiftoffAssembler::emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
Add(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
......
......@@ -2723,6 +2723,56 @@ void LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
this, dst, lhs, rhs);
}
void LiftoffAssembler::emit_i64x2_shr_s(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
XMMRegister shift = liftoff::kScratchDoubleReg;
XMMRegister tmp =
GetUnusedRegister(RegClass::kFpReg, LiftoffRegList::ForRegs(dst, lhs))
.fp();
// Take shift value modulo 64.
and_(rhs.gp(), Immediate(63));
Movd(shift, rhs.gp());
// Set up a mask [0x80000000,0,0x80000000,0].
Pcmpeqb(tmp, tmp);
Psllq(tmp, tmp, 63);
Psrlq(tmp, tmp, shift);
Psrlq(dst.fp(), lhs.fp(), shift);
Pxor(dst.fp(), tmp);
Psubq(dst.fp(), tmp);
}
void LiftoffAssembler::emit_i64x2_shri_s(LiftoffRegister dst,
LiftoffRegister lhs, int32_t rhs) {
XMMRegister tmp = liftoff::kScratchDoubleReg;
int32_t shift = rhs & 63;
// Set up a mask [0x80000000,0,0x80000000,0].
Pcmpeqb(tmp, tmp);
Psllq(tmp, tmp, 63);
Psrlq(tmp, tmp, shift);
Psrlq(dst.fp(), lhs.fp(), shift);
Pxor(dst.fp(), tmp);
Psubq(dst.fp(), tmp);
}
void LiftoffAssembler::emit_i64x2_shr_u(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
liftoff::EmitSimdShiftOp<&Assembler::vpsrlq, &Assembler::psrlq, 6>(this, dst,
lhs, rhs);
}
void LiftoffAssembler::emit_i64x2_shri_u(LiftoffRegister dst,
LiftoffRegister lhs, int32_t rhs) {
liftoff::EmitSimdShiftOpImm<&Assembler::vpsrlq, &Assembler::psrlq, 6>(
this, dst, lhs, rhs);
}
void LiftoffAssembler::emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddq, &Assembler::paddq>(
......
......@@ -895,6 +895,14 @@ class LiftoffAssembler : public TurboAssembler {
LiftoffRegister rhs);
inline void emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs);
inline void emit_i64x2_shr_s(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs);
inline void emit_i64x2_shri_s(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs);
inline void emit_i64x2_shr_u(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs);
inline void emit_i64x2_shri_u(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs);
inline void emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs);
inline void emit_i64x2_sub(LiftoffRegister dst, LiftoffRegister lhs,
......
......@@ -2584,6 +2584,12 @@ class LiftoffCompiler {
case wasm::kExprI64x2Shl:
return EmitSimdShiftOp(&LiftoffAssembler::emit_i64x2_shl,
&LiftoffAssembler::emit_i64x2_shli);
case wasm::kExprI64x2ShrS:
return EmitSimdShiftOp(&LiftoffAssembler::emit_i64x2_shr_s,
&LiftoffAssembler::emit_i64x2_shri_s);
case wasm::kExprI64x2ShrU:
return EmitSimdShiftOp(&LiftoffAssembler::emit_i64x2_shr_u,
&LiftoffAssembler::emit_i64x2_shri_u);
case wasm::kExprI64x2Add:
return EmitBinOp<kS128, kS128>(&LiftoffAssembler::emit_i64x2_add);
case wasm::kExprI64x2Sub:
......
......@@ -1975,6 +1975,38 @@ void EmitSimdShiftOpImm(LiftoffAssembler* assm, LiftoffRegister dst,
(assm->*sse_op)(dst.fp(), shift);
}
}
// Can be used by both the immediate and register version of the shifts. psraq
// is only available in AVX512, so we can't use it yet.
template <typename ShiftOperand>
void EmitI64x2ShrS(LiftoffAssembler* assm, LiftoffRegister dst,
LiftoffRegister lhs, ShiftOperand rhs,
bool shift_is_rcx = false) {
bool restore_rcx = false;
if (!shift_is_rcx) {
if (assm->cache_state()->is_used(LiftoffRegister(rcx))) {
restore_rcx = true;
assm->movq(kScratchRegister, rcx);
}
assm->movl(rcx, rhs);
}
Register tmp = kScratchRegister;
assm->Pextrq(tmp, lhs.fp(), int8_t{0x0});
assm->sarq_cl(tmp);
assm->Pinsrq(dst.fp(), tmp, int8_t{0x0});
assm->Pextrq(tmp, lhs.fp(), int8_t{0x1});
assm->sarq_cl(tmp);
assm->Pinsrq(dst.fp(), tmp, int8_t{0x1});
// restore rcx.
if (restore_rcx) {
assm->movq(rcx, kScratchRegister);
}
}
} // namespace liftoff
void LiftoffAssembler::emit_i8x16_splat(LiftoffRegister dst,
......@@ -2670,6 +2702,31 @@ void LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
this, dst, lhs, rhs);
}
void LiftoffAssembler::emit_i64x2_shr_s(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
liftoff::EmitI64x2ShrS(this, dst, lhs, rhs.gp(),
/*shift_is_rcx=*/rhs.gp() == rcx);
}
void LiftoffAssembler::emit_i64x2_shri_s(LiftoffRegister dst,
LiftoffRegister lhs, int32_t rhs) {
liftoff::EmitI64x2ShrS(this, dst, lhs, Immediate(rhs));
}
void LiftoffAssembler::emit_i64x2_shr_u(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
liftoff::EmitSimdShiftOp<&Assembler::vpsrlq, &Assembler::psrlq, 6>(this, dst,
lhs, rhs);
}
void LiftoffAssembler::emit_i64x2_shri_u(LiftoffRegister dst,
LiftoffRegister lhs, int32_t rhs) {
liftoff::EmitSimdShiftOpImm<&Assembler::vpsrlq, &Assembler::psrlq, 6>(
this, dst, lhs, rhs);
}
void LiftoffAssembler::emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddq, &Assembler::paddq>(
......
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