| Index: src/mips64/code-stubs-mips64.cc
|
| diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc
|
| index 2531d6b3f1fd3ed676291449c389196f45b0c9cc..ea9b659a443f8d4bb627e6b19c1ae58877297b0f 100644
|
| --- a/src/mips64/code-stubs-mips64.cc
|
| +++ b/src/mips64/code-stubs-mips64.cc
|
| @@ -1090,14 +1090,34 @@ void CEntryStub::Generate(MacroAssembler* masm) {
|
| // a0 = argc
|
| __ mov(s0, a0);
|
| __ mov(s2, a1);
|
| - // a1 = argv (set in the delay slot after find_ra below).
|
|
|
| // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We
|
| // also need to reserve the 4 argument slots on the stack.
|
|
|
| __ AssertStackIsAligned();
|
|
|
| - __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
|
| + int frame_alignment = MacroAssembler::ActivationFrameAlignment();
|
| + int frame_alignment_mask = frame_alignment - 1;
|
| + int result_stack_size;
|
| + if (result_size() <= 2) {
|
| + // a0 = argc, a1 = argv, a2 = isolate
|
| + __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
|
| + __ mov(a1, s1);
|
| + result_stack_size = 0;
|
| + } else {
|
| + DCHECK_EQ(3, result_size());
|
| + // Allocate additional space for the result.
|
| + result_stack_size =
|
| + ((result_size() * kPointerSize) + frame_alignment_mask) &
|
| + ~frame_alignment_mask;
|
| + __ Dsubu(sp, sp, Operand(result_stack_size));
|
| +
|
| + // a0 = hidden result argument, a1 = argc, a2 = argv, a3 = isolate.
|
| + __ li(a3, Operand(ExternalReference::isolate_address(isolate())));
|
| + __ mov(a2, s1);
|
| + __ mov(a1, a0);
|
| + __ mov(a0, sp);
|
| + }
|
|
|
| // To let the GC traverse the return address of the exit frames, we need to
|
| // know where the return address is. The CEntryStub is unmovable, so
|
| @@ -1109,28 +1129,37 @@ void CEntryStub::Generate(MacroAssembler* masm) {
|
| // Use masm-> here instead of the double-underscore macro since extra
|
| // coverage code can interfere with the proper calculation of ra.
|
| Label find_ra;
|
| - masm->bal(&find_ra); // bal exposes branch delay slot.
|
| - masm->mov(a1, s1);
|
| - masm->bind(&find_ra);
|
| + __ bal(&find_ra); // bal exposes branch delay slot.
|
| + __ nop();
|
| + __ bind(&find_ra);
|
|
|
| // Adjust the value in ra to point to the correct return location, 2nd
|
| // instruction past the real call into C code (the jalr(t9)), and push it.
|
| // This is the return address of the exit frame.
|
| const int kNumInstructionsToJump = 5;
|
| - masm->Daddu(ra, ra, kNumInstructionsToJump * kInt32Size);
|
| - masm->sd(ra, MemOperand(sp)); // This spot was reserved in EnterExitFrame.
|
| + __ Daddu(ra, ra, kNumInstructionsToJump * kInt32Size);
|
| + // This spot was reserved in EnterExitFrame.
|
| + __ sd(ra, MemOperand(sp, result_stack_size));
|
| // Stack space reservation moved to the branch delay slot below.
|
| // Stack is still aligned.
|
|
|
| // Call the C routine.
|
| - masm->mov(t9, s2); // Function pointer to t9 to conform to ABI for PIC.
|
| - masm->jalr(t9);
|
| + __ mov(t9, s2); // Function pointer to t9 to conform to ABI for PIC.
|
| + __ jalr(t9);
|
| // Set up sp in the delay slot.
|
| - masm->daddiu(sp, sp, -kCArgsSlotsSize);
|
| + __ daddiu(sp, sp, -kCArgsSlotsSize);
|
| // Make sure the stored 'ra' points to this position.
|
| DCHECK_EQ(kNumInstructionsToJump,
|
| masm->InstructionsGeneratedSince(&find_ra));
|
| }
|
| + if (result_size() > 2) {
|
| + DCHECK_EQ(3, result_size());
|
| + // Read result values stored on stack.
|
| + __ ld(a0, MemOperand(v0, 2 * kPointerSize));
|
| + __ ld(v1, MemOperand(v0, 1 * kPointerSize));
|
| + __ ld(v0, MemOperand(v0, 0 * kPointerSize));
|
| + }
|
| + // Result returned in v0, v1:v0 or a0:v1:v0 - do not destroy these registers!
|
|
|
| // Check result for exception sentinel.
|
| Label exception_returned;
|
|
|