| 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 |