Commit 0b67384a authored by sreten.kovacevic's avatar sreten.kovacevic Committed by Commit Bot

[Liftoff][mips] Implement CallerFrameSlot instructions

Implement Push and Load CallerFrameSlot instructions.
Also, fix some issues that was revealed after these changes.

Bug: v8:6600
Change-Id: I658c26b0dcec489e7e549d4f1fbd4ccd89a6ea99
Reviewed-on: https://chromium-review.googlesource.com/964001Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarIvica Bogosavljevic <ivica.bogosavljevic@mips.com>
Commit-Queue: Ivica Bogosavljevic <ivica.bogosavljevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#51942}
parent b20aafb9
......@@ -33,6 +33,44 @@ inline MemOperand GetHalfStackSlot(uint32_t half_index) {
inline MemOperand GetContextOperand() { return MemOperand(fp, -16); }
inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, MemOperand src,
ValueType type) {
switch (type) {
case kWasmI32:
assm->lw(dst.gp(), src);
break;
case kWasmF32:
assm->lwc1(dst.fp(), src);
break;
case kWasmF64:
assm->Ldc1(dst.fp(), src);
break;
default:
UNREACHABLE();
}
}
inline void push(LiftoffAssembler* assm, LiftoffRegister reg, ValueType type) {
switch (type) {
case kWasmI32:
assm->push(reg.gp());
break;
case kWasmI64:
assm->Push(reg.high_gp(), reg.low_gp());
break;
case kWasmF32:
assm->addiu(sp, sp, -sizeof(float));
assm->swc1(reg.fp(), MemOperand(sp, 0));
break;
case kWasmF64:
assm->addiu(sp, sp, -sizeof(double));
assm->Sdc1(reg.fp(), MemOperand(sp, 0));
break;
default:
UNREACHABLE();
}
}
} // namespace liftoff
uint32_t LiftoffAssembler::PrepareStackFrame() {
......@@ -233,7 +271,8 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
uint32_t caller_slot_idx,
ValueType type) {
BAILOUT("LoadCallerFrameSlot");
MemOperand src(fp, kPointerSize * (caller_slot_idx + 1));
liftoff::Load(this, dst, src, type);
}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
......@@ -498,12 +537,39 @@ void LiftoffAssembler::AssertUnreachable(AbortReason reason) {
void LiftoffAssembler::PushCallerFrameSlot(const VarState& src,
uint32_t src_index,
RegPairHalf half) {
BAILOUT("PushCallerFrameSlot");
switch (src.loc()) {
case VarState::kStack: {
if (src.type() == kWasmF64) {
DCHECK_EQ(kLowWord, half);
lw(at, liftoff::GetHalfStackSlot(2 * src_index - 1));
push(at);
}
lw(at,
liftoff::GetHalfStackSlot(2 * src_index + (half == kLowWord ? 0 : 1)));
push(at);
break;
}
case VarState::kRegister:
if (src.type() == kWasmI64) {
PushCallerFrameSlot(
half == kLowWord ? src.reg().low() : src.reg().high(), kWasmI32);
} else {
PushCallerFrameSlot(src.reg(), src.type());
}
break;
case VarState::KIntConst: {
// The high word is the sign extension of the low word.
li(at,
Operand(half == kLowWord ? src.i32_const() : src.i32_const() >> 31));
push(at);
break;
}
}
}
void LiftoffAssembler::PushCallerFrameSlot(LiftoffRegister reg,
ValueType type) {
BAILOUT("PushCallerFrameSlot reg");
liftoff::push(this, reg, type);
}
void LiftoffAssembler::PushRegisters(LiftoffRegList regs) {
......@@ -558,7 +624,7 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
void LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) {
DCHECK_LT(num_stack_slots, (1 << 16) / kPointerSize); // 16 bit immediate
TurboAssembler::DropAndRet(static_cast<int>(num_stack_slots * kPointerSize));
TurboAssembler::DropAndRet(static_cast<int>(num_stack_slots));
}
void LiftoffAssembler::PrepareCCall(wasm::FunctionSig* sig,
......
......@@ -28,6 +28,45 @@ inline MemOperand GetStackSlot(uint32_t index) {
inline MemOperand GetContextOperand() { return MemOperand(fp, -16); }
inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, MemOperand src,
ValueType type) {
switch (type) {
case kWasmI32:
assm->lw(dst.gp(), src);
break;
case kWasmI64:
assm->ld(dst.gp(), src);
break;
case kWasmF32:
assm->lwc1(dst.fp(), src);
break;
case kWasmF64:
assm->Ldc1(dst.fp(), src);
break;
default:
UNREACHABLE();
}
}
inline void push(LiftoffAssembler* assm, LiftoffRegister reg, ValueType type) {
switch (type) {
case kWasmI32:
case kWasmI64:
assm->push(reg.gp());
break;
case kWasmF32:
assm->daddiu(sp, sp, -kPointerSize);
assm->swc1(reg.fp(), MemOperand(sp, 0));
break;
case kWasmF64:
assm->daddiu(sp, sp, -kPointerSize);
assm->Sdc1(reg.fp(), MemOperand(sp, 0));
break;
default:
UNREACHABLE();
}
}
} // namespace liftoff
uint32_t LiftoffAssembler::PrepareStackFrame() {
......@@ -191,7 +230,8 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
uint32_t caller_slot_idx,
ValueType type) {
BAILOUT("LoadCallerFrameSlot");
MemOperand src(fp, kPointerSize * (caller_slot_idx + 1));
liftoff::Load(this, dst, src, type);
}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
......@@ -443,12 +483,25 @@ void LiftoffAssembler::AssertUnreachable(AbortReason reason) {
void LiftoffAssembler::PushCallerFrameSlot(const VarState& src,
uint32_t src_index,
RegPairHalf half) {
BAILOUT("PushCallerFrameSlot");
switch (src.loc()) {
case VarState::kStack:
ld(at, liftoff::GetStackSlot(src_index));
push(at);
break;
case VarState::kRegister:
PushCallerFrameSlot(src.reg(), src.type());
break;
case VarState::KIntConst: {
li(at, Operand(src.i32_const()));
push(at);
break;
}
}
}
void LiftoffAssembler::PushCallerFrameSlot(LiftoffRegister reg,
ValueType type) {
BAILOUT("PushCallerFrameSlot reg");
liftoff::push(this, reg, type);
}
void LiftoffAssembler::PushRegisters(LiftoffRegList regs) {
......@@ -498,12 +551,12 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
gp_regs.clear(reg);
gp_offset += kPointerSize;
}
addiu(sp, sp, gp_offset);
daddiu(sp, sp, gp_offset);
}
void LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) {
DCHECK_LT(num_stack_slots, (1 << 16) / kPointerSize); // 16 bit immediate
TurboAssembler::DropAndRet(static_cast<int>(num_stack_slots * kPointerSize));
TurboAssembler::DropAndRet(static_cast<int>(num_stack_slots));
}
void LiftoffAssembler::PrepareCCall(wasm::FunctionSig* sig,
......
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