| Index: src/mips/macro-assembler-mips.cc
|
| diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
|
| index 76b724ceebc6e41257ea0bd8e0fac541acc430d9..dd9e7d980e87438b7ff4d8b1d01745310aedc692 100644
|
| --- a/src/mips/macro-assembler-mips.cc
|
| +++ b/src/mips/macro-assembler-mips.cc
|
| @@ -4095,6 +4095,65 @@ void MacroAssembler::MovToFloatParameters(DoubleRegister src1,
|
| // -----------------------------------------------------------------------------
|
| // JavaScript invokes.
|
|
|
| +void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
|
| + Register caller_args_count_reg,
|
| + Register scratch0, Register scratch1) {
|
| +#if DEBUG
|
| + if (callee_args_count.is_reg()) {
|
| + DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0,
|
| + scratch1));
|
| + } else {
|
| + DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1));
|
| + }
|
| +#endif
|
| +
|
| + // Calculate the end of destination area where we will put the arguments
|
| + // after we drop current frame. We add kPointerSize to count the receiver
|
| + // argument which is not included into formal parameters count.
|
| + Register dst_reg = scratch0;
|
| + Lsa(dst_reg, fp, caller_args_count_reg, kPointerSizeLog2);
|
| + Addu(dst_reg, dst_reg,
|
| + Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize));
|
| +
|
| + Register src_reg = caller_args_count_reg;
|
| + // Calculate the end of source area. +kPointerSize is for the receiver.
|
| + if (callee_args_count.is_reg()) {
|
| + Lsa(src_reg, sp, callee_args_count.reg(), kPointerSizeLog2);
|
| + Addu(src_reg, src_reg, Operand(kPointerSize));
|
| + } else {
|
| + Addu(src_reg, sp,
|
| + Operand((callee_args_count.immediate() + 1) * kPointerSize));
|
| + }
|
| +
|
| + if (FLAG_debug_code) {
|
| + Check(lo, kStackAccessBelowStackPointer, src_reg, Operand(dst_reg));
|
| + }
|
| +
|
| + // Restore caller's frame pointer and return address now as they will be
|
| + // overwritten by the copying loop.
|
| + lw(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
|
| + lw(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
| +
|
| + // Now copy callee arguments to the caller frame going backwards to avoid
|
| + // callee arguments corruption (source and destination areas could overlap).
|
| +
|
| + // Both src_reg and dst_reg are pointing to the word after the one to copy,
|
| + // so they must be pre-decremented in the loop.
|
| + Register tmp_reg = scratch1;
|
| + Label loop, entry;
|
| + Branch(&entry);
|
| + bind(&loop);
|
| + Subu(src_reg, src_reg, Operand(kPointerSize));
|
| + Subu(dst_reg, dst_reg, Operand(kPointerSize));
|
| + lw(tmp_reg, MemOperand(src_reg));
|
| + sw(tmp_reg, MemOperand(dst_reg));
|
| + bind(&entry);
|
| + Branch(&loop, ne, sp, Operand(src_reg));
|
| +
|
| + // Leave current frame.
|
| + mov(sp, dst_reg);
|
| +}
|
| +
|
| void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
| const ParameterCount& actual,
|
| Label* done,
|
|
|