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 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 __ lw(T3, Address(T1)); | 485 __ lw(T3, Address(T1)); |
486 __ addiu(A1, A1, Immediate(-Smi::RawValue(1))); | 486 __ addiu(A1, A1, Immediate(-Smi::RawValue(1))); |
487 __ addiu(T1, T1, Immediate(-kWordSize)); | 487 __ addiu(T1, T1, Immediate(-kWordSize)); |
488 __ addiu(T2, T2, Immediate(kWordSize)); | 488 __ addiu(T2, T2, Immediate(kWordSize)); |
489 __ bgez(A1, &loop); | 489 __ bgez(A1, &loop); |
490 __ delay_slot()->sw(T3, Address(T2, -kWordSize)); | 490 __ delay_slot()->sw(T3, Address(T2, -kWordSize)); |
491 __ Bind(&loop_exit); | 491 __ Bind(&loop_exit); |
492 } | 492 } |
493 | 493 |
494 | 494 |
495 // Input parameters: | |
496 // S5: ic-data. | |
497 // S4: arguments descriptor array. | |
498 // Note: The receiver object is the first argument to the function being | |
499 // called, the stub accesses the receiver from this location directly | |
500 // when trying to resolve the call. | |
501 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | |
502 __ TraceSimMsg("InstanceFunctionLookupStub"); | |
503 __ EnterStubFrame(); | |
504 | |
505 // Load the receiver. | |
506 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | |
507 __ sll(TMP, A1, 1); // A1 is Smi. | |
508 __ addu(TMP, FP, TMP); | |
509 __ lw(T1, Address(TMP, kParamEndSlotFromFp * kWordSize)); | |
510 | |
511 // Push space for the return value. | |
512 // Push the receiver. | |
513 // Push TMP data object. | |
514 // Push arguments descriptor array. | |
515 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | |
516 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | |
517 __ sw(TMP, Address(SP, 3 * kWordSize)); | |
518 __ sw(T1, Address(SP, 2 * kWordSize)); | |
519 __ sw(S5, Address(SP, 1 * kWordSize)); | |
520 __ sw(S4, Address(SP, 0 * kWordSize)); | |
521 | |
522 // A1: Smi-tagged arguments array length. | |
523 PushArgumentsArray(assembler); | |
524 __ TraceSimMsg("InstanceFunctionLookupStub return"); | |
525 | |
526 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); | |
527 | |
528 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. | |
529 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Remove arguments. | |
530 | |
531 __ LeaveStubFrameAndReturn(); | |
532 } | |
533 | |
534 | |
535 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 495 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
536 intptr_t deopt_reason, | 496 intptr_t deopt_reason, |
537 uword saved_registers_address); | 497 uword saved_registers_address); |
538 | 498 |
539 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); | 499 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); |
540 | 500 |
541 | 501 |
542 // Used by eager and lazy deoptimization. Preserve result in V0 if necessary. | 502 // Used by eager and lazy deoptimization. Preserve result in V0 if necessary. |
543 // This stub translates optimized frame into unoptimized frame. The optimized | 503 // This stub translates optimized frame into unoptimized frame. The optimized |
544 // frame can contain values in registers and on stack, the unoptimized | 504 // frame can contain values in registers and on stack, the unoptimized |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 // Push IC data object. | 661 // Push IC data object. |
702 // Push arguments descriptor array. | 662 // Push arguments descriptor array. |
703 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 663 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
704 __ sw(TMP, Address(SP, 3 * kWordSize)); | 664 __ sw(TMP, Address(SP, 3 * kWordSize)); |
705 __ sw(T6, Address(SP, 2 * kWordSize)); | 665 __ sw(T6, Address(SP, 2 * kWordSize)); |
706 __ sw(S5, Address(SP, 1 * kWordSize)); | 666 __ sw(S5, Address(SP, 1 * kWordSize)); |
707 __ sw(S4, Address(SP, 0 * kWordSize)); | 667 __ sw(S4, Address(SP, 0 * kWordSize)); |
708 | 668 |
709 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 669 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
710 | 670 |
711 __ lw(T0, Address(SP, 3 * kWordSize)); // Get result. | 671 __ lw(T0, Address(SP, 3 * kWordSize)); // Get result function. |
712 __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. | 672 __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. |
713 __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. | 673 __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. |
714 __ addiu(SP, SP, Immediate(6 * kWordSize)); | 674 __ addiu(SP, SP, Immediate(6 * kWordSize)); |
715 | 675 |
716 __ LeaveStubFrame(); | 676 __ LeaveStubFrame(); |
717 | 677 |
718 Label nonnull; | 678 __ lw(T2, FieldAddress(T0, Function::code_offset())); |
719 __ BranchNotEqual(T0, reinterpret_cast<int32_t>(Object::null()), &nonnull); | 679 __ lw(T2, FieldAddress(T2, Code::instructions_offset())); |
720 __ Branch(&StubCode::InstanceFunctionLookupLabel()); | 680 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag); |
721 __ Bind(&nonnull); | 681 __ jr(T2); |
722 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | |
723 __ jr(T0); | |
724 } | 682 } |
725 | 683 |
726 | 684 |
727 // Called for inline allocation of arrays. | 685 // Called for inline allocation of arrays. |
728 // Input parameters: | 686 // Input parameters: |
729 // RA: return address. | 687 // RA: return address. |
730 // A1: Array length as Smi. | 688 // A1: Array length as Smi. |
731 // A0: array element type (either NULL or an instantiated type). | 689 // A0: array element type (either NULL or an instantiated type). |
732 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. | 690 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. |
733 // The newly allocated object is returned in V0. | 691 // The newly allocated object is returned in V0. |
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1669 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); | 1627 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); |
1670 // Push call arguments. | 1628 // Push call arguments. |
1671 for (intptr_t i = 0; i < num_args; i++) { | 1629 for (intptr_t i = 0; i < num_args; i++) { |
1672 __ lw(TMP, Address(T1, -i * kWordSize)); | 1630 __ lw(TMP, Address(T1, -i * kWordSize)); |
1673 __ sw(TMP, Address(SP, (num_slots - i - 4) * kWordSize)); | 1631 __ sw(TMP, Address(SP, (num_slots - i - 4) * kWordSize)); |
1674 } | 1632 } |
1675 // Pass IC data object. | 1633 // Pass IC data object. |
1676 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); | 1634 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); |
1677 __ CallRuntime(handle_ic_miss, num_args + 1); | 1635 __ CallRuntime(handle_ic_miss, num_args + 1); |
1678 __ TraceSimMsg("NArgsCheckInlineCacheStub return"); | 1636 __ TraceSimMsg("NArgsCheckInlineCacheStub return"); |
1679 // Pop returned code object into T3 (null if not found). | 1637 // Pop returned function object into T3. |
1680 // Restore arguments descriptor array and IC data array. | 1638 // Restore arguments descriptor array and IC data array. |
1681 __ lw(T3, Address(SP, (num_slots - 3) * kWordSize)); | 1639 __ lw(T3, Address(SP, (num_slots - 3) * kWordSize)); |
1682 __ lw(S4, Address(SP, (num_slots - 2) * kWordSize)); | 1640 __ lw(S4, Address(SP, (num_slots - 2) * kWordSize)); |
1683 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); | 1641 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); |
1684 // Remove the call arguments pushed earlier, including the IC data object | 1642 // Remove the call arguments pushed earlier, including the IC data object |
1685 // and the arguments descriptor array. | 1643 // and the arguments descriptor array. |
1686 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); | 1644 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); |
1687 __ LeaveStubFrame(); | 1645 __ LeaveStubFrame(); |
| 1646 |
1688 Label call_target_function; | 1647 Label call_target_function; |
1689 __ BranchNotEqual(T3, reinterpret_cast<int32_t>(Object::null()), | 1648 __ b(&call_target_function); |
1690 &call_target_function); | |
1691 | |
1692 // NoSuchMethod or closure. | |
1693 // Mark IC call that it may be a closure call that does not collect | |
1694 // type feedback. | |
1695 __ LoadImmediate(T6, 1); | |
1696 __ Branch(&StubCode::InstanceFunctionLookupLabel()); | |
1697 __ delay_slot()->sb(T6, FieldAddress(S5, ICData::is_closure_call_offset())); | |
1698 | 1649 |
1699 __ Bind(&found); | 1650 __ Bind(&found); |
1700 // T0: Pointer to an IC data check group. | 1651 // T0: Pointer to an IC data check group. |
1701 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; | 1652 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; |
1702 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; | 1653 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; |
1703 __ lw(T3, Address(T0, target_offset)); | 1654 __ lw(T3, Address(T0, target_offset)); |
1704 __ lw(T4, Address(T0, count_offset)); | 1655 __ lw(T4, Address(T0, count_offset)); |
1705 | 1656 |
1706 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); | 1657 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); |
1707 | 1658 |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 const Register right = T0; | 2191 const Register right = T0; |
2241 __ lw(left, Address(SP, 1 * kWordSize)); | 2192 __ lw(left, Address(SP, 1 * kWordSize)); |
2242 __ lw(right, Address(SP, 0 * kWordSize)); | 2193 __ lw(right, Address(SP, 0 * kWordSize)); |
2243 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2194 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2244 __ Ret(); | 2195 __ Ret(); |
2245 } | 2196 } |
2246 | 2197 |
2247 } // namespace dart | 2198 } // namespace dart |
2248 | 2199 |
2249 #endif // defined TARGET_ARCH_MIPS | 2200 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |