Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(570)

Side by Side Diff: runtime/vm/stub_code_mips.cc

Issue 16022011: Enables optimization on MIPS (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/simulator_mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 __ mov(CTX, A2); 104 __ mov(CTX, A2);
105 105
106 __ mov(SP, FP); 106 __ mov(SP, FP);
107 __ lw(RA, Address(SP, 1 * kWordSize)); 107 __ lw(RA, Address(SP, 1 * kWordSize));
108 __ lw(FP, Address(SP, 0 * kWordSize)); 108 __ lw(FP, Address(SP, 0 * kWordSize));
109 __ Ret(); 109 __ Ret();
110 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); 110 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize));
111 } 111 }
112 112
113 113
114 // Print the stop message.
115 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, const char* message) {
116 OS::Print("Stop message: %s\n", message);
117 }
118 END_LEAF_RUNTIME_ENTRY
119
120
121 // Input parameters:
122 // A0 : stop message (const char*).
123 // Must preserve all registers.
114 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { 124 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
115 __ Unimplemented("PrintStopMessage stub"); 125 __ EnterCallRuntimeFrame(0);
126 // Call the runtime leaf function. A0 already contains the parameter.
127 __ CallRuntime(kPrintStopMessageRuntimeEntry);
128 __ LeaveCallRuntimeFrame();
129 __ Ret();
116 } 130 }
117 131
118 132
119 // Input parameters: 133 // Input parameters:
120 // RA : return address. 134 // RA : return address.
121 // SP : address of return value. 135 // SP : address of return value.
122 // T5 : address of the native function to call. 136 // T5 : address of the native function to call.
123 // A2 : address of first argument in argument array. 137 // A2 : address of first argument in argument array.
124 // A1 : argc_tag including number of arguments and function kind. 138 // A1 : argc_tag including number of arguments and function kind.
125 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { 139 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 __ LeaveStubFrameAndReturn(T0); 246 __ LeaveStubFrameAndReturn(T0);
233 } 247 }
234 248
235 249
236 // Called from a static call only when an invalid code has been entered 250 // Called from a static call only when an invalid code has been entered
237 // (invalid because its function was optimized or deoptimized). 251 // (invalid because its function was optimized or deoptimized).
238 // S4: arguments descriptor array. 252 // S4: arguments descriptor array.
239 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 253 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
240 // Create a stub frame as we are pushing some objects on the stack before 254 // Create a stub frame as we are pushing some objects on the stack before
241 // calling into the runtime. 255 // calling into the runtime.
256 __ TraceSimMsg("FixCallersTarget");
242 __ EnterStubFrame(); 257 __ EnterStubFrame();
243 // Setup space on stack for return value and preserve arguments descriptor. 258 // Setup space on stack for return value and preserve arguments descriptor.
244 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 259 __ addiu(SP, SP, Immediate(-2 * kWordSize));
245 __ sw(S4, Address(SP, 1 * kWordSize)); 260 __ sw(S4, Address(SP, 1 * kWordSize));
246 __ sw(NULLREG, Address(SP, 0 * kWordSize)); 261 __ sw(NULLREG, Address(SP, 0 * kWordSize));
247 __ CallRuntime(kFixCallersTargetRuntimeEntry); 262 __ CallRuntime(kFixCallersTargetRuntimeEntry);
248 // Get Code object result and restore arguments descriptor array. 263 // Get Code object result and restore arguments descriptor array.
249 __ lw(T0, Address(SP, 0 * kWordSize)); 264 __ lw(T0, Address(SP, 0 * kWordSize));
250 __ lw(S4, Address(SP, 1 * kWordSize)); 265 __ lw(S4, Address(SP, 1 * kWordSize));
251 __ addiu(SP, SP, Immediate(2 * kWordSize)); 266 __ addiu(SP, SP, Immediate(2 * kWordSize));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 __ addiu(SP, SP, Immediate(-4 * kWordSize)); 332 __ addiu(SP, SP, Immediate(-4 * kWordSize));
318 __ sw(NULLREG, Address(SP, 3 * kWordSize)); 333 __ sw(NULLREG, Address(SP, 3 * kWordSize));
319 __ sw(T1, Address(SP, 2 * kWordSize)); 334 __ sw(T1, Address(SP, 2 * kWordSize));
320 __ sw(S5, Address(SP, 1 * kWordSize)); 335 __ sw(S5, Address(SP, 1 * kWordSize));
321 __ sw(S4, Address(SP, 0 * kWordSize)); 336 __ sw(S4, Address(SP, 0 * kWordSize));
322 337
323 // A1: Smi-tagged arguments array length. 338 // A1: Smi-tagged arguments array length.
324 PushArgumentsArray(assembler); 339 PushArgumentsArray(assembler);
325 __ TraceSimMsg("InstanceFunctionLookupStub return"); 340 __ TraceSimMsg("InstanceFunctionLookupStub return");
326 341
327 // Stack:
328 // TOS + 0: argument array.
329 // TOS + 1: arguments descriptor array.
330 // TOS + 2: IC data object.
331 // TOS + 3: Receiver.
332 // TOS + 4: place for result from the call.
333 // TOS + 5: saved FP of previous frame.
334 // TOS + 6: dart code return address
335 // TOS + 7: pc marker (0 for stub).
336 // TOS + 8: last argument of caller.
337 // ....
338 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); 342 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
339 343
340 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. 344 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0.
341 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Remove arguments. 345 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Remove arguments.
342 346
343 __ LeaveStubFrameAndReturn(); 347 __ LeaveStubFrameAndReturn();
344 } 348 }
345 349
346 350
347 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 351 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
348 intptr_t deopt_reason, 352 intptr_t deopt_reason,
349 uword saved_registers_address); 353 uword saved_registers_address);
350 354
351 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); 355 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
352 356
353 357
358
359
354 // Used by eager and lazy deoptimization. Preserve result in V0 if necessary. 360 // Used by eager and lazy deoptimization. Preserve result in V0 if necessary.
355 // This stub translates optimized frame into unoptimized frame. The optimized 361 // This stub translates optimized frame into unoptimized frame. The optimized
356 // frame can contain values in registers and on stack, the unoptimized 362 // frame can contain values in registers and on stack, the unoptimized
357 // frame contains all values on stack. 363 // frame contains all values on stack.
358 // Deoptimization occurs in following steps: 364 // Deoptimization occurs in following steps:
359 // - Push all registers that can contain values. 365 // - Push all registers that can contain values.
360 // - Call C routine to copy the stack and saved registers into temporary buffer. 366 // - Call C routine to copy the stack and saved registers into temporary buffer.
361 // - Adjust caller's frame to correct unoptimized frame size. 367 // - Adjust caller's frame to correct unoptimized frame size.
362 // - Fill the unoptimized frame. 368 // - Fill the unoptimized frame.
363 // - Materialize objects that require allocation (e.g. Double instances). 369 // - Materialize objects that require allocation (e.g. Double instances).
364 // GC can occur only after frame is fully rewritten. 370 // GC can occur only after frame is fully rewritten.
365 // Stack after EnterFrame(...) below: 371 // Stack after EnterFrame(...) below:
366 // +------------------+ 372 // +------------------+
367 // | Saved FP | <- TOS 373 // | Saved PP | <- TOS
368 // +------------------+ 374 // +------------------+
369 // | return-address | (deoptimization point) 375 // | Saved FP | <- FP of stub
370 // +------------------+ 376 // +------------------+
371 // | optimized frame | 377 // | Saved LR | (deoptimization point)
372 // | ... | 378 // +------------------+
379 // | PC marker |
380 // +------------------+
381 // | ... | <- SP of optimized frame
373 // 382 //
374 // Parts of the code cannot GC, part of the code can GC. 383 // Parts of the code cannot GC, part of the code can GC.
375 static void GenerateDeoptimizationSequence(Assembler* assembler, 384 static void GenerateDeoptimizationSequence(Assembler* assembler,
376 bool preserve_result) { 385 bool preserve_result) {
386 __ TraceSimMsg("GenerateDeoptimizationSequence");
377 const intptr_t kPushedRegistersSize = 387 const intptr_t kPushedRegistersSize =
378 kNumberOfCpuRegisters * kWordSize + 388 kNumberOfCpuRegisters * kWordSize +
379 2 * kWordSize + // FP and RA. 389 4 * kWordSize + // PP, FP, RA, PC marker.
380 kNumberOfFRegisters * kWordSize; 390 kNumberOfFRegisters * kWordSize;
381 391
392 // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
393 // is no need to set the correct PC marker or load PP, since they get patched.
382 __ addiu(SP, SP, Immediate(-kPushedRegistersSize * kWordSize)); 394 __ addiu(SP, SP, Immediate(-kPushedRegistersSize * kWordSize));
383 __ sw(RA, Address(SP, kPushedRegistersSize - 1 * kWordSize)); 395 __ sw(ZR, Address(SP, kPushedRegistersSize - 1 * kWordSize));
384 __ sw(FP, Address(SP, kPushedRegistersSize - 2 * kWordSize)); 396 __ sw(RA, Address(SP, kPushedRegistersSize - 2 * kWordSize));
385 __ addiu(FP, SP, Immediate(kPushedRegistersSize - 2 * kWordSize)); 397 __ sw(FP, Address(SP, kPushedRegistersSize - 3 * kWordSize));
386 398 __ sw(PP, Address(SP, kPushedRegistersSize - 4 * kWordSize));
399 __ addiu(FP, SP, Immediate(kPushedRegistersSize - 3 * kWordSize));
387 400
388 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry 401 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
389 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. 402 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
390 const intptr_t saved_v0_offset_from_fp = -(kNumberOfCpuRegisters - V0); 403 const intptr_t saved_result_slot_from_fp =
404 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - V0);
391 // Result in V0 is preserved as part of pushing all registers below. 405 // Result in V0 is preserved as part of pushing all registers below.
392 406
407 // TODO(regis): Should we align the stack before pushing the fpu registers?
408 // If we do, saved_result_slot_from_fp is not constant anymore.
409
393 // Push registers in their enumeration order: lowest register number at 410 // Push registers in their enumeration order: lowest register number at
394 // lowest address. 411 // lowest address.
395 for (int i = 0; i < kNumberOfCpuRegisters; i++) { 412 for (int i = 0; i < kNumberOfCpuRegisters; i++) {
396 const int slot = 2 + kNumberOfCpuRegisters - i; 413 const int slot = 4 + kNumberOfCpuRegisters - i;
397 Register reg = static_cast<Register>(i); 414 Register reg = static_cast<Register>(i);
398 __ sw(reg, Address(SP, kPushedRegistersSize - slot * kWordSize)); 415 __ sw(reg, Address(SP, kPushedRegistersSize - slot * kWordSize));
399 } 416 }
400 for (int i = 0; i < kNumberOfFRegisters; i++) { 417 for (int i = 0; i < kNumberOfFRegisters; i++) {
401 // These go below the CPU registers. 418 // These go below the CPU registers.
402 const int slot = 2 + kNumberOfCpuRegisters + kNumberOfFRegisters - i; 419 const int slot = 4 + kNumberOfCpuRegisters + kNumberOfFRegisters - i;
403 FRegister reg = static_cast<FRegister>(i); 420 FRegister reg = static_cast<FRegister>(i);
404 __ swc1(reg, Address(SP, kPushedRegistersSize - slot * kWordSize)); 421 __ swc1(reg, Address(SP, kPushedRegistersSize - slot * kWordSize));
405 } 422 }
406 423
407 __ mov(A0, SP); // Pass address of saved registers block. 424 __ mov(A0, SP); // Pass address of saved registers block.
408 __ ReserveAlignedFrameSpace(0); 425 __ ReserveAlignedFrameSpace(0);
409 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); 426 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry);
410 // Result (V0) is stack-size (FP - SP) in bytes, incl. the return address. 427 // Result (V0) is stack-size (FP - SP) in bytes, incl. the return address.
411 428
412 if (preserve_result) { 429 if (preserve_result) {
413 // Restore result into T1 temporarily. 430 // Restore result into T1 temporarily.
414 __ lw(T1, Address(FP, saved_v0_offset_from_fp * kWordSize)); 431 __ lw(T1, Address(FP, saved_result_slot_from_fp * kWordSize));
415 } 432 }
416 433
417 __ mov(SP, FP); 434 __ addiu(SP, FP, Immediate(-kWordSize));
418 __ lw(FP, Address(SP, 0 * kWordSize)); 435 __ lw(RA, Address(SP, 2 * kWordSize));
419 __ lw(RA, Address(SP, 1 * kWordSize)); 436 __ lw(FP, Address(SP, 1 * kWordSize));
420 __ addiu(SP, SP, Immediate(2 * kWordSize)); 437 __ lw(PP, Address(SP, 0 * kWordSize));
421
422 __ subu(SP, FP, V0); 438 __ subu(SP, FP, V0);
423 439
424 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 440 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
425 __ sw(RA, Address(SP, 1 * kWordSize)); 441 // is no need to set the correct PC marker or load PP, since they get patched.
426 __ sw(FP, Address(SP, 0 * kWordSize)); 442 __ addiu(SP, SP, Immediate(-4 * kWordSize));
427 __ mov(FP, SP); 443 __ sw(ZR, Address(SP, 3 * kWordSize));
444 __ sw(RA, Address(SP, 2 * kWordSize));
445 __ sw(FP, Address(SP, 1 * kWordSize));
446 __ sw(PP, Address(SP, 0 * kWordSize));
447 __ addiu(FP, SP, Immediate(kWordSize));
428 448
429 __ mov(A0, SP); // Get last FP address. 449 __ mov(A0, FP); // Get last FP address.
430 if (preserve_result) { 450 if (preserve_result) {
431 __ Push(T1); // Preserve result. 451 __ Push(T1); // Preserve result as first local.
432 } 452 }
433 __ ReserveAlignedFrameSpace(0); 453 __ ReserveAlignedFrameSpace(0);
434 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in A0. 454 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in A0.
435 // Result (V0) is our FP.
436 if (preserve_result) { 455 if (preserve_result) {
437 // Restore result into T1. 456 // Restore result into T1.
438 __ lw(T1, Address(FP, -1 * kWordSize)); 457 __ lw(T1, Address(FP, kFirstLocalSlotFromFp * kWordSize));
439 } 458 }
440 // Code above cannot cause GC. 459 // Code above cannot cause GC.
441 __ mov(SP, FP); 460 __ addiu(SP, FP, Immediate(-kWordSize));
442 __ lw(FP, Address(SP, 0 * kWordSize)); 461 __ lw(RA, Address(SP, 2 * kWordSize));
443 __ lw(RA, Address(SP, 1 * kWordSize)); 462 __ lw(FP, Address(SP, 1 * kWordSize));
444 __ addiu(SP, SP, Immediate(2 * kWordSize)); 463 __ lw(PP, Address(SP, 0 * kWordSize));
445 __ mov(FP, V0); 464 __ addiu(SP, SP, Immediate(4 * kWordSize));
446 465
447 // Frame is fully rewritten at this point and it is safe to perform a GC. 466 // Frame is fully rewritten at this point and it is safe to perform a GC.
448 // Materialize any objects that were deferred by FillFrame because they 467 // Materialize any objects that were deferred by FillFrame because they
449 // require allocation. 468 // require allocation.
450 __ EnterStubFrame(); 469 __ EnterStubFrame();
451 if (preserve_result) { 470 if (preserve_result) {
452 __ Push(T1); // Preserve result, it will be GC-d here. 471 __ Push(T1); // Preserve result, it will be GC-d here.
453 } 472 }
454 __ PushObject(Smi::ZoneHandle()); // Space for the result. 473 __ PushObject(Smi::ZoneHandle()); // Space for the result.
455 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); 474 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry);
456 // Result tells stub how many bytes to remove from the expression stack 475 // Result tells stub how many bytes to remove from the expression stack
457 // of the bottom-most frame. They were used as materialization arguments. 476 // of the bottom-most frame. They were used as materialization arguments.
458 __ Pop(T1); 477 __ Pop(T1);
459 __ SmiUntag(T1);
460 if (preserve_result) { 478 if (preserve_result) {
461 __ Pop(V0); // Restore result. 479 __ Pop(V0); // Restore result.
462 } 480 }
463 __ LeaveStubFrame(); 481 __ LeaveStubFrame();
464 482 // Remove materialization arguments.
465 // Return. 483 __ SmiUntag(T1);
466 __ jr(RA); 484 __ addu(SP, SP, T1);
467 __ delay_slot()->addu(SP, SP, T1); // Remove materialization arguments. 485 __ Ret();
468 } 486 }
469 487
470 488
471 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) { 489 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
472 __ Unimplemented("DeoptimizeLazy stub"); 490 // Correct return address to point just after the call that is being
491 // deoptimized.
492 __ AddImmediate(RA, -CallPattern::kFixedLengthInBytes);
493 GenerateDeoptimizationSequence(assembler, true); // Preserve V0.
473 } 494 }
474 495
475 496
476 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 497 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
477 GenerateDeoptimizationSequence(assembler, false); // Don't preserve V0. 498 GenerateDeoptimizationSequence(assembler, false); // Don't preserve V0.
478 } 499 }
479 500
480 501
481 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 502 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
482 __ Unimplemented("MegamorphicMiss stub"); 503 __ Unimplemented("MegamorphicMiss stub");
504 return;
483 } 505 }
484 506
485 507
486 // Called for inline allocation of arrays. 508 // Called for inline allocation of arrays.
487 // Input parameters: 509 // Input parameters:
488 // RA: return address. 510 // RA: return address.
489 // A1: Array length as Smi. 511 // A1: Array length as Smi.
490 // A0: array element type (either NULL or an instantiated type). 512 // A0: array element type (either NULL or an instantiated type).
491 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. 513 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved.
492 // The newly allocated object is returned in V0. 514 // The newly allocated object is returned in V0.
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 __ LeaveStubFrameAndReturn(); 881 __ LeaveStubFrameAndReturn();
860 } 882 }
861 883
862 884
863 // Called for inline allocation of contexts. 885 // Called for inline allocation of contexts.
864 // Input: 886 // Input:
865 // T1: number of context variables. 887 // T1: number of context variables.
866 // Output: 888 // Output:
867 // V0: new allocated RawContext object. 889 // V0: new allocated RawContext object.
868 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 890 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
891 __ TraceSimMsg("AllocateContext");
869 if (FLAG_inline_alloc) { 892 if (FLAG_inline_alloc) {
870 const Class& context_class = Class::ZoneHandle(Object::context_class()); 893 const Class& context_class = Class::ZoneHandle(Object::context_class());
871 Label slow_case; 894 Label slow_case;
872 Heap* heap = Isolate::Current()->heap(); 895 Heap* heap = Isolate::Current()->heap();
873 // First compute the rounded instance size. 896 // First compute the rounded instance size.
874 // T1: number of context variables. 897 // T1: number of context variables.
875 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; 898 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1;
876 __ LoadImmediate(T2, fixed_size); 899 __ LoadImmediate(T2, fixed_size);
877 __ sll(T0, T1, 2); 900 __ sll(T0, T1, 2);
878 __ addu(T2, T2, T0); 901 __ addu(T2, T2, T0);
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 __ LeaveDartFrameAndReturn(); 1773 __ LeaveDartFrameAndReturn();
1751 } 1774 }
1752 1775
1753 1776
1754 // RA: return address (Dart code). 1777 // RA: return address (Dart code).
1755 // S5: Inline cache data array. 1778 // S5: Inline cache data array.
1756 // S4: Arguments descriptor array. 1779 // S4: Arguments descriptor array.
1757 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1780 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1758 // Create a stub frame as we are pushing some objects on the stack before 1781 // Create a stub frame as we are pushing some objects on the stack before
1759 // calling into the runtime. 1782 // calling into the runtime.
1783 __ TraceSimMsg("BreakpointDynamicStub");
1760 __ EnterStubFrame(); 1784 __ EnterStubFrame();
1761 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 1785 __ addiu(SP, SP, Immediate(-2 * kWordSize));
1762 __ sw(S5, Address(SP, 1 * kWordSize)); 1786 __ sw(S5, Address(SP, 1 * kWordSize));
1763 __ sw(S4, Address(SP, 0 * kWordSize)); 1787 __ sw(S4, Address(SP, 0 * kWordSize));
1764 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); 1788 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
1765 __ lw(S4, Address(SP, 0 * kWordSize)); 1789 __ lw(S4, Address(SP, 0 * kWordSize));
1766 __ lw(S5, Address(SP, 1 * kWordSize)); 1790 __ lw(S5, Address(SP, 1 * kWordSize));
1767 __ addiu(SP, SP, Immediate(2 * kWordSize)); 1791 __ addiu(SP, SP, Immediate(2 * kWordSize));
1768 __ LeaveStubFrame(); 1792 __ LeaveStubFrame();
1769 1793
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 __ CallRuntime(kBigintCompareRuntimeEntry); 2154 __ CallRuntime(kBigintCompareRuntimeEntry);
2131 __ TraceSimMsg("IdenticalWithNumberCheckStub return"); 2155 __ TraceSimMsg("IdenticalWithNumberCheckStub return");
2132 // Result in V0, 0 means equal. 2156 // Result in V0, 0 means equal.
2133 __ LeaveStubFrame(); 2157 __ LeaveStubFrame();
2134 __ b(&done); 2158 __ b(&done);
2135 __ delay_slot()->mov(CMPRES, V0); 2159 __ delay_slot()->mov(CMPRES, V0);
2136 2160
2137 __ Bind(&reference_compare); 2161 __ Bind(&reference_compare);
2138 __ subu(ret, left, right); 2162 __ subu(ret, left, right);
2139 __ Bind(&done); 2163 __ Bind(&done);
2164 // A branch or test after this comparison will check CMPRES == TMP1.
2165 __ mov(TMP1, ZR);
2140 __ lw(T0, Address(SP, 0 * kWordSize)); 2166 __ lw(T0, Address(SP, 0 * kWordSize));
2141 __ lw(T1, Address(SP, 1 * kWordSize)); 2167 __ lw(T1, Address(SP, 1 * kWordSize));
2142 __ Ret(); 2168 __ Ret();
2143 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); 2169 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize));
2144 } 2170 }
2145 2171
2146 } // namespace dart 2172 } // namespace dart
2147 2173
2148 #endif // defined TARGET_ARCH_MIPS 2174 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/simulator_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698