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