Commit fbf9b5e4 authored by sreten.kovacevic's avatar sreten.kovacevic Committed by Commit Bot

[mips] Cleanup: Refactor AddPair and SubPair, implement MulPair

Refactor AddPair and SubPair Macro-assembler instructions to
prevent register overwriting, refactor all the places where
these instructions are used. Also, implement MulPair instruction.

Change-Id: I3f8f9d5fe6fa5bf25df3446614ac311cf886b6ac
Reviewed-on: https://chromium-review.googlesource.com/1013571Reviewed-by: 's avatarIvica Bogosavljevic <ivica.bogosavljevic@mips.com>
Commit-Queue: Sreten Kovacevic <sreten.kovacevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#52642}
parent b70dd880
......@@ -1174,19 +1174,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} break;
case kMipsAddPair:
__ AddPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0),
i.InputRegister(1), i.InputRegister(2), i.InputRegister(3));
i.InputRegister(1), i.InputRegister(2), i.InputRegister(3),
kScratchReg, kScratchReg2);
break;
case kMipsSubPair:
__ SubPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0),
i.InputRegister(1), i.InputRegister(2), i.InputRegister(3));
i.InputRegister(1), i.InputRegister(2), i.InputRegister(3),
kScratchReg, kScratchReg2);
break;
case kMipsMulPair: {
__ Mulu(i.OutputRegister(1), i.OutputRegister(0), i.InputRegister(0),
i.InputRegister(2));
__ Mul(kScratchReg, i.InputRegister(0), i.InputRegister(3));
__ Mul(kScratchReg2, i.InputRegister(1), i.InputRegister(2));
__ Addu(i.OutputRegister(1), i.OutputRegister(1), kScratchReg);
__ Addu(i.OutputRegister(1), i.OutputRegister(1), kScratchReg2);
__ MulPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0),
i.InputRegister(1), i.InputRegister(2), i.InputRegister(3),
kScratchReg, kScratchReg2);
} break;
case kMipsAddD:
// TODO(plind): add special case: combine mult & add.
......
......@@ -1411,34 +1411,44 @@ void TurboAssembler::MultiPopFPU(RegList regs) {
addiu(sp, sp, stack_offset);
}
void TurboAssembler::AddPair(Register dst_low, Register dst_high,
Register left_low, Register left_high,
Register right_low, Register right_high) {
Register kScratchReg = s3;
if (left_low == right_low) {
// Special case for left = right and the sum potentially overwriting both
// left and right.
Slt(kScratchReg, left_low, zero_reg);
Addu(dst_low, left_low, right_low);
} else {
Addu(dst_low, left_low, right_low);
// If the sum overwrites right, left remains unchanged, otherwise right
// remains unchanged.
Sltu(kScratchReg, dst_low, (dst_low == right_low) ? left_low : right_low);
}
Addu(dst_high, left_high, right_high);
Addu(dst_high, dst_high, kScratchReg);
Register right_low, Register right_high,
Register scratch1, Register scratch2) {
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch3 = t8;
Addu(scratch1, left_low, right_low);
Sltu(scratch3, scratch1, left_low);
Addu(scratch2, left_high, right_high);
Addu(dst_high, scratch2, scratch3);
Move(dst_low, scratch1);
}
void TurboAssembler::SubPair(Register dst_low, Register dst_high,
Register left_low, Register left_high,
Register right_low, Register right_high) {
Register kScratchReg = s3;
Sltu(kScratchReg, left_low, right_low);
Subu(dst_low, left_low, right_low);
Subu(dst_high, left_high, right_high);
Subu(dst_high, dst_high, kScratchReg);
Register right_low, Register right_high,
Register scratch1, Register scratch2) {
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch3 = t8;
Sltu(scratch3, left_low, right_low);
Subu(scratch1, left_low, right_low);
Subu(scratch2, left_high, right_high);
Subu(dst_high, scratch2, scratch3);
Move(dst_low, scratch1);
}
void TurboAssembler::MulPair(Register dst_low, Register dst_high,
Register left_low, Register left_high,
Register right_low, Register right_high,
Register scratch1, Register scratch2) {
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch3 = t8;
Mulu(scratch2, scratch1, left_low, right_low);
Mul(scratch3, left_low, right_high);
Addu(scratch2, scratch2, scratch3);
Mul(scratch3, left_high, right_low);
Addu(dst_high, scratch2, scratch3);
Move(dst_low, scratch1);
}
void TurboAssembler::ShlPair(Register dst_low, Register dst_high,
......
......@@ -579,10 +579,16 @@ class TurboAssembler : public Assembler {
// Int64Lowering instructions
void AddPair(Register dst_low, Register dst_high, Register left_low,
Register left_high, Register right_low, Register right_high);
Register left_high, Register right_low, Register right_high,
Register scratch1, Register scratch2);
void SubPair(Register dst_low, Register dst_high, Register left_low,
Register left_high, Register right_low, Register right_high);
Register left_high, Register right_low, Register right_high,
Register scratch1, Register scratch2);
void MulPair(Register dst_low, Register dst_high, Register left_low,
Register left_high, Register right_low, Register right_high,
Register scratch1, Register scratch2);
void ShlPair(Register dst_low, Register dst_high, Register src_low,
Register src_high, Register shift, Register scratch1,
......
......@@ -584,60 +584,23 @@ I32_SHIFTOP(shr, srlv)
void LiftoffAssembler::emit_i64_mul(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
LiftoffRegister org_dst = dst;
// Allocate registers for dst, to prevent overwriting source.
if (dst.overlaps(lhs) || dst.overlaps(rhs)) {
dst = GetUnusedRegister(kGpRegPair, LiftoffRegList::ForRegs(lhs, rhs));
}
// Multiply.
TurboAssembler::Mulu(dst.high_gp(), dst.low_gp(), lhs.low_gp(), rhs.low_gp());
LiftoffRegister tmp =
GetUnusedRegister(kGpReg, LiftoffRegList::ForRegs(dst, lhs, rhs));
TurboAssembler::Mul(tmp.gp(), lhs.low_gp(), rhs.high_gp());
TurboAssembler::Addu(dst.high_gp(), dst.high_gp(), tmp.gp());
TurboAssembler::Mul(tmp.gp(), lhs.high_gp(), rhs.low_gp());
TurboAssembler::Addu(dst.high_gp(), dst.high_gp(), tmp.gp());
// Move result to original dst if needed.
if (dst != org_dst) {
Move(org_dst, dst, kWasmI64);
}
TurboAssembler::MulPair(dst.low_gp(), dst.high_gp(), lhs.low_gp(),
lhs.high_gp(), rhs.low_gp(), rhs.high_gp(),
kScratchReg, kScratchReg2);
}
void LiftoffAssembler::emit_i64_add(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
LiftoffRegister org_dst = dst;
// Allocate registers for dst, to prevent overwriting source.
if (dst.overlaps(lhs) || dst.overlaps(rhs)) {
dst = GetUnusedRegister(kGpRegPair, LiftoffRegList::ForRegs(lhs, rhs));
}
TurboAssembler::AddPair(dst.low_gp(), dst.high_gp(), lhs.low_gp(),
lhs.high_gp(), rhs.low_gp(), rhs.high_gp());
// Move result to original dst if needed.
if (dst != org_dst) {
Move(org_dst, dst, kWasmI64);
}
lhs.high_gp(), rhs.low_gp(), rhs.high_gp(),
kScratchReg, kScratchReg2);
}
void LiftoffAssembler::emit_i64_sub(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
LiftoffRegister org_dst = dst;
// Allocate registers for dst, to prevent overwriting source.
if (dst.overlaps(lhs) || dst.overlaps(rhs)) {
dst = GetUnusedRegister(kGpRegPair, LiftoffRegList::ForRegs(lhs, rhs));
}
TurboAssembler::SubPair(dst.low_gp(), dst.high_gp(), lhs.low_gp(),
lhs.high_gp(), rhs.low_gp(), rhs.high_gp());
// Move result to original dst if needed.
if (dst != org_dst) {
Move(org_dst, dst, kWasmI64);
}
lhs.high_gp(), rhs.low_gp(), rhs.high_gp(),
kScratchReg, kScratchReg2);
}
namespace liftoff {
......
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