| Index: src/mips/macro-assembler-mips.cc
|
| diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
|
| index 2072b39e7a6d7240b2236f148f34724a6a2d2926..4578014b37da0ec4d3436edc9eb349fca36580c7 100644
|
| --- a/src/mips/macro-assembler-mips.cc
|
| +++ b/src/mips/macro-assembler-mips.cc
|
| @@ -2438,8 +2438,15 @@ void MacroAssembler::Jump(intptr_t target,
|
| Register rs,
|
| const Operand& rt,
|
| BranchDelaySlot bd) {
|
| + Label skip;
|
| + if (cond != cc_always) {
|
| + Branch(USE_DELAY_SLOT, &skip, NegateCondition(cond), rs, rt);
|
| + }
|
| + // The first instruction of 'li' may be placed in the delay slot.
|
| + // This is not an issue, t9 is expected to be clobbered anyway.
|
| li(t9, Operand(target, rmode));
|
| - Jump(t9, cond, rs, rt, bd);
|
| + Jump(t9, al, zero_reg, Operand(zero_reg), bd);
|
| + bind(&skip);
|
| }
|
|
|
|
|
| @@ -2569,7 +2576,7 @@ void MacroAssembler::Call(Handle<Code> code,
|
| rmode = RelocInfo::CODE_TARGET_WITH_ID;
|
| }
|
| Call(reinterpret_cast<Address>(code.location()), rmode, cond, rs, rt, bd);
|
| - ASSERT_EQ(CallSize(code, rmode, ast_id, cond, rs, rt),
|
| + ASSERT_EQ(CallSize(code, rmode, ast_id, cond, rs, rt, bd),
|
| SizeOfCodeGeneratedSince(&start));
|
| }
|
|
|
| @@ -2639,14 +2646,16 @@ void MacroAssembler::Jalr(Label* L, BranchDelaySlot bdslot) {
|
| nop();
|
| }
|
|
|
| +void MacroAssembler::DropAndRet(int drop) {
|
| + Ret(USE_DELAY_SLOT);
|
| + addiu(sp, sp, drop * kPointerSize);
|
| +}
|
|
|
| void MacroAssembler::DropAndRet(int drop,
|
| Condition cond,
|
| Register r1,
|
| const Operand& r2) {
|
| - // This is a workaround to make sure only one branch instruction is
|
| - // generated. It relies on Drop and Ret not creating branches if
|
| - // cond == cc_always.
|
| + // Both Drop and Ret need to be conditional.
|
| Label skip;
|
| if (cond != cc_always) {
|
| Branch(&skip, NegateCondition(cond), r1, r2);
|
| @@ -2713,8 +2722,8 @@ void MacroAssembler::Push(Handle<Object> handle) {
|
| #ifdef ENABLE_DEBUGGER_SUPPORT
|
|
|
| void MacroAssembler::DebugBreak() {
|
| - mov(a0, zero_reg);
|
| - li(a1, Operand(ExternalReference(Runtime::kDebugBreak, isolate())));
|
| + PrepareCEntryArgs(0);
|
| + PrepareCEntryFunction(ExternalReference(Runtime::kDebugBreak, isolate()));
|
| CEntryStub ces(1);
|
| ASSERT(AllowThisStubCall(&ces));
|
| Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
|
| @@ -3876,10 +3885,13 @@ void MacroAssembler::GetObjectType(Register object,
|
| // -----------------------------------------------------------------------------
|
| // Runtime calls.
|
|
|
| -void MacroAssembler::CallStub(CodeStub* stub, Condition cond,
|
| - Register r1, const Operand& r2) {
|
| +void MacroAssembler::CallStub(CodeStub* stub,
|
| + Condition cond,
|
| + Register r1,
|
| + const Operand& r2,
|
| + BranchDelaySlot bd) {
|
| ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
|
| - Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond, r1, r2);
|
| + Call(stub->GetCode(), RelocInfo::CODE_TARGET, kNoASTId, cond, r1, r2, bd);
|
| }
|
|
|
|
|
| @@ -3962,8 +3974,7 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
|
| lw(t1, MemOperand(at));
|
| Branch(&promote_scheduled_exception, ne, t0, Operand(t1));
|
| li(s0, Operand(stack_space));
|
| - LeaveExitFrame(false, s0);
|
| - Ret();
|
| + LeaveExitFrame(false, s0, true);
|
|
|
| bind(&promote_scheduled_exception);
|
| TailCallExternalReference(
|
| @@ -4161,8 +4172,8 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
|
| // arguments passed in because it is constant. At some point we
|
| // should remove this need and make the runtime routine entry code
|
| // smarter.
|
| - li(a0, num_arguments);
|
| - li(a1, Operand(ExternalReference(f, isolate())));
|
| + PrepareCEntryArgs(num_arguments);
|
| + PrepareCEntryFunction(ExternalReference(f, isolate()));
|
| CEntryStub stub(1);
|
| CallStub(&stub);
|
| }
|
| @@ -4170,8 +4181,8 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
|
|
|
| void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
|
| const Runtime::Function* function = Runtime::FunctionForId(id);
|
| - li(a0, Operand(function->nargs));
|
| - li(a1, Operand(ExternalReference(function, isolate())));
|
| + PrepareCEntryArgs(function->nargs);
|
| + PrepareCEntryFunction(ExternalReference(function, isolate()));
|
| CEntryStub stub(1, kSaveFPRegs);
|
| CallStub(&stub);
|
| }
|
| @@ -4183,12 +4194,13 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
|
|
|
|
|
| void MacroAssembler::CallExternalReference(const ExternalReference& ext,
|
| - int num_arguments) {
|
| - li(a0, Operand(num_arguments));
|
| - li(a1, Operand(ext));
|
| + int num_arguments,
|
| + BranchDelaySlot bd) {
|
| + PrepareCEntryArgs(num_arguments);
|
| + PrepareCEntryFunction(ext);
|
|
|
| CEntryStub stub(1);
|
| - CallStub(&stub);
|
| + CallStub(&stub, al, zero_reg, Operand(zero_reg), bd);
|
| }
|
|
|
|
|
| @@ -4199,7 +4211,7 @@ void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
|
| // arguments passed in because it is constant. At some point we
|
| // should remove this need and make the runtime routine entry code
|
| // smarter.
|
| - li(a0, Operand(num_arguments));
|
| + PrepareCEntryArgs(num_arguments);
|
| JumpToExternalReference(ext);
|
| }
|
|
|
| @@ -4213,10 +4225,16 @@ void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
|
| }
|
|
|
|
|
| -void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
|
| - li(a1, Operand(builtin));
|
| +void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
|
| + BranchDelaySlot bd) {
|
| + PrepareCEntryFunction(builtin);
|
| CEntryStub stub(1);
|
| - Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
| + Jump(stub.GetCode(),
|
| + RelocInfo::CODE_TARGET,
|
| + al,
|
| + zero_reg,
|
| + Operand(zero_reg),
|
| + bd);
|
| }
|
|
|
|
|
| @@ -4563,7 +4581,8 @@ void MacroAssembler::EnterExitFrame(bool save_doubles,
|
|
|
|
|
| void MacroAssembler::LeaveExitFrame(bool save_doubles,
|
| - Register argument_count) {
|
| + Register argument_count,
|
| + bool do_return) {
|
| // Optionally restore all double registers.
|
| if (save_doubles) {
|
| // Remember: we only need to restore every 2nd double FPU value.
|
| @@ -4589,11 +4608,17 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
|
| mov(sp, fp); // Respect ABI stack constraint.
|
| lw(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset));
|
| lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset));
|
| - addiu(sp, sp, 8);
|
| +
|
| if (argument_count.is_valid()) {
|
| sll(t8, argument_count, kPointerSizeLog2);
|
| addu(sp, sp, t8);
|
| }
|
| +
|
| + if (do_return) {
|
| + Ret(USE_DELAY_SLOT);
|
| + // If returning, the instruction in the delay slot will be the addiu below.
|
| + }
|
| + addiu(sp, sp, 8);
|
| }
|
|
|
|
|
|
|