Commit 609d4719 authored by sreten.kovacevic's avatar sreten.kovacevic Committed by Commit Bot

[Liftoff][mips] Implement i64 shiftops

Implement i64 shl, shr and sar instructions in Liftoff for MIPS.

Bug: v8:6600
Change-Id: I195804509242657929ec8c4f0bd6470bbd26f010
Reviewed-on: https://chromium-review.googlesource.com/975131
Commit-Queue: Sreten Kovacevic <sreten.kovacevic@mips.com>
Reviewed-by: 's avatarIvica Bogosavljevic <ivica.bogosavljevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#52149}
parent 9debc06f
......@@ -440,18 +440,71 @@ I32_SHIFTOP(shr, srlv)
#undef I32_SHIFTOP
#define UNIMPLEMENTED_I64_SHIFTOP(name) \
void LiftoffAssembler::emit_i64_##name(LiftoffRegister dst, \
LiftoffRegister src, Register amount, \
LiftoffRegList pinned) { \
BAILOUT("i64 shiftop"); \
namespace liftoff {
inline bool IsRegInRegPair(LiftoffRegister pair, Register reg) {
DCHECK(pair.is_pair());
return pair.low_gp() == reg || pair.high_gp() == reg;
}
inline void Emit64BitShiftOperation(
LiftoffAssembler* assm, LiftoffRegister dst, LiftoffRegister src,
Register amount,
void (TurboAssembler::*emit_shift)(Register, Register, Register, Register,
Register),
LiftoffRegList pinned) {
Label move, done;
pinned.set(dst);
pinned.set(src);
pinned.set(amount);
// If shift amount is 0, don't do the shifting.
assm->TurboAssembler::Branch(&move, eq, amount, Operand(zero_reg));
if (liftoff::IsRegInRegPair(dst, amount) || dst.overlaps(src)) {
// If some of destination registers are in use, get another, unused pair.
// That way we prevent overwriting some input registers while shifting.
LiftoffRegister tmp = assm->GetUnusedRegister(kGpRegPair, pinned);
// Do the actual shift.
(assm->*emit_shift)(tmp.low_gp(), tmp.high_gp(), src.low_gp(),
src.high_gp(), amount);
// Place result in destination register.
assm->TurboAssembler::Move(dst.high_gp(), tmp.high_gp());
assm->TurboAssembler::Move(dst.low_gp(), tmp.low_gp());
} else {
(assm->*emit_shift)(dst.low_gp(), dst.high_gp(), src.low_gp(),
src.high_gp(), amount);
}
assm->TurboAssembler::Branch(&done);
UNIMPLEMENTED_I64_SHIFTOP(shl)
UNIMPLEMENTED_I64_SHIFTOP(sar)
UNIMPLEMENTED_I64_SHIFTOP(shr)
// If shift amount is 0, move src to dst.
assm->bind(&move);
assm->TurboAssembler::Move(dst.high_gp(), src.high_gp());
assm->TurboAssembler::Move(dst.low_gp(), src.low_gp());
#undef I32_SHIFTOP
assm->bind(&done);
}
} // namespace liftoff
void LiftoffAssembler::emit_i64_shl(LiftoffRegister dst, LiftoffRegister src,
Register amount, LiftoffRegList pinned) {
liftoff::Emit64BitShiftOperation(this, dst, src, amount,
&TurboAssembler::ShlPair, pinned);
}
void LiftoffAssembler::emit_i64_sar(LiftoffRegister dst, LiftoffRegister src,
Register amount, LiftoffRegList pinned) {
liftoff::Emit64BitShiftOperation(this, dst, src, amount,
&TurboAssembler::SarPair, pinned);
}
void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
Register amount, LiftoffRegList pinned) {
liftoff::Emit64BitShiftOperation(this, dst, src, amount,
&TurboAssembler::ShrPair, pinned);
}
#define FP_BINOP(name, instruction) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister lhs, \
......
......@@ -387,16 +387,16 @@ I32_SHIFTOP(shr, srlv)
#undef I32_SHIFTOP
#define UNIMPLEMENTED_I64_SHIFTOP(name) \
#define I64_SHIFTOP(name, instruction) \
void LiftoffAssembler::emit_i64_##name(LiftoffRegister dst, \
LiftoffRegister src, Register amount, \
LiftoffRegList pinned) { \
BAILOUT("i64 shiftop"); \
instruction(dst.gp(), src.gp(), amount); \
}
UNIMPLEMENTED_I64_SHIFTOP(shl)
UNIMPLEMENTED_I64_SHIFTOP(sar)
UNIMPLEMENTED_I64_SHIFTOP(shr)
I64_SHIFTOP(shl, dsllv)
I64_SHIFTOP(sar, dsrav)
I64_SHIFTOP(shr, dsrlv)
#undef I32_SHIFTOP
......
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