OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 254 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
255 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); | 255 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); |
256 | 256 |
257 // Remove the stub frame. | 257 // Remove the stub frame. |
258 __ LeaveStubFrameAndReturn(T0); | 258 __ LeaveStubFrameAndReturn(T0); |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 // Input parameters: | 262 // Input parameters: |
263 // A1: Smi-tagged argument count, may be zero. | 263 // A1: Smi-tagged argument count, may be zero. |
264 // FP[kLastParamSlotIndex]: Last argument. | 264 // FP[kParamEndSlotFromFp + 1]: Last argument. |
265 static void PushArgumentsArray(Assembler* assembler) { | 265 static void PushArgumentsArray(Assembler* assembler) { |
266 __ TraceSimMsg("PushArgumentsArray"); | 266 __ TraceSimMsg("PushArgumentsArray"); |
267 // Allocate array to store arguments of caller. | 267 // Allocate array to store arguments of caller. |
268 __ mov(A0, NULLREG); | 268 __ mov(A0, NULLREG); |
269 // A0: Null element type for raw Array. | 269 // A0: Null element type for raw Array. |
270 // A1: Smi-tagged argument count, may be zero. | 270 // A1: Smi-tagged argument count, may be zero. |
271 __ BranchLink(&StubCode::AllocateArrayLabel()); | 271 __ BranchLink(&StubCode::AllocateArrayLabel()); |
272 __ TraceSimMsg("PushArgumentsArray return"); | 272 __ TraceSimMsg("PushArgumentsArray return"); |
273 // V0: newly allocated array. | 273 // V0: newly allocated array. |
274 // A1: Smi-tagged argument count, may be zero (was preserved by the stub). | 274 // A1: Smi-tagged argument count, may be zero (was preserved by the stub). |
275 __ Push(V0); // Array is in V0 and on top of stack. | 275 __ Push(V0); // Array is in V0 and on top of stack. |
276 __ sll(T1, A1, 1); | 276 __ sll(T1, A1, 1); |
277 __ addu(T1, FP, T1); | 277 __ addu(T1, FP, T1); |
278 __ AddImmediate(T1, (kLastParamSlotIndex - 1) * kWordSize); | 278 __ AddImmediate(T1, kParamEndSlotFromFp * kWordSize); |
279 // T1: address of first argument on stack. | 279 // T1: address of first argument on stack. |
280 // T2: address of first argument in array. | 280 // T2: address of first argument in array. |
281 | 281 |
282 Label loop, loop_exit; | 282 Label loop, loop_exit; |
283 __ blez(A1, &loop_exit); | 283 __ blez(A1, &loop_exit); |
284 __ delay_slot()->addiu(T2, V0, | 284 __ delay_slot()->addiu(T2, V0, |
285 Immediate(Array::data_offset() - kHeapObjectTag)); | 285 Immediate(Array::data_offset() - kHeapObjectTag)); |
286 __ Bind(&loop); | 286 __ Bind(&loop); |
287 __ lw(TMP, Address(T1)); | 287 __ lw(TMP, Address(T1)); |
288 __ addiu(A1, A1, Immediate(-Smi::RawValue(1))); | 288 __ addiu(A1, A1, Immediate(-Smi::RawValue(1))); |
(...skipping 12 matching lines...) Expand all Loading... |
301 // called, the stub accesses the receiver from this location directly | 301 // called, the stub accesses the receiver from this location directly |
302 // when trying to resolve the call. | 302 // when trying to resolve the call. |
303 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | 303 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
304 __ TraceSimMsg("InstanceFunctionLookupStub"); | 304 __ TraceSimMsg("InstanceFunctionLookupStub"); |
305 __ EnterStubFrame(); | 305 __ EnterStubFrame(); |
306 | 306 |
307 // Load the receiver. | 307 // Load the receiver. |
308 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | 308 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
309 __ sll(TMP1, A1, 1); // A1 is Smi. | 309 __ sll(TMP1, A1, 1); // A1 is Smi. |
310 __ addu(TMP1, FP, TMP1); | 310 __ addu(TMP1, FP, TMP1); |
311 __ lw(T1, Address(TMP1, (kLastParamSlotIndex - 1) * kWordSize)); | 311 __ lw(T1, Address(TMP1, kParamEndSlotFromFp * kWordSize)); |
312 | 312 |
313 // Push space for the return value. | 313 // Push space for the return value. |
314 // Push the receiver. | 314 // Push the receiver. |
315 // Push TMP1 data object. | 315 // Push TMP1 data object. |
316 // Push arguments descriptor array. | 316 // Push arguments descriptor array. |
317 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 317 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
318 __ sw(NULLREG, Address(SP, 3 * kWordSize)); | 318 __ sw(NULLREG, Address(SP, 3 * kWordSize)); |
319 __ sw(T1, Address(SP, 2 * kWordSize)); | 319 __ sw(T1, Address(SP, 2 * kWordSize)); |
320 __ sw(S5, Address(SP, 1 * kWordSize)); | 320 __ sw(S5, Address(SP, 1 * kWordSize)); |
321 __ sw(S4, Address(SP, 0 * kWordSize)); | 321 __ sw(S4, Address(SP, 0 * kWordSize)); |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 __ lw(T2, FieldAddress(CTX, Context::isolate_offset())); | 766 __ lw(T2, FieldAddress(CTX, Context::isolate_offset())); |
767 | 767 |
768 // Save the top exit frame info. Use T0 as a temporary register. | 768 // Save the top exit frame info. Use T0 as a temporary register. |
769 // StackFrameIterator reads the top exit frame info saved in this frame. | 769 // StackFrameIterator reads the top exit frame info saved in this frame. |
770 __ lw(T0, Address(T2, Isolate::top_exit_frame_info_offset())); | 770 __ lw(T0, Address(T2, Isolate::top_exit_frame_info_offset())); |
771 __ sw(ZR, Address(T2, Isolate::top_exit_frame_info_offset())); | 771 __ sw(ZR, Address(T2, Isolate::top_exit_frame_info_offset())); |
772 | 772 |
773 // Save the old Context pointer. Use T1 as a temporary register. | 773 // Save the old Context pointer. Use T1 as a temporary register. |
774 // Note that VisitObjectPointers will find this saved Context pointer during | 774 // Note that VisitObjectPointers will find this saved Context pointer during |
775 // GC marking, since it traverses any information between SP and | 775 // GC marking, since it traverses any information between SP and |
776 // FP - kExitLinkOffsetInEntryFrame. | 776 // FP - kExitLinkSlotFromEntryFp. |
777 // EntryFrame::SavedContext reads the context saved in this frame. | 777 // EntryFrame::SavedContext reads the context saved in this frame. |
778 __ lw(T1, Address(T2, Isolate::top_context_offset())); | 778 __ lw(T1, Address(T2, Isolate::top_context_offset())); |
779 | 779 |
780 // The constants kSavedContextOffsetInEntryFrame and | 780 // The constants kSavedContextSlotFromEntryFp and |
781 // kExitLinkOffsetInEntryFrame must be kept in sync with the code below. | 781 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
| 782 ASSERT(kExitLinkSlotFromEntryFp == -10); |
| 783 ASSERT(kSavedContextSlotFromEntryFp == -11); |
782 __ sw(T0, Address(SP, 1 * kWordSize)); | 784 __ sw(T0, Address(SP, 1 * kWordSize)); |
783 __ sw(T1, Address(SP, 0 * kWordSize)); | 785 __ sw(T1, Address(SP, 0 * kWordSize)); |
784 | 786 |
785 // After the call, The stack pointer is restored to this location. | 787 // After the call, The stack pointer is restored to this location. |
786 // Pushed A3, S0-7, T0, T1 = 11. | 788 // Pushed A3, S0-7, T0, T1 = 11. |
787 const intptr_t kSavedContextOffsetInEntryFrame = -11 * kWordSize; | |
788 | 789 |
789 // Load arguments descriptor array into S4, which is passed to Dart code. | 790 // Load arguments descriptor array into S4, which is passed to Dart code. |
790 __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle)); | 791 __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle)); |
791 | 792 |
792 // Load number of arguments into S5. | 793 // Load number of arguments into S5. |
793 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | 794 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
794 __ SmiUntag(T1); | 795 __ SmiUntag(T1); |
795 | 796 |
796 // Compute address of 'arguments array' data area into A2. | 797 // Compute address of 'arguments array' data area into A2. |
797 __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); | 798 __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); |
(...skipping 19 matching lines...) Expand all Loading... |
817 | 818 |
818 // Call the Dart code entrypoint. | 819 // Call the Dart code entrypoint. |
819 __ jalr(A0); // S4 is the arguments descriptor array. | 820 __ jalr(A0); // S4 is the arguments descriptor array. |
820 __ TraceSimMsg("InvokeDartCodeStub return"); | 821 __ TraceSimMsg("InvokeDartCodeStub return"); |
821 | 822 |
822 // Read the saved new Context pointer. | 823 // Read the saved new Context pointer. |
823 __ lw(CTX, Address(FP, kNewContextOffset)); | 824 __ lw(CTX, Address(FP, kNewContextOffset)); |
824 __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); | 825 __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); |
825 | 826 |
826 // Get rid of arguments pushed on the stack. | 827 // Get rid of arguments pushed on the stack. |
827 __ AddImmediate(SP, FP, kSavedContextOffsetInEntryFrame); | 828 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); |
828 | 829 |
829 // Load Isolate pointer from Context structure into CTX. Drop Context. | 830 // Load Isolate pointer from Context structure into CTX. Drop Context. |
830 __ lw(CTX, FieldAddress(CTX, Context::isolate_offset())); | 831 __ lw(CTX, FieldAddress(CTX, Context::isolate_offset())); |
831 | 832 |
832 // Restore the saved Context pointer into the Isolate structure. | 833 // Restore the saved Context pointer into the Isolate structure. |
833 // Uses T1 as a temporary register for this. | 834 // Uses T1 as a temporary register for this. |
834 // Restore the saved top exit frame info back into the Isolate structure. | 835 // Restore the saved top exit frame info back into the Isolate structure. |
835 // Uses T0 as a temporary register for this. | 836 // Uses T0 as a temporary register for this. |
836 __ lw(T1, Address(SP, 0 * kWordSize)); | 837 __ lw(T1, Address(SP, 0 * kWordSize)); |
837 __ lw(T0, Address(SP, 1 * kWordSize)); | 838 __ lw(T0, Address(SP, 1 * kWordSize)); |
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2124 __ Bind(&done); | 2125 __ Bind(&done); |
2125 __ lw(T0, Address(SP, 0 * kWordSize)); | 2126 __ lw(T0, Address(SP, 0 * kWordSize)); |
2126 __ lw(T1, Address(SP, 1 * kWordSize)); | 2127 __ lw(T1, Address(SP, 1 * kWordSize)); |
2127 __ Ret(); | 2128 __ Ret(); |
2128 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); | 2129 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); |
2129 } | 2130 } |
2130 | 2131 |
2131 } // namespace dart | 2132 } // namespace dart |
2132 | 2133 |
2133 #endif // defined TARGET_ARCH_MIPS | 2134 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |