diff --git a/src/wasm/baseline/liftoff-assembler.cc b/src/wasm/baseline/liftoff-assembler.cc index 0c2dad6cb2..6c00b9a374 100644 --- a/src/wasm/baseline/liftoff-assembler.cc +++ b/src/wasm/baseline/liftoff-assembler.cc @@ -11,6 +11,7 @@ #include "src/compiler/wasm-compiler.h" #include "src/macro-assembler-inl.h" #include "src/wasm/function-body-decoder-impl.h" +#include "src/wasm/wasm-linkage.h" #include "src/wasm/wasm-opcodes.h" namespace v8 { @@ -620,6 +621,22 @@ void LiftoffAssembler::ParallelRegisterMove( } } +void LiftoffAssembler::MoveToReturnRegisters(FunctionSig* sig) { + // We do not support multi-value yet. + DCHECK_EQ(1, sig->return_count()); + ValueType return_type = sig->GetReturn(0); + StackTransferRecipe stack_transfers(this); + LiftoffRegister return_reg = + needs_reg_pair(return_type) + ? LiftoffRegister::ForPair(kGpReturnRegisters[0], + kGpReturnRegisters[1]) + : reg_class_for(return_type) == kGpReg + ? LiftoffRegister(kGpReturnRegisters[0]) + : LiftoffRegister(kFpReturnRegisters[0]); + stack_transfers.LoadIntoRegister(return_reg, cache_state_.stack_state.back(), + cache_state_.stack_height() - 1); +} + #ifdef ENABLE_SLOW_DCHECKS bool LiftoffAssembler::ValidateCacheState() const { uint32_t register_use_count[kAfterMaxLiftoffRegCode] = {0}; diff --git a/src/wasm/baseline/liftoff-assembler.h b/src/wasm/baseline/liftoff-assembler.h index 6476f0c22d..64a2d8c25b 100644 --- a/src/wasm/baseline/liftoff-assembler.h +++ b/src/wasm/baseline/liftoff-assembler.h @@ -338,6 +338,8 @@ class LiftoffAssembler : public TurboAssembler { }; void ParallelRegisterMove(Vector); + void MoveToReturnRegisters(FunctionSig*); + #ifdef ENABLE_SLOW_DCHECKS // Validate that the register use counts reflect the state of the cache. bool ValidateCacheState() const; diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index 49c5ab19d4..26484ac9e4 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -1075,25 +1075,17 @@ class LiftoffCompiler { __ cache_state()->stack_state.pop_back(); } - void DoReturn(FullDecoder* decoder, Vector values, bool implicit) { + void DoReturn(FullDecoder* decoder, Vector /*values*/, bool implicit) { if (implicit) { DCHECK_EQ(1, decoder->control_depth()); Control* func_block = decoder->control_at(0); __ bind(func_block->label.get()); __ cache_state()->Steal(func_block->label_state); + TraceCacheState(decoder); } - if (!values.is_empty()) { - if (values.size() > 1) return unsupported(decoder, "multi-return"); - LiftoffRegister reg = __ PopToRegister(); - LiftoffRegister return_reg = - kNeedI64RegPair && values[0].type == kWasmI64 - ? LiftoffRegister::ForPair(kGpReturnRegisters[0], - kGpReturnRegisters[1]) - : reg_class_for(values[0].type) == kGpReg - ? LiftoffRegister(kGpReturnRegisters[0]) - : LiftoffRegister(kFpReturnRegisters[0]); - if (reg != return_reg) __ Move(return_reg, reg, values[0].type); - } + size_t num_returns = decoder->sig_->return_count(); + if (num_returns > 1) return unsupported(decoder, "multi-return"); + if (num_returns > 0) __ MoveToReturnRegisters(decoder->sig_); __ LeaveFrame(StackFrame::WASM_COMPILED); __ DropStackSlotsAndRet( static_cast(descriptor_->StackParameterCount()));