From 62cb792c5ee246acc630340fc40d536c985abff3 Mon Sep 17 00:00:00 2001 From: Zhao Jiazhong Date: Mon, 27 Jul 2020 23:38:33 -0400 Subject: [PATCH] [mips][wasm][liftoff] Add direct and indirect tail-calls Port b64cede5d8d2dd7056812488c6ebe95fe36c29dc https://crrev.com/c/2289970 Port 5de28709202142f9455ae039b8c9212baa2aa100 https://crrev.com/c/2316304 Change-Id: Ia4e24558b10adef196ab167137a9a5b6db98754b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2321950 Reviewed-by: Clemens Backes Commit-Queue: Zhao Jiazhong Cr-Commit-Position: refs/heads/master@{#69089} --- .../baseline/mips/liftoff-assembler-mips.h | 36 +++++++++++++++++++ .../mips64/liftoff-assembler-mips64.h | 36 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/wasm/baseline/mips/liftoff-assembler-mips.h b/src/wasm/baseline/mips/liftoff-assembler-mips.h index 802074630f..5c0427eb91 100644 --- a/src/wasm/baseline/mips/liftoff-assembler-mips.h +++ b/src/wasm/baseline/mips/liftoff-assembler-mips.h @@ -275,6 +275,29 @@ int LiftoffAssembler::PrepareStackFrame() { return offset; } +void LiftoffAssembler::PrepareTailCall(int num_callee_stack_params, + int stack_param_delta) { + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); + + // Push the return address and frame pointer to complete the stack frame. + Lw(scratch, MemOperand(fp, 4)); + Push(scratch); + Lw(scratch, MemOperand(fp, 0)); + Push(scratch); + + // Shift the whole frame upwards. + int slot_count = num_callee_stack_params + 2; + for (int i = slot_count - 1; i >= 0; --i) { + Lw(scratch, MemOperand(sp, i * 4)); + Sw(scratch, MemOperand(fp, (i - stack_param_delta) * 4)); + } + + // Set the new stack and frame pointer. + addiu(sp, fp, -stack_param_delta * 4); + Pop(ra, fp); +} + void LiftoffAssembler::PatchPrepareStackFrame(int offset, int frame_size) { // We can't run out of space, just pass anything big enough to not cause the // assembler to try to grow the buffer. @@ -2575,6 +2598,10 @@ void LiftoffAssembler::CallNativeWasmCode(Address addr) { Call(addr, RelocInfo::WASM_CALL); } +void LiftoffAssembler::TailCallNativeWasmCode(Address addr) { + Jump(addr, RelocInfo::WASM_CALL); +} + void LiftoffAssembler::CallIndirect(const wasm::FunctionSig* sig, compiler::CallDescriptor* call_descriptor, Register target) { @@ -2586,6 +2613,15 @@ void LiftoffAssembler::CallIndirect(const wasm::FunctionSig* sig, } } +void LiftoffAssembler::TailCallIndirect(Register target) { + if (target == no_reg) { + Pop(kScratchReg); + Jump(kScratchReg); + } else { + Jump(target); + } +} + void LiftoffAssembler::CallRuntimeStub(WasmCode::RuntimeStubId sid) { // A direct call to a wasm runtime stub defined in this module. // Just encode the stub index. This will be patched at relocation. diff --git a/src/wasm/baseline/mips64/liftoff-assembler-mips64.h b/src/wasm/baseline/mips64/liftoff-assembler-mips64.h index 4c4fa6d255..de6bb6e548 100644 --- a/src/wasm/baseline/mips64/liftoff-assembler-mips64.h +++ b/src/wasm/baseline/mips64/liftoff-assembler-mips64.h @@ -240,6 +240,29 @@ int LiftoffAssembler::PrepareStackFrame() { return offset; } +void LiftoffAssembler::PrepareTailCall(int num_callee_stack_params, + int stack_param_delta) { + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); + + // Push the return address and frame pointer to complete the stack frame. + Ld(scratch, MemOperand(fp, 8)); + Push(scratch); + Ld(scratch, MemOperand(fp, 0)); + Push(scratch); + + // Shift the whole frame upwards. + int slot_count = num_callee_stack_params + 2; + for (int i = slot_count - 1; i >= 0; --i) { + Ld(scratch, MemOperand(sp, i * 8)); + Sd(scratch, MemOperand(fp, (i - stack_param_delta) * 8)); + } + + // Set the new stack and frame pointer. + daddiu(sp, fp, -stack_param_delta * 8); + Pop(ra, fp); +} + void LiftoffAssembler::PatchPrepareStackFrame(int offset, int frame_size) { // We can't run out of space, just pass anything big enough to not cause the // assembler to try to grow the buffer. @@ -2678,6 +2701,10 @@ void LiftoffAssembler::CallNativeWasmCode(Address addr) { Call(addr, RelocInfo::WASM_CALL); } +void LiftoffAssembler::TailCallNativeWasmCode(Address addr) { + Jump(addr, RelocInfo::WASM_CALL); +} + void LiftoffAssembler::CallIndirect(const wasm::FunctionSig* sig, compiler::CallDescriptor* call_descriptor, Register target) { @@ -2689,6 +2716,15 @@ void LiftoffAssembler::CallIndirect(const wasm::FunctionSig* sig, } } +void LiftoffAssembler::TailCallIndirect(Register target) { + if (target == no_reg) { + Pop(kScratchReg); + Jump(kScratchReg); + } else { + Jump(target); + } +} + void LiftoffAssembler::CallRuntimeStub(WasmCode::RuntimeStubId sid) { // A direct call to a wasm runtime stub defined in this module. // Just encode the stub index. This will be patched at relocation.