[mips32][Liftoff] Fix i64 shift with immediate

The ShlPair function has two out of order instructions, this patch
reorder them and add some checks to prevent the dst register from
conflicting with the src register.

Change-Id: I2dd4b20a5c55fbbe75b126162302997acec5a6bb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1936647
Auto-Submit: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65188}
This commit is contained in:
Zhao Jiazhong 2019-11-26 07:02:37 -05:00 committed by Commit Bot
parent 01716359e9
commit 2a8baff963
2 changed files with 21 additions and 6 deletions

View File

@ -1560,14 +1560,17 @@ void TurboAssembler::ShlPair(Register dst_low, Register dst_high,
void TurboAssembler::ShlPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
uint32_t shift, Register scratch) {
DCHECK_NE(dst_low, src_low);
DCHECK_NE(dst_high, src_low);
shift = shift & 0x3F;
if (shift == 0) {
mov(dst_high, src_high);
mov(dst_low, src_low);
} else if (shift < 32) {
if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
Ins(dst_high, src_high, shift, 32 - shift);
DCHECK_NE(dst_high, src_high);
srl(dst_high, src_low, 32 - shift);
Ins(dst_high, src_high, shift, 32 - shift);
sll(dst_low, src_low, shift);
} else {
sll(dst_high, src_high, shift);
@ -1614,6 +1617,8 @@ void TurboAssembler::ShrPair(Register dst_low, Register dst_high,
void TurboAssembler::ShrPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
uint32_t shift, Register scratch) {
DCHECK_NE(dst_low, src_high);
DCHECK_NE(dst_high, src_high);
shift = shift & 0x3F;
if (shift == 0) {
mov(dst_low, src_low);
@ -1664,6 +1669,8 @@ void TurboAssembler::SarPair(Register dst_low, Register dst_high,
void TurboAssembler::SarPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
uint32_t shift, Register scratch) {
DCHECK_NE(dst_low, src_high);
DCHECK_NE(dst_high, src_high);
shift = shift & 0x3F;
if (shift == 0) {
mov(dst_low, src_low);

View File

@ -862,13 +862,19 @@ void LiftoffAssembler::emit_i64_shl(LiftoffRegister dst, LiftoffRegister src,
void LiftoffAssembler::emit_i64_shl(LiftoffRegister dst, LiftoffRegister src,
int32_t amount) {
UseScratchRegisterScope temps(this);
// {src.low_gp()} will still be needed after writing {dst.high_gp()}.
// {src.low_gp()} will still be needed after writing {dst.high_gp()} and
// {dst.low_gp()}.
Register src_low = liftoff::EnsureNoAlias(this, src.low_gp(), dst, &temps);
Register src_high = src.high_gp();
// {src.high_gp()} will still be needed after writing {dst.high_gp()}.
if (src_high == dst.high_gp()) {
mov(kScratchReg, src_high);
src_high = kScratchReg;
}
DCHECK_NE(dst.low_gp(), kScratchReg);
DCHECK_NE(dst.high_gp(), kScratchReg);
ShlPair(dst.low_gp(), dst.high_gp(), src_low, src.high_gp(), amount,
kScratchReg);
ShlPair(dst.low_gp(), dst.high_gp(), src_low, src_high, amount, kScratchReg);
}
void LiftoffAssembler::emit_i64_sar(LiftoffRegister dst, LiftoffRegister src,
@ -880,7 +886,8 @@ void LiftoffAssembler::emit_i64_sar(LiftoffRegister dst, LiftoffRegister src,
void LiftoffAssembler::emit_i64_sar(LiftoffRegister dst, LiftoffRegister src,
int32_t amount) {
UseScratchRegisterScope temps(this);
// {src.high_gp()} will still be needed after writing {dst.low_gp()}.
// {src.high_gp()} will still be needed after writing {dst.high_gp()} and
// {dst.low_gp()}.
Register src_high = liftoff::EnsureNoAlias(this, src.high_gp(), dst, &temps);
DCHECK_NE(dst.low_gp(), kScratchReg);
DCHECK_NE(dst.high_gp(), kScratchReg);
@ -898,7 +905,8 @@ void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
int32_t amount) {
UseScratchRegisterScope temps(this);
// {src.high_gp()} will still be needed after writing {dst.low_gp()}.
// {src.high_gp()} will still be needed after writing {dst.high_gp()} and
// {dst.low_gp()}.
Register src_high = liftoff::EnsureNoAlias(this, src.high_gp(), dst, &temps);
DCHECK_NE(dst.low_gp(), kScratchReg);
DCHECK_NE(dst.high_gp(), kScratchReg);