Index: src/mips/macro-assembler-mips.cc |
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc |
index 0d1eed56c572a66749c1c6fa70c10e694604023c..b2311435e418935ac5c68d240340c75173a6845c 100644 |
--- a/src/mips/macro-assembler-mips.cc |
+++ b/src/mips/macro-assembler-mips.cc |
@@ -193,6 +193,77 @@ void MacroAssembler::RecordWriteHelper(Register object, |
sw(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
} |
+// Push and pop all registers that can hold pointers. |
+void MacroAssembler::PushSafepointRegisters() { |
+ // Safepoints expect a block of kNumSafepointRegisters values on the |
+ // stack, so adjust the stack for unsaved registers. |
+ const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; |
+ ASSERT(num_unsaved >= 0); |
+ Subu(sp, sp, Operand(num_unsaved * kPointerSize)); |
+ MultiPush(kSafepointSavedRegisters); |
+} |
+ |
+void MacroAssembler::PopSafepointRegisters() { |
+ const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; |
+ MultiPop(kSafepointSavedRegisters); |
+ Addu(sp, sp, Operand(num_unsaved * kPointerSize)); |
+} |
+ |
+void MacroAssembler::PushSafepointRegistersAndDoubles() { |
+ PushSafepointRegisters(); |
+ Subu(sp, sp, Operand(FPURegister::kNumAllocatableRegisters * kDoubleSize)); |
+ for (int i = 0; i < FPURegister::kNumAllocatableRegisters; i+=2) { |
Søren Thygesen Gjesse
2011/05/24 07:21:00
Indentation.
|
+ FPURegister reg = FPURegister::FromAllocationIndex(i); |
+ sdc1(reg, MemOperand(sp, i * kDoubleSize)); |
+ } |
+} |
+ |
+void MacroAssembler::PopSafepointRegistersAndDoubles() { |
+ for (int i = 0; i < FPURegister::kNumAllocatableRegisters; i+=2) { |
Søren Thygesen Gjesse
2011/05/24 07:21:00
Indentation.
|
+ FPURegister reg = FPURegister::FromAllocationIndex(i); |
+ ldc1(reg, MemOperand(sp, i * kDoubleSize)); |
+ } |
+ Addu(sp, sp, Operand(FPURegister::kNumAllocatableRegisters * kDoubleSize)); |
+ PopSafepointRegisters(); |
+} |
+ |
+void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src, |
+ Register dst) { |
+ sw(src, SafepointRegistersAndDoublesSlot(dst)); |
+} |
+ |
+ |
+void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) { |
+ sw(src, SafepointRegisterSlot(dst)); |
+} |
+ |
+ |
+void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { |
+ lw(dst, SafepointRegisterSlot(src)); |
+} |
+ |
+ |
+int MacroAssembler::SafepointRegisterStackIndex(int reg_code) { |
+ // The registers are pushed starting with the highest encoding, |
+ // which means that lowest encodings are closest to the stack pointer. |
+ return kSafepointRegisterStackIndexMap[reg_code]; |
+} |
+ |
+ |
+MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) { |
+ return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); |
+} |
+ |
+ |
+MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { |
+ // General purpose registers are pushed last on the stack. |
+ int doubles_size = FPURegister::kNumAllocatableRegisters * kDoubleSize; |
+ int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; |
+ return MemOperand(sp, doubles_size + register_offset); |
+} |
+ |
+ |
+ |
void MacroAssembler::InNewSpace(Register object, |
Register scratch, |
@@ -1903,13 +1974,6 @@ void MacroAssembler::Call(Label* target) { |
} |
-void MacroAssembler::Move(Register dst, Register src) { |
- if (!dst.is(src)) { |
- mov(dst, src); |
- } |
-} |
- |
- |
#ifdef ENABLE_DEBUGGER_SUPPORT |
void MacroAssembler::DebugBreak() { |
@@ -2585,17 +2649,56 @@ void MacroAssembler::CheckMap(Register obj, |
void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) { |
+ CpuFeatures::Scope scope(FPU); |
if (IsMipsSoftFloatABI) { |
- mtc1(v0, dst); |
- mtc1(v1, FPURegister::from_code(dst.code() + 1)); |
+ Move(v0, v1, dst); |
} else { |
- if (!dst.is(f0)) { |
- mov_d(dst, f0); // Reg f0 is o32 ABI FP return value. |
+ Move(f0, dst); // Reg f0 is o32 ABI FP return value. |
+ } |
+} |
+ |
+ |
+void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg) { |
+ CpuFeatures::Scope scope(FPU); |
+ if (!IsMipsSoftFloatABI) { |
+ Move(f12, dreg); |
+ } else { |
+ Move(a0, a1, dreg); |
+ } |
+} |
+ |
+ |
+void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg1, |
+ DoubleRegister dreg2) { |
+ CpuFeatures::Scope scope(FPU); |
+ if (!IsMipsSoftFloatABI) { |
+ if (dreg2.is(f12)) { |
+ ASSERT(!dreg1.is(f14)); |
+ Move(f14, dreg2); |
+ Move(f12, dreg1); |
+ } else { |
+ Move(f12, dreg1); |
+ Move(f14, dreg2); |
} |
+ } else { |
+ Move(a0, a1, dreg1); |
+ Move(a2, a3, dreg2); |
} |
} |
+void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg, |
+ Register reg) { |
+ CpuFeatures::Scope scope(FPU); |
+ if (!IsMipsSoftFloatABI) { |
+ Move(f12, dreg); |
+ Move(a2, reg); |
+ } else { |
+ Move(a2, reg); |
+ Move(a0, a1, dreg); |
+ } |
+} |
+ |
// ----------------------------------------------------------------------------- |
// JavaScript invokes. |
@@ -3490,14 +3593,27 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, |
li(t8, Operand(ExternalReference(Isolate::k_context_address, isolate()))); |
sw(cp, MemOperand(t8)); |
- // Ensure we are not saving doubles, since it's not implemented yet. |
- ASSERT(save_doubles == 0); |
+ const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); |
+ if (save_doubles) { |
+ // The stack must be allign to 0 modulo 8 for stores with sdc1. |
+ ASSERT(kDoubleSize == frame_alignment); |
+ if (frame_alignment > 0) { |
+ ASSERT(IsPowerOf2(frame_alignment)); |
+ And(sp, sp, Operand(-frame_alignment)); // Align stack. |
+ } |
+ int space = FPURegister::kNumRegisters * kDoubleSize; |
+ Subu(sp, sp, Operand(space)); |
+ // Remember: we only need to save every 2nd double FPU value. |
+ for (int i = 0; i < FPURegister::kNumRegisters; i+=2) { |
+ FPURegister reg = FPURegister::from_code(i); |
+ sdc1(reg, MemOperand(sp, i * kDoubleSize)); |
+ } |
+ } |
// Reserve place for the return address, stack space and an optional slot |
// (used by the DirectCEntryStub to hold the return value if a struct is |
// returned) and align the frame preparing for calling the runtime function. |
ASSERT(stack_space >= 0); |
- const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); |
Subu(sp, sp, Operand((stack_space + 2) * kPointerSize)); |
if (frame_alignment > 0) { |
ASSERT(IsPowerOf2(frame_alignment)); |
@@ -3513,8 +3629,15 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, |
void MacroAssembler::LeaveExitFrame(bool save_doubles, |
Register argument_count) { |
- // Ensure we are not restoring doubles, since it's not implemented yet. |
- ASSERT(save_doubles == 0); |
+ // Optionally restore all double registers. |
+ if (save_doubles) { |
+ // Remember: we only need to restore every 2nd double FPU value. |
+ lw(t8, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
+ for (int i = 0; i < FPURegister::kNumRegisters; i+=2) { |
+ FPURegister reg = FPURegister::from_code(i); |
+ ldc1(reg, MemOperand(t8, i * kDoubleSize + kPointerSize)); |
+ } |
+ } |
// Clear top frame. |
li(t8, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); |
@@ -3837,6 +3960,17 @@ void MacroAssembler::CallCFunctionHelper(Register function, |
#undef BRANCH_ARGS_CHECK |
+void MacroAssembler::LoadInstanceDescriptors(Register map, |
+ Register descriptors) { |
+ lw(descriptors, |
+ FieldMemOperand(map, Map::kInstanceDescriptorsOrBitField3Offset)); |
+ Label not_smi; |
+ JumpIfNotSmi(descriptors, ¬_smi); |
+ li(descriptors, Operand(FACTORY->empty_descriptor_array())); |
+ bind(¬_smi); |
+} |
+ |
+ |
CodePatcher::CodePatcher(byte* address, int instructions) |
: address_(address), |
instructions_(instructions), |