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) { ...@@ -33,6 +33,44 @@ inline MemOperand GetHalfStackSlot(uint32_t half_index) {
inline MemOperand GetContextOperand() { return MemOperand(fp, -16); } 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 } // namespace liftoff
uint32_t LiftoffAssembler::PrepareStackFrame() { uint32_t LiftoffAssembler::PrepareStackFrame() {
...@@ -233,7 +271,8 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg, ...@@ -233,7 +271,8 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst, void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
uint32_t caller_slot_idx, uint32_t caller_slot_idx,
ValueType type) { 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, void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
...@@ -498,12 +537,39 @@ void LiftoffAssembler::AssertUnreachable(AbortReason reason) { ...@@ -498,12 +537,39 @@ void LiftoffAssembler::AssertUnreachable(AbortReason reason) {
void LiftoffAssembler::PushCallerFrameSlot(const VarState& src, void LiftoffAssembler::PushCallerFrameSlot(const VarState& src,
uint32_t src_index, uint32_t src_index,
RegPairHalf half) { 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, void LiftoffAssembler::PushCallerFrameSlot(LiftoffRegister reg,
ValueType type) { ValueType type) {
BAILOUT("PushCallerFrameSlot reg"); liftoff::push(this, reg, type);
} }
void LiftoffAssembler::PushRegisters(LiftoffRegList regs) { void LiftoffAssembler::PushRegisters(LiftoffRegList regs) {
...@@ -558,7 +624,7 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) { ...@@ -558,7 +624,7 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
void LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) { void LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) {
DCHECK_LT(num_stack_slots, (1 << 16) / kPointerSize); // 16 bit immediate 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, void LiftoffAssembler::PrepareCCall(wasm::FunctionSig* sig,
......
...@@ -28,6 +28,45 @@ inline MemOperand GetStackSlot(uint32_t index) { ...@@ -28,6 +28,45 @@ inline MemOperand GetStackSlot(uint32_t index) {
inline MemOperand GetContextOperand() { return MemOperand(fp, -16); } 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 } // namespace liftoff
uint32_t LiftoffAssembler::PrepareStackFrame() { uint32_t LiftoffAssembler::PrepareStackFrame() {
...@@ -191,7 +230,8 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg, ...@@ -191,7 +230,8 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst, void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
uint32_t caller_slot_idx, uint32_t caller_slot_idx,
ValueType type) { 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, void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
...@@ -443,12 +483,25 @@ void LiftoffAssembler::AssertUnreachable(AbortReason reason) { ...@@ -443,12 +483,25 @@ void LiftoffAssembler::AssertUnreachable(AbortReason reason) {
void LiftoffAssembler::PushCallerFrameSlot(const VarState& src, void LiftoffAssembler::PushCallerFrameSlot(const VarState& src,
uint32_t src_index, uint32_t src_index,
RegPairHalf half) { 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, void LiftoffAssembler::PushCallerFrameSlot(LiftoffRegister reg,
ValueType type) { ValueType type) {
BAILOUT("PushCallerFrameSlot reg"); liftoff::push(this, reg, type);
} }
void LiftoffAssembler::PushRegisters(LiftoffRegList regs) { void LiftoffAssembler::PushRegisters(LiftoffRegList regs) {
...@@ -498,12 +551,12 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) { ...@@ -498,12 +551,12 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
gp_regs.clear(reg); gp_regs.clear(reg);
gp_offset += kPointerSize; gp_offset += kPointerSize;
} }
addiu(sp, sp, gp_offset); daddiu(sp, sp, gp_offset);
} }
void LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) { void LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) {
DCHECK_LT(num_stack_slots, (1 << 16) / kPointerSize); // 16 bit immediate 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, 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