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 18 matching lines...) Expand all Loading... |
29 DECLARE_FLAG(bool, support_debugger); | 29 DECLARE_FLAG(bool, support_debugger); |
30 | 30 |
31 // Input parameters: | 31 // Input parameters: |
32 // RA : return address. | 32 // RA : return address. |
33 // SP : address of last argument in argument array. | 33 // SP : address of last argument in argument array. |
34 // SP + 4*S4 - 4 : address of first argument in argument array. | 34 // SP + 4*S4 - 4 : address of first argument in argument array. |
35 // SP + 4*S4 : address of return value. | 35 // SP + 4*S4 : address of return value. |
36 // S5 : address of the runtime function to call. | 36 // S5 : address of the runtime function to call. |
37 // S4 : number of arguments to the call. | 37 // S4 : number of arguments to the call. |
38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 38 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
39 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 39 const intptr_t thread_offset = NativeArguments::thread_offset(); |
40 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 40 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
41 const intptr_t argv_offset = NativeArguments::argv_offset(); | 41 const intptr_t argv_offset = NativeArguments::argv_offset(); |
42 const intptr_t retval_offset = NativeArguments::retval_offset(); | 42 const intptr_t retval_offset = NativeArguments::retval_offset(); |
43 const intptr_t exitframe_last_param_slot_from_fp = 2; | 43 const intptr_t exitframe_last_param_slot_from_fp = 2; |
44 | 44 |
45 __ SetPrologueOffset(); | 45 __ SetPrologueOffset(); |
46 __ Comment("CallToRuntimeStub"); | 46 __ Comment("CallToRuntimeStub"); |
47 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 47 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
48 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker | 48 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker |
49 __ sw(RA, Address(SP, 1 * kWordSize)); | 49 __ sw(RA, Address(SP, 1 * kWordSize)); |
(...skipping 21 matching lines...) Expand all Loading... |
71 __ sw(S5, Address(S6, Isolate::vm_tag_offset())); | 71 __ sw(S5, Address(S6, Isolate::vm_tag_offset())); |
72 | 72 |
73 // Reserve space for arguments and align frame before entering C++ world. | 73 // Reserve space for arguments and align frame before entering C++ world. |
74 // NativeArguments are passed in registers. | 74 // NativeArguments are passed in registers. |
75 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); | 75 ASSERT(sizeof(NativeArguments) == 4 * kWordSize); |
76 __ ReserveAlignedFrameSpace(4 * kWordSize); // Reserve space for arguments. | 76 __ ReserveAlignedFrameSpace(4 * kWordSize); // Reserve space for arguments. |
77 | 77 |
78 // Pass NativeArguments structure by value and call runtime. | 78 // Pass NativeArguments structure by value and call runtime. |
79 // Registers A0, A1, A2, and A3 are used. | 79 // Registers A0, A1, A2, and A3 are used. |
80 | 80 |
81 ASSERT(isolate_offset == 0 * kWordSize); | 81 ASSERT(thread_offset == 0 * kWordSize); |
82 // Set isolate in NativeArgs. | 82 // Set thread in NativeArgs. |
83 __ mov(A0, S6); | 83 __ mov(A0, THR); |
84 | 84 |
85 // There are no runtime calls to closures, so we do not need to set the tag | 85 // There are no runtime calls to closures, so we do not need to set the tag |
86 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 86 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
87 ASSERT(argc_tag_offset == 1 * kWordSize); | 87 ASSERT(argc_tag_offset == 1 * kWordSize); |
88 __ mov(A1, S4); // Set argc in NativeArguments. | 88 __ mov(A1, S4); // Set argc in NativeArguments. |
89 | 89 |
90 ASSERT(argv_offset == 2 * kWordSize); | 90 ASSERT(argv_offset == 2 * kWordSize); |
91 __ sll(A2, S4, 2); | 91 __ sll(A2, S4, 2); |
92 __ addu(A2, FP, A2); // Compute argv. | 92 __ addu(A2, FP, A2); // Compute argv. |
93 // Set argv in NativeArguments. | 93 // Set argv in NativeArguments. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 } | 139 } |
140 | 140 |
141 | 141 |
142 // Input parameters: | 142 // Input parameters: |
143 // RA : return address. | 143 // RA : return address. |
144 // SP : address of return value. | 144 // SP : address of return value. |
145 // T5 : address of the native function to call. | 145 // T5 : address of the native function to call. |
146 // A2 : address of first argument in argument array. | 146 // A2 : address of first argument in argument array. |
147 // A1 : argc_tag including number of arguments and function kind. | 147 // A1 : argc_tag including number of arguments and function kind. |
148 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 148 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
149 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 149 const intptr_t thread_offset = NativeArguments::thread_offset(); |
150 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 150 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
151 const intptr_t argv_offset = NativeArguments::argv_offset(); | 151 const intptr_t argv_offset = NativeArguments::argv_offset(); |
152 const intptr_t retval_offset = NativeArguments::retval_offset(); | 152 const intptr_t retval_offset = NativeArguments::retval_offset(); |
153 | 153 |
154 __ SetPrologueOffset(); | 154 __ SetPrologueOffset(); |
155 __ Comment("CallNativeCFunctionStub"); | 155 __ Comment("CallNativeCFunctionStub"); |
156 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 156 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
157 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker | 157 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker |
158 __ sw(RA, Address(SP, 1 * kWordSize)); | 158 __ sw(RA, Address(SP, 1 * kWordSize)); |
159 __ sw(FP, Address(SP, 0 * kWordSize)); | 159 __ sw(FP, Address(SP, 0 * kWordSize)); |
(...skipping 15 matching lines...) Expand all Loading... |
175 __ Bind(&ok); | 175 __ Bind(&ok); |
176 } | 176 } |
177 #endif | 177 #endif |
178 | 178 |
179 // Mark that the isolate is executing Native code. | 179 // Mark that the isolate is executing Native code. |
180 __ sw(T5, Address(S6, Isolate::vm_tag_offset())); | 180 __ sw(T5, Address(S6, Isolate::vm_tag_offset())); |
181 | 181 |
182 // Initialize NativeArguments structure and call native function. | 182 // Initialize NativeArguments structure and call native function. |
183 // Registers A0, A1, A2, and A3 are used. | 183 // Registers A0, A1, A2, and A3 are used. |
184 | 184 |
185 ASSERT(isolate_offset == 0 * kWordSize); | 185 ASSERT(thread_offset == 0 * kWordSize); |
186 // Set isolate in NativeArgs. | 186 // Set thread in NativeArgs. |
187 __ mov(A0, S6); | 187 __ mov(A0, THR); |
188 | 188 |
189 // There are no native calls to closures, so we do not need to set the tag | 189 // There are no native calls to closures, so we do not need to set the tag |
190 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 190 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
191 ASSERT(argc_tag_offset == 1 * kWordSize); | 191 ASSERT(argc_tag_offset == 1 * kWordSize); |
192 // Set argc in NativeArguments: A1 already contains argc. | 192 // Set argc in NativeArguments: A1 already contains argc. |
193 | 193 |
194 ASSERT(argv_offset == 2 * kWordSize); | 194 ASSERT(argv_offset == 2 * kWordSize); |
195 // Set argv in NativeArguments: A2 already contains argv. | 195 // Set argv in NativeArguments: A2 already contains argv. |
196 | 196 |
197 ASSERT(retval_offset == 3 * kWordSize); | 197 ASSERT(retval_offset == 3 * kWordSize); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 // Input parameters: | 240 // Input parameters: |
241 // RA : return address. | 241 // RA : return address. |
242 // SP : address of return value. | 242 // SP : address of return value. |
243 // T5 : address of the native function to call. | 243 // T5 : address of the native function to call. |
244 // A2 : address of first argument in argument array. | 244 // A2 : address of first argument in argument array. |
245 // A1 : argc_tag including number of arguments and function kind. | 245 // A1 : argc_tag including number of arguments and function kind. |
246 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 246 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
247 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 247 const intptr_t thread_offset = NativeArguments::thread_offset(); |
248 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 248 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
249 const intptr_t argv_offset = NativeArguments::argv_offset(); | 249 const intptr_t argv_offset = NativeArguments::argv_offset(); |
250 const intptr_t retval_offset = NativeArguments::retval_offset(); | 250 const intptr_t retval_offset = NativeArguments::retval_offset(); |
251 | 251 |
252 __ SetPrologueOffset(); | 252 __ SetPrologueOffset(); |
253 __ Comment("CallNativeCFunctionStub"); | 253 __ Comment("CallNativeCFunctionStub"); |
254 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 254 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
255 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker | 255 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker |
256 __ sw(RA, Address(SP, 1 * kWordSize)); | 256 __ sw(RA, Address(SP, 1 * kWordSize)); |
257 __ sw(FP, Address(SP, 0 * kWordSize)); | 257 __ sw(FP, Address(SP, 0 * kWordSize)); |
(...skipping 15 matching lines...) Expand all Loading... |
273 __ Bind(&ok); | 273 __ Bind(&ok); |
274 } | 274 } |
275 #endif | 275 #endif |
276 | 276 |
277 // Mark that the isolate is executing Native code. | 277 // Mark that the isolate is executing Native code. |
278 __ sw(T5, Address(S6, Isolate::vm_tag_offset())); | 278 __ sw(T5, Address(S6, Isolate::vm_tag_offset())); |
279 | 279 |
280 // Initialize NativeArguments structure and call native function. | 280 // Initialize NativeArguments structure and call native function. |
281 // Registers A0, A1, A2, and A3 are used. | 281 // Registers A0, A1, A2, and A3 are used. |
282 | 282 |
283 ASSERT(isolate_offset == 0 * kWordSize); | 283 ASSERT(thread_offset == 0 * kWordSize); |
284 // Set isolate in NativeArgs. | 284 // Set thread in NativeArgs. |
285 __ mov(A0, S6); | 285 __ mov(A0, THR); |
286 | 286 |
287 // There are no native calls to closures, so we do not need to set the tag | 287 // There are no native calls to closures, so we do not need to set the tag |
288 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 288 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
289 ASSERT(argc_tag_offset == 1 * kWordSize); | 289 ASSERT(argc_tag_offset == 1 * kWordSize); |
290 // Set argc in NativeArguments: A1 already contains argc. | 290 // Set argc in NativeArguments: A1 already contains argc. |
291 | 291 |
292 ASSERT(argv_offset == 2 * kWordSize); | 292 ASSERT(argv_offset == 2 * kWordSize); |
293 // Set argv in NativeArguments: A2 already contains argv. | 293 // Set argv in NativeArguments: A2 already contains argv. |
294 | 294 |
295 ASSERT(retval_offset == 3 * kWordSize); | 295 ASSERT(retval_offset == 3 * kWordSize); |
(...skipping 1789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2085 } | 2085 } |
2086 | 2086 |
2087 | 2087 |
2088 // Jump to the exception or error handler. | 2088 // Jump to the exception or error handler. |
2089 // RA: return address. | 2089 // RA: return address. |
2090 // A0: program_counter. | 2090 // A0: program_counter. |
2091 // A1: stack_pointer. | 2091 // A1: stack_pointer. |
2092 // A2: frame_pointer. | 2092 // A2: frame_pointer. |
2093 // A3: error object. | 2093 // A3: error object. |
2094 // SP + 4*kWordSize: address of stacktrace object. | 2094 // SP + 4*kWordSize: address of stacktrace object. |
2095 // SP + 5*kWordSize: address of isolate. | 2095 // SP + 5*kWordSize: address of thread. |
2096 // Does not return. | 2096 // Does not return. |
2097 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { | 2097 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { |
2098 ASSERT(kExceptionObjectReg == V0); | 2098 ASSERT(kExceptionObjectReg == V0); |
2099 ASSERT(kStackTraceObjectReg == V1); | 2099 ASSERT(kStackTraceObjectReg == V1); |
2100 __ mov(V0, A3); // Exception object. | 2100 __ mov(V0, A3); // Exception object. |
2101 // MIPS ABI reserves stack space for all arguments. The StackTrace object is | 2101 // MIPS ABI reserves stack space for all arguments. The StackTrace object is |
2102 // the last of five arguments, so it is first pushed on the stack. | 2102 // the last of five arguments, so it is first pushed on the stack. |
2103 __ lw(V1, Address(SP, 4 * kWordSize)); // StackTrace object. | 2103 __ lw(V1, Address(SP, 4 * kWordSize)); // StackTrace object. |
2104 __ mov(FP, A2); // Frame_pointer. | 2104 __ mov(FP, A2); // Frame_pointer. |
2105 __ lw(A3, Address(SP, 5 * kWordSize)); // Isolate. | 2105 __ lw(THR, Address(SP, 5 * kWordSize)); // Thread. |
2106 // TODO(koda): Pass thread instead of isolate. | 2106 __ LoadIsolate(A3); |
2107 __ lw(THR, Address(A3, Isolate::mutator_thread_offset())); | |
2108 // Set tag. | 2107 // Set tag. |
2109 __ LoadImmediate(A2, VMTag::kDartTagId); | 2108 __ LoadImmediate(A2, VMTag::kDartTagId); |
2110 __ sw(A2, Address(A3, Isolate::vm_tag_offset())); | 2109 __ sw(A2, Address(A3, Isolate::vm_tag_offset())); |
2111 // Clear top exit frame. | 2110 // Clear top exit frame. |
2112 __ sw(ZR, Address(A3, Isolate::top_exit_frame_info_offset())); | 2111 __ sw(ZR, Address(A3, Isolate::top_exit_frame_info_offset())); |
2113 | 2112 |
2114 __ jr(A0); // Jump to the exception handler code. | 2113 __ jr(A0); // Jump to the exception handler code. |
2115 __ delay_slot()->mov(SP, A1); // Stack pointer. | 2114 __ delay_slot()->mov(SP, A1); // Stack pointer. |
2116 } | 2115 } |
2117 | 2116 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2335 // Result: | 2334 // Result: |
2336 // T1: entry point. | 2335 // T1: entry point. |
2337 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2336 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2338 EmitMegamorphicLookup(assembler, T0, T1, T1); | 2337 EmitMegamorphicLookup(assembler, T0, T1, T1); |
2339 __ Ret(); | 2338 __ Ret(); |
2340 } | 2339 } |
2341 | 2340 |
2342 } // namespace dart | 2341 } // namespace dart |
2343 | 2342 |
2344 #endif // defined TARGET_ARCH_MIPS | 2343 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |