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" |
| 9 #include "vm/code_generator.h" |
| 10 #include "vm/dart_entry.h" |
| 11 #include "vm/instructions.h" |
| 12 #include "vm/stack_frame.h" |
8 #include "vm/stub_code.h" | 13 #include "vm/stub_code.h" |
9 | 14 |
10 #define __ assembler-> | 15 #define __ assembler-> |
11 | 16 |
12 namespace dart { | 17 namespace dart { |
13 | 18 |
14 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 19 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
15 __ Unimplemented("CallToRuntime stub"); | 20 __ Unimplemented("CallToRuntime stub"); |
16 } | 21 } |
17 | 22 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { | 64 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { |
60 __ Unimplemented("AllocateArray stub"); | 65 __ Unimplemented("AllocateArray stub"); |
61 } | 66 } |
62 | 67 |
63 | 68 |
64 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { | 69 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { |
65 __ Unimplemented("CallClosureFunction stub"); | 70 __ Unimplemented("CallClosureFunction stub"); |
66 } | 71 } |
67 | 72 |
68 | 73 |
| 74 // Called when invoking Dart code from C++ (VM code). |
| 75 // Input parameters: |
| 76 // RA : points to return address. |
| 77 // A0 : entrypoint of the Dart function to call. |
| 78 // A1 : arguments descriptor array. |
| 79 // A2 : arguments array. |
| 80 // A3 : new context containing the current isolate pointer. |
69 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 81 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
70 __ Unimplemented("InvokeDartCode stub"); | 82 // Save frame pointer coming in. |
| 83 __ EnterStubFrame(); |
| 84 |
| 85 // Save new context and C++ ABI callee-saved registers. |
| 86 const intptr_t kNewContextOffset = |
| 87 -(1 + kAbiPreservedCpuRegCount) * kWordSize; |
| 88 |
| 89 __ addiu(SP, SP, Immediate(-(3 + kAbiPreservedCpuRegCount) * kWordSize)); |
| 90 for (int i = S0; i <= S7; i++) { |
| 91 Register r = static_cast<Register>(i); |
| 92 __ sw(r, Address(SP, (i - S0 + 3) * kWordSize)); |
| 93 } |
| 94 __ sw(A3, Address(SP, 2 * kWordSize)); |
| 95 |
| 96 // The new Context structure contains a pointer to the current Isolate |
| 97 // structure. Cache the Context pointer in the CTX register so that it is |
| 98 // available in generated code and calls to Isolate::Current() need not be |
| 99 // done. The assumption is that this register will never be clobbered by |
| 100 // compiled or runtime stub code. |
| 101 |
| 102 // Cache the new Context pointer into CTX while executing Dart code. |
| 103 __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle)); |
| 104 |
| 105 // Load Isolate pointer from Context structure into temporary register R8. |
| 106 __ lw(T2, FieldAddress(CTX, Context::isolate_offset())); |
| 107 |
| 108 // Save the top exit frame info. Use R5 as a temporary register. |
| 109 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 110 __ lw(S5, Address(T2, Isolate::top_exit_frame_info_offset())); |
| 111 __ LoadImmediate(T0, 0); |
| 112 __ sw(T0, Address(T2, Isolate::top_exit_frame_info_offset())); |
| 113 |
| 114 // Save the old Context pointer. Use S4 as a temporary register. |
| 115 // Note that VisitObjectPointers will find this saved Context pointer during |
| 116 // GC marking, since it traverses any information between SP and |
| 117 // FP - kExitLinkOffsetInEntryFrame. |
| 118 // EntryFrame::SavedContext reads the context saved in this frame. |
| 119 __ lw(S4, Address(T2, Isolate::top_context_offset())); |
| 120 |
| 121 // The constants kSavedContextOffsetInEntryFrame and |
| 122 // kExitLinkOffsetInEntryFrame must be kept in sync with the code below. |
| 123 __ sw(S5, Address(SP, 1 * kWordSize)); |
| 124 __ sw(S4, Address(SP, 0 * kWordSize)); |
| 125 |
| 126 // after the call, The stack pointer is restored to this location. |
| 127 // Pushed A3, S0-7, S4, S5 = 11. |
| 128 const intptr_t kSavedContextOffsetInEntryFrame = -11 * kWordSize; |
| 129 |
| 130 // Load arguments descriptor array into S4, which is passed to Dart code. |
| 131 __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle)); |
| 132 |
| 133 // Load number of arguments into S5. |
| 134 __ lw(S5, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
| 135 __ SmiUntag(S5); |
| 136 |
| 137 // Compute address of 'arguments array' data area into A2. |
| 138 __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); |
| 139 __ addiu(A2, A2, Immediate(Array::data_offset() - kHeapObjectTag)); |
| 140 |
| 141 // Set up arguments for the Dart call. |
| 142 Label push_arguments; |
| 143 Label done_push_arguments; |
| 144 |
| 145 __ beq(S5, ZR, &done_push_arguments); // check if there are arguments. |
| 146 __ LoadImmediate(A1, 0); |
| 147 __ Bind(&push_arguments); |
| 148 __ lw(A3, Address(A2)); |
| 149 __ Push(A3); |
| 150 __ addiu(A2, A2, Immediate(kWordSize)); |
| 151 __ addiu(A1, A1, Immediate(1)); |
| 152 __ subu(T0, A1, S5); |
| 153 __ bltz(T0, &push_arguments); |
| 154 |
| 155 __ Bind(&done_push_arguments); |
| 156 |
| 157 |
| 158 // Call the Dart code entrypoint. |
| 159 __ jalr(A0); // S4 is the arguments descriptor array. |
| 160 |
| 161 // Read the saved new Context pointer. |
| 162 __ lw(CTX, Address(FP, kNewContextOffset)); |
| 163 __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); |
| 164 |
| 165 // Get rid of arguments pushed on the stack. |
| 166 __ addiu(SP, FP, Immediate(kSavedContextOffsetInEntryFrame)); |
| 167 |
| 168 // Load Isolate pointer from Context structure into CTX. Drop Context. |
| 169 __ lw(CTX, FieldAddress(CTX, Context::isolate_offset())); |
| 170 |
| 171 // Restore the saved Context pointer into the Isolate structure. |
| 172 // Uses S4 as a temporary register for this. |
| 173 // Restore the saved top exit frame info back into the Isolate structure. |
| 174 // Uses S5 as a temporary register for this. |
| 175 __ lw(S4, Address(SP, 0 * kWordSize)); |
| 176 __ lw(S5, Address(SP, 1 * kWordSize)); |
| 177 __ sw(S4, Address(CTX, Isolate::top_context_offset())); |
| 178 __ sw(S5, Address(CTX, Isolate::top_exit_frame_info_offset())); |
| 179 |
| 180 // Restore C++ ABI callee-saved registers. |
| 181 for (int i = S0; i <= S7; i++) { |
| 182 Register r = static_cast<Register>(i); |
| 183 __ lw(r, Address(SP, (i - S0 + 3) * kWordSize)); |
| 184 } |
| 185 __ lw(A3, Address(SP)); |
| 186 __ addiu(SP, SP, Immediate((3 + kAbiPreservedCpuRegCount) * kWordSize)); |
| 187 |
| 188 // Restore the frame pointer and return. |
| 189 __ LeaveStubFrame(); |
| 190 __ Ret(); |
71 } | 191 } |
72 | 192 |
73 | 193 |
74 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 194 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
75 __ Unimplemented("AllocateContext stub"); | 195 __ Unimplemented("AllocateContext stub"); |
76 } | 196 } |
77 | 197 |
78 | 198 |
79 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { | 199 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { |
80 __ Unimplemented("UpdateStoreBuffer stub"); | 200 __ Unimplemented("UpdateStoreBuffer stub"); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 } | 342 } |
223 | 343 |
224 | 344 |
225 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { | 345 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
226 __ Unimplemented("IdenticalWithNumberCheck stub"); | 346 __ Unimplemented("IdenticalWithNumberCheck stub"); |
227 } | 347 } |
228 | 348 |
229 } // namespace dart | 349 } // namespace dart |
230 | 350 |
231 #endif // defined TARGET_ARCH_MIPS | 351 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |