Index: src/mips/lithium-codegen-mips.cc |
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc |
index 7dc341f2edfa43e4424ed429036dd852374c3c04..0a52c080fac373ef64d5ea67dfea3846516ab7ad 100644 |
--- a/src/mips/lithium-codegen-mips.cc |
+++ b/src/mips/lithium-codegen-mips.cc |
@@ -98,6 +98,38 @@ void LChunkBuilder::Abort(BailoutReason reason) { |
} |
+void LCodeGen::SaveCallerDoubles() { |
+ ASSERT(info()->saves_caller_doubles()); |
+ ASSERT(NeedsEagerFrame()); |
+ Comment(";;; Save clobbered callee double registers"); |
+ int count = 0; |
+ BitVector* doubles = chunk()->allocated_double_registers(); |
+ BitVector::Iterator save_iterator(doubles); |
+ while (!save_iterator.Done()) { |
+ __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
+ MemOperand(sp, count * kDoubleSize)); |
+ save_iterator.Advance(); |
+ count++; |
+ } |
+} |
+ |
+ |
+void LCodeGen::RestoreCallerDoubles() { |
+ ASSERT(info()->saves_caller_doubles()); |
+ ASSERT(NeedsEagerFrame()); |
+ Comment(";;; Restore clobbered callee double registers"); |
+ BitVector* doubles = chunk()->allocated_double_registers(); |
+ BitVector::Iterator save_iterator(doubles); |
+ int count = 0; |
+ while (!save_iterator.Done()) { |
+ __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
+ MemOperand(sp, count * kDoubleSize)); |
+ save_iterator.Advance(); |
+ count++; |
+ } |
+} |
+ |
+ |
bool LCodeGen::GeneratePrologue() { |
ASSERT(is_generating()); |
@@ -160,16 +192,7 @@ bool LCodeGen::GeneratePrologue() { |
} |
if (info()->saves_caller_doubles()) { |
- Comment(";;; Save clobbered callee double registers"); |
- int count = 0; |
- BitVector* doubles = chunk()->allocated_double_registers(); |
- BitVector::Iterator save_iterator(doubles); |
- while (!save_iterator.Done()) { |
- __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
- MemOperand(sp, count * kDoubleSize)); |
- save_iterator.Advance(); |
- count++; |
- } |
+ SaveCallerDoubles(); |
} |
// Possibly allocate a local context. |
@@ -298,6 +321,7 @@ bool LCodeGen::GenerateDeoptJumpTable() { |
} |
__ li(t9, Operand(ExternalReference::ForDeoptEntry(entry))); |
if (deopt_jump_table_[i].needs_frame) { |
+ ASSERT(!info()->saves_caller_doubles()); |
if (needs_frame.is_bound()) { |
__ Branch(&needs_frame); |
} else { |
@@ -313,6 +337,10 @@ bool LCodeGen::GenerateDeoptJumpTable() { |
__ Call(t9); |
} |
} else { |
+ if (info()->saves_caller_doubles()) { |
+ ASSERT(info()->IsStub()); |
+ RestoreCallerDoubles(); |
+ } |
__ Call(t9); |
} |
} |
@@ -786,7 +814,10 @@ void LCodeGen::DeoptimizeIf(Condition condition, |
} |
ASSERT(info()->IsStub() || frame_is_built_); |
- if (condition == al && frame_is_built_) { |
+ // Go through jump table if we need to handle condition, build frame, or |
+ // restore caller doubles. |
+ if (condition == al && frame_is_built_ && |
+ !info()->saves_caller_doubles()) { |
__ Call(entry, RelocInfo::RUNTIME_ENTRY, condition, src1, src2); |
} else { |
// We often have several deopts to the same entry, reuse the last |
@@ -2806,16 +2837,7 @@ void LCodeGen::DoReturn(LReturn* instr) { |
__ CallRuntime(Runtime::kTraceExit, 1); |
} |
if (info()->saves_caller_doubles()) { |
- ASSERT(NeedsEagerFrame()); |
- BitVector* doubles = chunk()->allocated_double_registers(); |
- BitVector::Iterator save_iterator(doubles); |
- int count = 0; |
- while (!save_iterator.Done()) { |
- __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
- MemOperand(sp, count * kDoubleSize)); |
- save_iterator.Advance(); |
- count++; |
- } |
+ RestoreCallerDoubles(); |
} |
int no_frame_start = -1; |
if (NeedsEagerFrame()) { |