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 30 matching lines...) Expand all Loading... |
41 const intptr_t exitframe_last_param_slot_from_fp = 2; | 41 const intptr_t exitframe_last_param_slot_from_fp = 2; |
42 | 42 |
43 __ SetPrologueOffset(); | 43 __ SetPrologueOffset(); |
44 __ TraceSimMsg("CallToRuntimeStub"); | 44 __ TraceSimMsg("CallToRuntimeStub"); |
45 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 45 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
46 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker | 46 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker |
47 __ sw(RA, Address(SP, 1 * kWordSize)); | 47 __ sw(RA, Address(SP, 1 * kWordSize)); |
48 __ sw(FP, Address(SP, 0 * kWordSize)); | 48 __ sw(FP, Address(SP, 0 * kWordSize)); |
49 __ mov(FP, SP); | 49 __ mov(FP, SP); |
50 | 50 |
51 __ LoadIsolate(A0); | 51 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0); |
| 52 __ LoadIsolate(S6); |
52 | 53 |
53 // Save exit frame information to enable stack walking as we are about | 54 // Save exit frame information to enable stack walking as we are about |
54 // to transition to Dart VM C++ code. | 55 // to transition to Dart VM C++ code. |
55 __ sw(SP, Address(A0, Isolate::top_exit_frame_info_offset())); | 56 __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset())); |
56 | |
57 // Save current Context pointer into Isolate structure. | |
58 __ sw(CTX, Address(A0, Isolate::top_context_offset())); | |
59 | |
60 // Cache Isolate pointer into CTX while executing runtime code. | |
61 __ mov(CTX, A0); | |
62 | 57 |
63 #if defined(DEBUG) | 58 #if defined(DEBUG) |
64 { Label ok; | 59 { Label ok; |
65 // Check that we are always entering from Dart code. | 60 // Check that we are always entering from Dart code. |
66 __ lw(T0, Address(A0, Isolate::vm_tag_offset())); | 61 __ lw(T0, Address(S6, Isolate::vm_tag_offset())); |
67 __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok); | 62 __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok); |
68 __ Stop("Not coming from Dart code."); | 63 __ Stop("Not coming from Dart code."); |
69 __ Bind(&ok); | 64 __ Bind(&ok); |
70 } | 65 } |
71 #endif | 66 #endif |
72 | 67 |
73 // Mark that the isolate is executing VM code. | 68 // Mark that the isolate is executing VM code. |
74 __ sw(S5, Address(A0, Isolate::vm_tag_offset())); | 69 __ sw(S5, Address(S6, Isolate::vm_tag_offset())); |
75 | 70 |
76 // Reserve space for arguments and align frame before entering C++ world. | 71 // Reserve space for arguments and align frame before entering C++ world. |
77 // NativeArguments are passed in registers. | 72 // NativeArguments are passed in registers. |
78 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 73 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
79 __ ReserveAlignedFrameSpace(4 * kWordSize); // Reserve space for arguments. | 74 __ ReserveAlignedFrameSpace(4 * kWordSize); // Reserve space for arguments. |
80 | 75 |
81 // Pass NativeArguments structure by value and call runtime. | 76 // Pass NativeArguments structure by value and call runtime. |
82 // Registers A0, A1, A2, and A3 are used. | 77 // Registers A0, A1, A2, and A3 are used. |
83 | 78 |
84 ASSERT(isolate_offset == 0 * kWordSize); | 79 ASSERT(isolate_offset == 0 * kWordSize); |
85 // Set isolate in NativeArgs: A0 already contains CTX. | 80 // Set isolate in NativeArgs. |
| 81 __ mov(A0, S6); |
86 | 82 |
87 // There are no runtime calls to closures, so we do not need to set the tag | 83 // There are no runtime calls to closures, so we do not need to set the tag |
88 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 84 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
89 ASSERT(argc_tag_offset == 1 * kWordSize); | 85 ASSERT(argc_tag_offset == 1 * kWordSize); |
90 __ mov(A1, S4); // Set argc in NativeArguments. | 86 __ mov(A1, S4); // Set argc in NativeArguments. |
91 | 87 |
92 ASSERT(argv_offset == 2 * kWordSize); | 88 ASSERT(argv_offset == 2 * kWordSize); |
93 __ sll(A2, S4, 2); | 89 __ sll(A2, S4, 2); |
94 __ addu(A2, FP, A2); // Compute argv. | 90 __ addu(A2, FP, A2); // Compute argv. |
95 // Set argv in NativeArguments. | 91 // Set argv in NativeArguments. |
96 __ addiu(A2, A2, Immediate(exitframe_last_param_slot_from_fp * kWordSize)); | 92 __ addiu(A2, A2, Immediate(exitframe_last_param_slot_from_fp * kWordSize)); |
97 | 93 |
98 | 94 |
99 // Call runtime or redirection via simulator. | 95 // Call runtime or redirection via simulator. |
100 // We defensively always jalr through T9 because it is sometimes required by | 96 // We defensively always jalr through T9 because it is sometimes required by |
101 // the MIPS ABI. | 97 // the MIPS ABI. |
102 __ mov(T9, S5); | 98 __ mov(T9, S5); |
103 __ jalr(T9); | 99 __ jalr(T9); |
104 | 100 |
105 ASSERT(retval_offset == 3 * kWordSize); | 101 ASSERT(retval_offset == 3 * kWordSize); |
106 // Retval is next to 1st argument. | 102 // Retval is next to 1st argument. |
107 __ delay_slot()->addiu(A3, A2, Immediate(kWordSize)); | 103 __ delay_slot()->addiu(A3, A2, Immediate(kWordSize)); |
108 __ TraceSimMsg("CallToRuntimeStub return"); | 104 __ TraceSimMsg("CallToRuntimeStub return"); |
109 | 105 |
110 // Mark that the isolate is executing Dart code. | 106 // Mark that the isolate is executing Dart code. |
111 __ LoadImmediate(A2, VMTag::kDartTagId); | 107 __ LoadImmediate(A2, VMTag::kDartTagId); |
112 __ sw(A2, Address(CTX, Isolate::vm_tag_offset())); | 108 __ sw(A2, Address(S6, Isolate::vm_tag_offset())); |
113 | 109 |
114 // Reset exit frame information in Isolate structure. | 110 // Reset exit frame information in Isolate structure. |
115 __ sw(ZR, Address(CTX, Isolate::top_exit_frame_info_offset())); | 111 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset())); |
116 | |
117 // Load Context pointer from Isolate structure into A2. | |
118 __ lw(A2, Address(CTX, Isolate::top_context_offset())); | |
119 | |
120 // Load null. | |
121 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | |
122 | |
123 // Reset Context pointer in Isolate structure. | |
124 __ sw(TMP, Address(CTX, Isolate::top_context_offset())); | |
125 | |
126 // Cache Context pointer into CTX while executing Dart code. | |
127 __ mov(CTX, A2); | |
128 | 112 |
129 __ mov(SP, FP); | 113 __ mov(SP, FP); |
130 __ lw(RA, Address(SP, 1 * kWordSize)); | 114 __ lw(RA, Address(SP, 1 * kWordSize)); |
131 __ lw(FP, Address(SP, 0 * kWordSize)); | 115 __ lw(FP, Address(SP, 0 * kWordSize)); |
132 __ Ret(); | 116 __ Ret(); |
133 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); | 117 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); |
134 } | 118 } |
135 | 119 |
136 | 120 |
137 // Print the stop message. | 121 // Print the stop message. |
(...skipping 28 matching lines...) Expand all Loading... |
166 const intptr_t retval_offset = NativeArguments::retval_offset(); | 150 const intptr_t retval_offset = NativeArguments::retval_offset(); |
167 | 151 |
168 __ SetPrologueOffset(); | 152 __ SetPrologueOffset(); |
169 __ TraceSimMsg("CallNativeCFunctionStub"); | 153 __ TraceSimMsg("CallNativeCFunctionStub"); |
170 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 154 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
171 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker | 155 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker |
172 __ sw(RA, Address(SP, 1 * kWordSize)); | 156 __ sw(RA, Address(SP, 1 * kWordSize)); |
173 __ sw(FP, Address(SP, 0 * kWordSize)); | 157 __ sw(FP, Address(SP, 0 * kWordSize)); |
174 __ mov(FP, SP); | 158 __ mov(FP, SP); |
175 | 159 |
176 __ LoadIsolate(A0); | 160 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0); |
| 161 __ LoadIsolate(S6); |
177 | 162 |
178 // Save exit frame information to enable stack walking as we are about | 163 // Save exit frame information to enable stack walking as we are about |
179 // to transition to native code. | 164 // to transition to native code. |
180 __ sw(SP, Address(A0, Isolate::top_exit_frame_info_offset())); | 165 __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset())); |
181 | |
182 // Save current Context pointer into Isolate structure. | |
183 __ sw(CTX, Address(A0, Isolate::top_context_offset())); | |
184 | |
185 // Cache Isolate pointer into CTX while executing native code. | |
186 __ mov(CTX, A0); | |
187 | 166 |
188 #if defined(DEBUG) | 167 #if defined(DEBUG) |
189 { Label ok; | 168 { Label ok; |
190 // Check that we are always entering from Dart code. | 169 // Check that we are always entering from Dart code. |
191 __ lw(T0, Address(A0, Isolate::vm_tag_offset())); | 170 __ lw(T0, Address(S6, Isolate::vm_tag_offset())); |
192 __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok); | 171 __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok); |
193 __ Stop("Not coming from Dart code."); | 172 __ Stop("Not coming from Dart code."); |
194 __ Bind(&ok); | 173 __ Bind(&ok); |
195 } | 174 } |
196 #endif | 175 #endif |
197 | 176 |
198 // Mark that the isolate is executing Native code. | 177 // Mark that the isolate is executing Native code. |
199 __ sw(T5, Address(A0, Isolate::vm_tag_offset())); | 178 __ sw(T5, Address(S6, Isolate::vm_tag_offset())); |
200 | 179 |
201 // Initialize NativeArguments structure and call native function. | 180 // Initialize NativeArguments structure and call native function. |
202 // Registers A0, A1, A2, and A3 are used. | 181 // Registers A0, A1, A2, and A3 are used. |
203 | 182 |
204 ASSERT(isolate_offset == 0 * kWordSize); | 183 ASSERT(isolate_offset == 0 * kWordSize); |
205 // Set isolate in NativeArgs: A0 already contains CTX. | 184 // Set isolate in NativeArgs. |
| 185 __ mov(A0, S6); |
206 | 186 |
207 // There are no native calls to closures, so we do not need to set the tag | 187 // There are no native calls to closures, so we do not need to set the tag |
208 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 188 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
209 ASSERT(argc_tag_offset == 1 * kWordSize); | 189 ASSERT(argc_tag_offset == 1 * kWordSize); |
210 // Set argc in NativeArguments: A1 already contains argc. | 190 // Set argc in NativeArguments: A1 already contains argc. |
211 | 191 |
212 ASSERT(argv_offset == 2 * kWordSize); | 192 ASSERT(argv_offset == 2 * kWordSize); |
213 // Set argv in NativeArguments: A2 already contains argv. | 193 // Set argv in NativeArguments: A2 already contains argv. |
214 | 194 |
215 ASSERT(retval_offset == 3 * kWordSize); | 195 ASSERT(retval_offset == 3 * kWordSize); |
(...skipping 19 matching lines...) Expand all Loading... |
235 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); | 215 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); |
236 __ LoadImmediate(T9, entry); | 216 __ LoadImmediate(T9, entry); |
237 __ jalr(T9); | 217 __ jalr(T9); |
238 #else | 218 #else |
239 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); | 219 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); |
240 #endif | 220 #endif |
241 __ TraceSimMsg("CallNativeCFunctionStub return"); | 221 __ TraceSimMsg("CallNativeCFunctionStub return"); |
242 | 222 |
243 // Mark that the isolate is executing Dart code. | 223 // Mark that the isolate is executing Dart code. |
244 __ LoadImmediate(A2, VMTag::kDartTagId); | 224 __ LoadImmediate(A2, VMTag::kDartTagId); |
245 __ sw(A2, Address(CTX, Isolate::vm_tag_offset())); | 225 __ sw(A2, Address(S6, Isolate::vm_tag_offset())); |
246 | 226 |
247 // Reset exit frame information in Isolate structure. | 227 // Reset exit frame information in Isolate structure. |
248 __ sw(ZR, Address(CTX, Isolate::top_exit_frame_info_offset())); | 228 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset())); |
249 | |
250 // Load Context pointer from Isolate structure into A2. | |
251 __ lw(A2, Address(CTX, Isolate::top_context_offset())); | |
252 | |
253 // Load null. | |
254 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | |
255 | |
256 // Reset Context pointer in Isolate structure. | |
257 __ sw(TMP, Address(CTX, Isolate::top_context_offset())); | |
258 | |
259 // Cache Context pointer into CTX while executing Dart code. | |
260 __ mov(CTX, A2); | |
261 | 229 |
262 __ mov(SP, FP); | 230 __ mov(SP, FP); |
263 __ lw(RA, Address(SP, 1 * kWordSize)); | 231 __ lw(RA, Address(SP, 1 * kWordSize)); |
264 __ lw(FP, Address(SP, 0 * kWordSize)); | 232 __ lw(FP, Address(SP, 0 * kWordSize)); |
265 __ Ret(); | 233 __ Ret(); |
266 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); | 234 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); |
267 } | 235 } |
268 | 236 |
269 | 237 |
270 // Input parameters: | 238 // Input parameters: |
271 // RA : return address. | 239 // RA : return address. |
272 // SP : address of return value. | 240 // SP : address of return value. |
273 // T5 : address of the native function to call. | 241 // T5 : address of the native function to call. |
274 // A2 : address of first argument in argument array. | 242 // A2 : address of first argument in argument array. |
275 // A1 : argc_tag including number of arguments and function kind. | 243 // A1 : argc_tag including number of arguments and function kind. |
276 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 244 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
277 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 245 const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
278 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 246 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
279 const intptr_t argv_offset = NativeArguments::argv_offset(); | 247 const intptr_t argv_offset = NativeArguments::argv_offset(); |
280 const intptr_t retval_offset = NativeArguments::retval_offset(); | 248 const intptr_t retval_offset = NativeArguments::retval_offset(); |
281 | 249 |
282 __ SetPrologueOffset(); | 250 __ SetPrologueOffset(); |
283 __ TraceSimMsg("CallNativeCFunctionStub"); | 251 __ TraceSimMsg("CallNativeCFunctionStub"); |
284 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 252 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
285 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker | 253 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker |
286 __ sw(RA, Address(SP, 1 * kWordSize)); | 254 __ sw(RA, Address(SP, 1 * kWordSize)); |
287 __ sw(FP, Address(SP, 0 * kWordSize)); | 255 __ sw(FP, Address(SP, 0 * kWordSize)); |
288 __ mov(FP, SP); | 256 __ mov(FP, SP); |
289 | 257 |
290 __ LoadIsolate(A0); | 258 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0); |
| 259 __ LoadIsolate(S6); |
291 | 260 |
292 // Save exit frame information to enable stack walking as we are about | 261 // Save exit frame information to enable stack walking as we are about |
293 // to transition to native code. | 262 // to transition to native code. |
294 __ sw(SP, Address(A0, Isolate::top_exit_frame_info_offset())); | 263 __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset())); |
295 | |
296 // Save current Context pointer into Isolate structure. | |
297 __ sw(CTX, Address(A0, Isolate::top_context_offset())); | |
298 | |
299 // Cache Isolate pointer into CTX while executing native code. | |
300 __ mov(CTX, A0); | |
301 | 264 |
302 #if defined(DEBUG) | 265 #if defined(DEBUG) |
303 { Label ok; | 266 { Label ok; |
304 // Check that we are always entering from Dart code. | 267 // Check that we are always entering from Dart code. |
305 __ lw(T0, Address(A0, Isolate::vm_tag_offset())); | 268 __ lw(T0, Address(S6, Isolate::vm_tag_offset())); |
306 __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok); | 269 __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok); |
307 __ Stop("Not coming from Dart code."); | 270 __ Stop("Not coming from Dart code."); |
308 __ Bind(&ok); | 271 __ Bind(&ok); |
309 } | 272 } |
310 #endif | 273 #endif |
311 | 274 |
312 // Mark that the isolate is executing Native code. | 275 // Mark that the isolate is executing Native code. |
313 __ sw(T5, Address(A0, Isolate::vm_tag_offset())); | 276 __ sw(T5, Address(S6, Isolate::vm_tag_offset())); |
314 | 277 |
315 // Initialize NativeArguments structure and call native function. | 278 // Initialize NativeArguments structure and call native function. |
316 // Registers A0, A1, A2, and A3 are used. | 279 // Registers A0, A1, A2, and A3 are used. |
317 | 280 |
318 ASSERT(isolate_offset == 0 * kWordSize); | 281 ASSERT(isolate_offset == 0 * kWordSize); |
319 // Set isolate in NativeArgs: A0 already contains CTX. | 282 // Set isolate in NativeArgs. |
| 283 __ mov(A0, S6); |
320 | 284 |
321 // There are no native calls to closures, so we do not need to set the tag | 285 // There are no native calls to closures, so we do not need to set the tag |
322 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 286 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
323 ASSERT(argc_tag_offset == 1 * kWordSize); | 287 ASSERT(argc_tag_offset == 1 * kWordSize); |
324 // Set argc in NativeArguments: A1 already contains argc. | 288 // Set argc in NativeArguments: A1 already contains argc. |
325 | 289 |
326 ASSERT(argv_offset == 2 * kWordSize); | 290 ASSERT(argv_offset == 2 * kWordSize); |
327 // Set argv in NativeArguments: A2 already contains argv. | 291 // Set argv in NativeArguments: A2 already contains argv. |
328 | 292 |
329 ASSERT(retval_offset == 3 * kWordSize); | 293 ASSERT(retval_offset == 3 * kWordSize); |
(...skipping 14 matching lines...) Expand all Loading... |
344 // Call native function or redirection via simulator. | 308 // Call native function or redirection via simulator. |
345 | 309 |
346 // We defensively always jalr through T9 because it is sometimes required by | 310 // We defensively always jalr through T9 because it is sometimes required by |
347 // the MIPS ABI. | 311 // the MIPS ABI. |
348 __ mov(T9, T5); | 312 __ mov(T9, T5); |
349 __ jalr(T9); | 313 __ jalr(T9); |
350 __ TraceSimMsg("CallNativeCFunctionStub return"); | 314 __ TraceSimMsg("CallNativeCFunctionStub return"); |
351 | 315 |
352 // Mark that the isolate is executing Dart code. | 316 // Mark that the isolate is executing Dart code. |
353 __ LoadImmediate(A2, VMTag::kDartTagId); | 317 __ LoadImmediate(A2, VMTag::kDartTagId); |
354 __ sw(A2, Address(CTX, Isolate::vm_tag_offset())); | 318 __ sw(A2, Address(S6, Isolate::vm_tag_offset())); |
355 | 319 |
356 // Reset exit frame information in Isolate structure. | 320 // Reset exit frame information in Isolate structure. |
357 __ sw(ZR, Address(CTX, Isolate::top_exit_frame_info_offset())); | 321 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset())); |
358 | |
359 // Load Context pointer from Isolate structure into A2. | |
360 __ lw(A2, Address(CTX, Isolate::top_context_offset())); | |
361 | |
362 // Load null. | |
363 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | |
364 | |
365 // Reset Context pointer in Isolate structure. | |
366 __ sw(TMP, Address(CTX, Isolate::top_context_offset())); | |
367 | |
368 // Cache Context pointer into CTX while executing Dart code. | |
369 __ mov(CTX, A2); | |
370 | 322 |
371 __ mov(SP, FP); | 323 __ mov(SP, FP); |
372 __ lw(RA, Address(SP, 1 * kWordSize)); | 324 __ lw(RA, Address(SP, 1 * kWordSize)); |
373 __ lw(FP, Address(SP, 0 * kWordSize)); | 325 __ lw(FP, Address(SP, 0 * kWordSize)); |
374 __ Ret(); | 326 __ Ret(); |
375 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); | 327 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); |
376 } | 328 } |
377 | 329 |
378 | 330 |
379 // Input parameters: | 331 // Input parameters: |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 __ BranchPatchable(&stub_code->FixAllocateArrayStubTargetLabel()); | 805 __ BranchPatchable(&stub_code->FixAllocateArrayStubTargetLabel()); |
854 } | 806 } |
855 | 807 |
856 | 808 |
857 // Called when invoking Dart code from C++ (VM code). | 809 // Called when invoking Dart code from C++ (VM code). |
858 // Input parameters: | 810 // Input parameters: |
859 // RA : points to return address. | 811 // RA : points to return address. |
860 // A0 : entrypoint of the Dart function to call. | 812 // A0 : entrypoint of the Dart function to call. |
861 // A1 : arguments descriptor array. | 813 // A1 : arguments descriptor array. |
862 // A2 : arguments array. | 814 // A2 : arguments array. |
863 // A3 : new context containing the current isolate pointer. | |
864 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 815 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
865 // Save frame pointer coming in. | 816 // Save frame pointer coming in. |
866 __ TraceSimMsg("InvokeDartCodeStub"); | 817 __ TraceSimMsg("InvokeDartCodeStub"); |
867 __ EnterFrame(); | 818 __ EnterFrame(); |
868 | 819 |
869 // Save new context and C++ ABI callee-saved registers. | 820 // Save new context and C++ ABI callee-saved registers. |
870 | 821 |
871 // The new context, saved vm tag, the top exit frame, and the old context. | 822 // The saved vm tag and the top exit frame. |
872 const intptr_t kPreservedContextSlots = 4; | 823 const intptr_t kPreservedSlots = 2; |
873 const intptr_t kPreservedRegSpace = | 824 const intptr_t kPreservedRegSpace = |
874 kWordSize * (kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount + | 825 kWordSize * (kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount + |
875 kPreservedContextSlots); | 826 kPreservedSlots); |
876 | 827 |
877 __ addiu(SP, SP, Immediate(-kPreservedRegSpace)); | 828 __ addiu(SP, SP, Immediate(-kPreservedRegSpace)); |
878 for (int i = S0; i <= S7; i++) { | 829 for (int i = S0; i <= S7; i++) { |
879 Register r = static_cast<Register>(i); | 830 Register r = static_cast<Register>(i); |
880 const intptr_t slot = i - S0 + kPreservedContextSlots; | 831 const intptr_t slot = i - S0 + kPreservedSlots; |
881 __ sw(r, Address(SP, slot * kWordSize)); | 832 __ sw(r, Address(SP, slot * kWordSize)); |
882 } | 833 } |
883 | 834 |
884 for (intptr_t i = kAbiFirstPreservedFpuReg; | 835 for (intptr_t i = kAbiFirstPreservedFpuReg; |
885 i <= kAbiLastPreservedFpuReg; i++) { | 836 i <= kAbiLastPreservedFpuReg; i++) { |
886 FRegister r = static_cast<FRegister>(i); | 837 FRegister r = static_cast<FRegister>(i); |
887 const intptr_t slot = | 838 const intptr_t slot = |
888 kAbiPreservedCpuRegCount + kPreservedContextSlots + i - | 839 kAbiPreservedCpuRegCount + kPreservedSlots + i - |
889 kAbiFirstPreservedFpuReg; | 840 kAbiFirstPreservedFpuReg; |
890 __ swc1(r, Address(SP, slot * kWordSize)); | 841 __ swc1(r, Address(SP, slot * kWordSize)); |
891 } | 842 } |
892 | 843 |
893 __ sw(A3, Address(SP, 3 * kWordSize)); | |
894 | |
895 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 844 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
896 // could potentially invoke some intrinsic functions which need the PP to be | 845 // could potentially invoke some intrinsic functions which need the PP to be |
897 // set up. | 846 // set up. |
898 __ LoadPoolPointer(); | 847 __ LoadPoolPointer(); |
899 | 848 |
900 // The new Context structure contains a pointer to the current Isolate | |
901 // structure. Cache the Context pointer in the CTX register so that it is | |
902 // available in generated code and calls to Isolate::Current() need not be | |
903 // done. The assumption is that this register will never be clobbered by | |
904 // compiled or runtime stub code. | |
905 | |
906 // Cache the new Context pointer into CTX while executing Dart code. | |
907 __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle)); | |
908 | |
909 __ LoadIsolate(T2); | 849 __ LoadIsolate(T2); |
910 | 850 |
911 // Save the current VMTag on the stack. | 851 // Save the current VMTag on the stack. |
912 ASSERT(kSavedVMTagSlotFromEntryFp == -22); | |
913 __ lw(T1, Address(T2, Isolate::vm_tag_offset())); | 852 __ lw(T1, Address(T2, Isolate::vm_tag_offset())); |
914 __ sw(T1, Address(SP, 2 * kWordSize)); | 853 __ sw(T1, Address(SP, 1 * kWordSize)); |
915 | 854 |
916 // Mark that the isolate is executing Dart code. | 855 // Mark that the isolate is executing Dart code. |
917 __ LoadImmediate(T0, VMTag::kDartTagId); | 856 __ LoadImmediate(T0, VMTag::kDartTagId); |
918 __ sw(T0, Address(T2, Isolate::vm_tag_offset())); | 857 __ sw(T0, Address(T2, Isolate::vm_tag_offset())); |
919 | 858 |
920 // Save the top exit frame info. Use T0 as a temporary register. | 859 // Save the top exit frame info. Use T0 as a temporary register. |
921 // StackFrameIterator reads the top exit frame info saved in this frame. | 860 // StackFrameIterator reads the top exit frame info saved in this frame. |
922 __ lw(T0, Address(T2, Isolate::top_exit_frame_info_offset())); | 861 __ lw(T0, Address(T2, Isolate::top_exit_frame_info_offset())); |
923 __ sw(ZR, Address(T2, Isolate::top_exit_frame_info_offset())); | 862 __ sw(ZR, Address(T2, Isolate::top_exit_frame_info_offset())); |
924 | 863 |
925 // Save the old Context pointer. Use T1 as a temporary register. | |
926 // Note that VisitObjectPointers will find this saved Context pointer during | |
927 // GC marking, since it traverses any information between SP and | |
928 // FP - kExitLinkSlotFromEntryFp. | |
929 // EntryFrame::SavedContext reads the context saved in this frame. | |
930 __ lw(T1, Address(T2, Isolate::top_context_offset())); | |
931 | |
932 // The constants kSavedContextSlotFromEntryFp and | |
933 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 864 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
934 ASSERT(kExitLinkSlotFromEntryFp == -23); | 865 ASSERT(kExitLinkSlotFromEntryFp == -22); |
935 ASSERT(kSavedContextSlotFromEntryFp == -24); | 866 __ sw(T0, Address(SP, 0 * kWordSize)); |
936 __ sw(T0, Address(SP, 1 * kWordSize)); | |
937 __ sw(T1, Address(SP, 0 * kWordSize)); | |
938 | 867 |
939 // After the call, The stack pointer is restored to this location. | 868 // After the call, The stack pointer is restored to this location. |
940 // Pushed A3, S0-7, F20-31, T0, T1 = 23. | 869 // Pushed S0-7, F20-31, T0, T1 = 22. |
941 | 870 |
942 // Load arguments descriptor array into S4, which is passed to Dart code. | 871 // Load arguments descriptor array into S4, which is passed to Dart code. |
943 __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle)); | 872 __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle)); |
944 | 873 |
945 // Load number of arguments into S5. | 874 // Load number of arguments into S5. |
946 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | 875 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
947 __ SmiUntag(T1); | 876 __ SmiUntag(T1); |
948 | 877 |
949 // Compute address of 'arguments array' data area into A2. | 878 // Compute address of 'arguments array' data area into A2. |
950 __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); | 879 __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); |
(...skipping 14 matching lines...) Expand all Loading... |
965 | 894 |
966 __ Bind(&done_push_arguments); | 895 __ Bind(&done_push_arguments); |
967 | 896 |
968 // Call the Dart code entrypoint. | 897 // Call the Dart code entrypoint. |
969 // We are calling into Dart code, here, so there is no need to call through | 898 // We are calling into Dart code, here, so there is no need to call through |
970 // T9 to match the ABI. | 899 // T9 to match the ABI. |
971 __ jalr(A0); // S4 is the arguments descriptor array. | 900 __ jalr(A0); // S4 is the arguments descriptor array. |
972 __ TraceSimMsg("InvokeDartCodeStub return"); | 901 __ TraceSimMsg("InvokeDartCodeStub return"); |
973 | 902 |
974 // Get rid of arguments pushed on the stack. | 903 // Get rid of arguments pushed on the stack. |
975 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); | 904 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize); |
976 | 905 |
977 // Load Isolate pointer into CTX. | 906 __ LoadIsolate(S6); |
978 __ LoadIsolate(CTX); | |
979 | 907 |
980 // Restore the current VMTag from the stack. | 908 // Restore the current VMTag from the stack. |
981 __ lw(T1, Address(SP, 2 * kWordSize)); | 909 __ lw(T1, Address(SP, 1 * kWordSize)); |
982 __ sw(T1, Address(CTX, Isolate::vm_tag_offset())); | 910 __ sw(T1, Address(S6, Isolate::vm_tag_offset())); |
983 | 911 |
984 // Restore the saved Context pointer into the Isolate structure. | |
985 // Uses T1 as a temporary register for this. | |
986 // Restore the saved top exit frame info back into the Isolate structure. | 912 // Restore the saved top exit frame info back into the Isolate structure. |
987 // Uses T0 as a temporary register for this. | 913 // Uses T0 as a temporary register for this. |
988 __ lw(T1, Address(SP, 0 * kWordSize)); | 914 __ lw(T0, Address(SP, 0 * kWordSize)); |
989 __ lw(T0, Address(SP, 1 * kWordSize)); | 915 __ sw(T0, Address(S6, Isolate::top_exit_frame_info_offset())); |
990 __ sw(T1, Address(CTX, Isolate::top_context_offset())); | |
991 __ sw(T0, Address(CTX, Isolate::top_exit_frame_info_offset())); | |
992 | 916 |
993 // Restore C++ ABI callee-saved registers. | 917 // Restore C++ ABI callee-saved registers. |
994 for (int i = S0; i <= S7; i++) { | 918 for (int i = S0; i <= S7; i++) { |
995 Register r = static_cast<Register>(i); | 919 Register r = static_cast<Register>(i); |
996 const intptr_t slot = i - S0 + kPreservedContextSlots; | 920 const intptr_t slot = i - S0 + kPreservedSlots; |
997 __ lw(r, Address(SP, slot * kWordSize)); | 921 __ lw(r, Address(SP, slot * kWordSize)); |
998 } | 922 } |
999 | 923 |
1000 for (intptr_t i = kAbiFirstPreservedFpuReg; | 924 for (intptr_t i = kAbiFirstPreservedFpuReg; |
1001 i <= kAbiLastPreservedFpuReg; i++) { | 925 i <= kAbiLastPreservedFpuReg; i++) { |
1002 FRegister r = static_cast<FRegister>(i); | 926 FRegister r = static_cast<FRegister>(i); |
1003 const intptr_t slot = | 927 const intptr_t slot = |
1004 kAbiPreservedCpuRegCount + kPreservedContextSlots + i - | 928 kAbiPreservedCpuRegCount + kPreservedSlots + i - |
1005 kAbiFirstPreservedFpuReg; | 929 kAbiFirstPreservedFpuReg; |
1006 __ lwc1(r, Address(SP, slot * kWordSize)); | 930 __ lwc1(r, Address(SP, slot * kWordSize)); |
1007 } | 931 } |
1008 | 932 |
1009 __ lw(A3, Address(SP, 3 * kWordSize)); | |
1010 __ addiu(SP, SP, Immediate(kPreservedRegSpace)); | 933 __ addiu(SP, SP, Immediate(kPreservedRegSpace)); |
1011 | 934 |
1012 // Restore the frame pointer and return. | 935 // Restore the frame pointer and return. |
1013 __ LeaveFrameAndReturn(); | 936 __ LeaveFrameAndReturn(); |
1014 } | 937 } |
1015 | 938 |
1016 | 939 |
1017 // Called for inline allocation of contexts. | 940 // Called for inline allocation of contexts. |
1018 // Input: | 941 // Input: |
1019 // T1: number of context variables. | 942 // T1: number of context variables. |
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2251 const Register right = T0; | 2174 const Register right = T0; |
2252 __ lw(left, Address(SP, 1 * kWordSize)); | 2175 __ lw(left, Address(SP, 1 * kWordSize)); |
2253 __ lw(right, Address(SP, 0 * kWordSize)); | 2176 __ lw(right, Address(SP, 0 * kWordSize)); |
2254 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2177 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2255 __ Ret(); | 2178 __ Ret(); |
2256 } | 2179 } |
2257 | 2180 |
2258 } // namespace dart | 2181 } // namespace dart |
2259 | 2182 |
2260 #endif // defined TARGET_ARCH_MIPS | 2183 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |