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 -(2 + kAbiPreservedCpuRegCount) * kWordSize; | |
88 | |
89 __ addiu(SP, SP, Immediate(-(1 + kAbiPreservedCpuRegCount) * kWordSize)); | |
90 for (int i = S0; i <= S7; i++) { | |
91 Register r = static_cast<Register>(i); | |
92 __ sw(r, Address(SP, (i - S0 + 1) * kWordSize)); | |
93 } | |
94 __ sw(A3, Address(SP)); | |
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 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
regis
2013/03/29 00:23:32
The SP could be adjusted only once above.
zra
2013/03/29 17:10:44
Done.
| |
124 __ sw(S4, Address(SP)); | |
125 __ sw(S5, Address(SP, kWordSize)); | |
126 | |
127 // after the call, The stack pointer is restored to this location. | |
128 const intptr_t kSavedContextOffsetInEntryFrame = -12 * 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)); | |
176 __ lw(S5, Address(SP, kWordSize)); | |
177 __ addiu(SP, SP, Immediate(2 * kWordSize)); | |
regis
2013/03/29 00:23:32
ditto
zra
2013/03/29 17:10:44
Done.
| |
178 __ sw(S4, Address(CTX, Isolate::top_context_offset())); | |
179 __ sw(S5, Address(CTX, Isolate::top_exit_frame_info_offset())); | |
180 | |
181 // Restore C++ ABI callee-saved registers. | |
182 for (int i = S0; i <= S7; i++) { | |
183 Register r = static_cast<Register>(i); | |
184 __ lw(r, Address(SP, (i - S0 + 1) * kWordSize)); | |
185 } | |
186 __ lw(A3, Address(SP)); | |
187 __ addiu(SP, SP, Immediate((1 + kAbiPreservedCpuRegCount) * kWordSize)); | |
188 | |
189 // Restore the frame pointer and return. | |
190 __ LeaveStubFrame(); | |
191 __ Ret(); | |
71 } | 192 } |
72 | 193 |
73 | 194 |
74 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 195 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
75 __ Unimplemented("AllocateContext stub"); | 196 __ Unimplemented("AllocateContext stub"); |
76 } | 197 } |
77 | 198 |
78 | 199 |
79 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { | 200 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { |
80 __ Unimplemented("UpdateStoreBuffer stub"); | 201 __ Unimplemented("UpdateStoreBuffer stub"); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 } | 343 } |
223 | 344 |
224 | 345 |
225 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { | 346 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
226 __ Unimplemented("IdenticalWithNumberCheck stub"); | 347 __ Unimplemented("IdenticalWithNumberCheck stub"); |
227 } | 348 } |
228 | 349 |
229 } // namespace dart | 350 } // namespace dart |
230 | 351 |
231 #endif // defined TARGET_ARCH_MIPS | 352 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |