[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/1013571 Reviewed-by: Ivica Bogosavljevic <ivica.bogosavljevic@mips.com> Commit-Queue: Sreten Kovacevic <sreten.kovacevic@mips.com> Cr-Commit-Position: refs/heads/master@{#52642}
This commit is contained in:
parent
b70dd880f2
commit
fbf9b5e4ff
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user