[Liftoff][mips] Implement i64 binops
Implement i64 binops (`add`, `sub`, `mul`, `and`, `or` and `xor` on MIPS64 and `add`, `mul` and `sub` on MIPS). Bug: v8:6600 Change-Id: I96640a6b4420789f075b1d919789a72163c954d2 Reviewed-on: https://chromium-review.googlesource.com/1010203 Commit-Queue: Sreten Kovacevic <sreten.kovacevic@mips.com> Reviewed-by: Ivica Bogosavljevic <ivica.bogosavljevic@mips.com> Cr-Commit-Position: refs/heads/master@{#52617}
This commit is contained in:
parent
a5f782745e
commit
c1401045e3
@ -489,16 +489,15 @@ void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {
|
||||
break;
|
||||
}
|
||||
case kWasmI64: {
|
||||
LiftoffRegister low = GetUnusedRegister(kGpReg);
|
||||
LiftoffRegister high = GetUnusedRegister(kGpReg);
|
||||
LiftoffRegister tmp = GetUnusedRegister(kGpRegPair);
|
||||
|
||||
int32_t low_word = value.to_i64();
|
||||
int32_t high_word = value.to_i64() >> 32;
|
||||
TurboAssembler::li(low.gp(), Operand(low_word));
|
||||
TurboAssembler::li(high.gp(), Operand(high_word));
|
||||
TurboAssembler::li(tmp.low_gp(), Operand(low_word));
|
||||
TurboAssembler::li(tmp.high_gp(), Operand(high_word));
|
||||
|
||||
sw(low.gp(), dst);
|
||||
sw(high.gp(), liftoff::GetHalfStackSlot(2 * index + 1));
|
||||
sw(tmp.low_gp(), dst);
|
||||
sw(tmp.high_gp(), liftoff::GetHalfStackSlot(2 * index + 1));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -581,17 +580,63 @@ I32_SHIFTOP(shr, srlv)
|
||||
|
||||
#undef I32_SHIFTOP
|
||||
|
||||
#define UNIMPLEMENTED_I64_BINOP(name) \
|
||||
void LiftoffAssembler::emit_i64_##name( \
|
||||
LiftoffRegister dst, LiftoffRegister lhs, LiftoffRegister rhs) { \
|
||||
BAILOUT("i64 binop: " #name); \
|
||||
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));
|
||||
}
|
||||
|
||||
UNIMPLEMENTED_I64_BINOP(add)
|
||||
UNIMPLEMENTED_I64_BINOP(sub)
|
||||
UNIMPLEMENTED_I64_BINOP(mul)
|
||||
// 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());
|
||||
|
||||
#undef UNIMPLEMENTED_I64_BINOP
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
namespace liftoff {
|
||||
|
||||
|
@ -508,31 +508,23 @@ I32_SHIFTOP(shr, srlv)
|
||||
|
||||
#undef I32_SHIFTOP
|
||||
|
||||
void LiftoffAssembler::emit_i64_add(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs) {
|
||||
TurboAssembler::Daddu(dst.gp(), lhs.gp(), rhs.gp());
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i64_sub(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs) {
|
||||
BAILOUT("i64_sub");
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i64_mul(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs) {
|
||||
BAILOUT("i64_mul");
|
||||
TurboAssembler::Dmul(dst.gp(), lhs.gp(), rhs.gp());
|
||||
}
|
||||
|
||||
#define I64_BINOP(name) \
|
||||
#define I64_BINOP(name, instruction) \
|
||||
void LiftoffAssembler::emit_i64_##name( \
|
||||
LiftoffRegister dst, LiftoffRegister lhs, LiftoffRegister rhs) { \
|
||||
BAILOUT("i64_" #name); \
|
||||
instruction(dst.gp(), lhs.gp(), rhs.gp()); \
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
I64_BINOP(and)
|
||||
I64_BINOP(or)
|
||||
I64_BINOP(xor)
|
||||
I64_BINOP(add, daddu)
|
||||
I64_BINOP(sub, dsubu)
|
||||
I64_BINOP(and, and_)
|
||||
I64_BINOP(or, or_)
|
||||
I64_BINOP(xor, xor_)
|
||||
// clang-format on
|
||||
|
||||
#undef I64_BINOP
|
||||
|
Loading…
Reference in New Issue
Block a user