| Index: src/ppc/macro-assembler-ppc.cc
|
| diff --git a/src/ppc/macro-assembler-ppc.cc b/src/ppc/macro-assembler-ppc.cc
|
| index 14759de0da334b700d2f96e720489672948b493b..3f8640a408fdf9b9393c78c164d387705424c0a9 100644
|
| --- a/src/ppc/macro-assembler-ppc.cc
|
| +++ b/src/ppc/macro-assembler-ppc.cc
|
| @@ -1093,6 +1093,67 @@ void MacroAssembler::MovFromFloatParameter(const DoubleRegister dst) {
|
| Move(dst, d1);
|
| }
|
|
|
| +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;
|
| + ShiftLeftImm(dst_reg, caller_args_count_reg, Operand(kPointerSizeLog2));
|
| + add(dst_reg, fp, dst_reg);
|
| + addi(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()) {
|
| + ShiftLeftImm(src_reg, callee_args_count.reg(), Operand(kPointerSizeLog2));
|
| + add(src_reg, sp, src_reg);
|
| + addi(src_reg, src_reg, Operand(kPointerSize));
|
| + } else {
|
| + Add(src_reg, sp, (callee_args_count.immediate() + 1) * kPointerSize, r0);
|
| + }
|
| +
|
| + if (FLAG_debug_code) {
|
| + cmpl(src_reg, dst_reg);
|
| + Check(lt, kStackAccessBelowStackPointer);
|
| + }
|
| +
|
| + // Restore caller's frame pointer and return address now as they will be
|
| + // overwritten by the copying loop.
|
| + RestoreFrameStateForTailCall();
|
| +
|
| + // 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;
|
| + if (callee_args_count.is_reg()) {
|
| + addi(tmp_reg, callee_args_count.reg(), Operand(1)); // +1 for receiver
|
| + } else {
|
| + mov(tmp_reg, Operand(callee_args_count.immediate() + 1));
|
| + }
|
| + mtctr(tmp_reg);
|
| + bind(&loop);
|
| + LoadPU(tmp_reg, MemOperand(src_reg, -kPointerSize));
|
| + StorePU(tmp_reg, MemOperand(dst_reg, -kPointerSize));
|
| + bdnz(&loop);
|
| +
|
| + // Leave current frame.
|
| + mr(sp, dst_reg);
|
| +}
|
|
|
| void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
| const ParameterCount& actual, Label* done,
|
|
|