| 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" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 2666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2677 vmulqs(qd, qn, qd); | 2677 vmulqs(qd, qn, qd); |
| 2678 } | 2678 } |
| 2679 | 2679 |
| 2680 | 2680 |
| 2681 void Assembler::Branch(const ExternalLabel* label, Condition cond) { | 2681 void Assembler::Branch(const ExternalLabel* label, Condition cond) { |
| 2682 LoadImmediate(IP, label->address(), cond); // Address is never patched. | 2682 LoadImmediate(IP, label->address(), cond); // Address is never patched. |
| 2683 bx(IP, cond); | 2683 bx(IP, cond); |
| 2684 } | 2684 } |
| 2685 | 2685 |
| 2686 | 2686 |
| 2687 void Assembler::Branch(const StubEntry& stub_entry, Condition cond) { |
| 2688 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2689 Branch(&label, cond); |
| 2690 } |
| 2691 |
| 2692 |
| 2687 void Assembler::BranchPatchable(const ExternalLabel* label) { | 2693 void Assembler::BranchPatchable(const ExternalLabel* label) { |
| 2688 // Use a fixed size code sequence, since a function prologue may be patched | 2694 // Use a fixed size code sequence, since a function prologue may be patched |
| 2689 // with this branch sequence. | 2695 // with this branch sequence. |
| 2690 // Contrarily to BranchLinkPatchable, BranchPatchable requires an instruction | 2696 // Contrarily to BranchLinkPatchable, BranchPatchable requires an instruction |
| 2691 // cache flush upon patching. | 2697 // cache flush upon patching. |
| 2692 LoadPatchableImmediate(IP, label->address()); | 2698 LoadPatchableImmediate(IP, label->address()); |
| 2693 bx(IP); | 2699 bx(IP); |
| 2694 } | 2700 } |
| 2695 | 2701 |
| 2696 | 2702 |
| 2703 void Assembler::BranchPatchable(const StubEntry& stub_entry) { |
| 2704 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2705 BranchPatchable(&label); |
| 2706 } |
| 2707 |
| 2708 |
| 2697 void Assembler::BranchLink(const ExternalLabel* label) { | 2709 void Assembler::BranchLink(const ExternalLabel* label) { |
| 2698 LoadImmediate(LR, label->address()); // Target address is never patched. | 2710 LoadImmediate(LR, label->address()); // Target address is never patched. |
| 2699 blx(LR); // Use blx instruction so that the return branch prediction works. | 2711 blx(LR); // Use blx instruction so that the return branch prediction works. |
| 2700 } | 2712 } |
| 2701 | 2713 |
| 2702 | 2714 |
| 2715 void Assembler::BranchLink(const StubEntry& stub_entry) { |
| 2716 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2717 BranchLink(&label); |
| 2718 } |
| 2719 |
| 2720 |
| 2703 void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) { | 2721 void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) { |
| 2704 // Make sure that class CallPattern is able to patch the label referred | 2722 // Make sure that class CallPattern is able to patch the label referred |
| 2705 // to by this code sequence. | 2723 // to by this code sequence. |
| 2706 // For added code robustness, use 'blx lr' in a patchable sequence and | 2724 // For added code robustness, use 'blx lr' in a patchable sequence and |
| 2707 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). | 2725 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). |
| 2708 const int32_t offset = ObjectPool::element_offset( | 2726 const int32_t offset = ObjectPool::element_offset( |
| 2709 object_pool_wrapper_.FindExternalLabel(label, patchable)); | 2727 object_pool_wrapper_.FindExternalLabel(label, patchable)); |
| 2710 LoadWordFromPoolOffset(LR, offset - kHeapObjectTag); | 2728 LoadWordFromPoolOffset(LR, offset - kHeapObjectTag); |
| 2711 blx(LR); // Use blx instruction so that the return branch prediction works. | 2729 blx(LR); // Use blx instruction so that the return branch prediction works. |
| 2712 } | 2730 } |
| 2713 | 2731 |
| 2714 | 2732 |
| 2733 void Assembler::BranchLink(const StubEntry& stub_entry, |
| 2734 Patchability patchable) { |
| 2735 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2736 BranchLink(&label, patchable); |
| 2737 } |
| 2738 |
| 2739 |
| 2715 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { | 2740 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { |
| 2716 BranchLink(label, kPatchable); | 2741 BranchLink(label, kPatchable); |
| 2717 } | 2742 } |
| 2718 | 2743 |
| 2719 | 2744 |
| 2745 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) { |
| 2746 const ExternalLabel label(stub_entry.EntryPoint()); |
| 2747 BranchLinkPatchable(&label); |
| 2748 } |
| 2749 |
| 2750 |
| 2720 void Assembler::BranchLinkOffset(Register base, int32_t offset) { | 2751 void Assembler::BranchLinkOffset(Register base, int32_t offset) { |
| 2721 ASSERT(base != PC); | 2752 ASSERT(base != PC); |
| 2722 ASSERT(base != IP); | 2753 ASSERT(base != IP); |
| 2723 LoadFromOffset(kWord, IP, base, offset); | 2754 LoadFromOffset(kWord, IP, base, offset); |
| 2724 blx(IP); // Use blx instruction so that the return branch prediction works. | 2755 blx(IP); // Use blx instruction so that the return branch prediction works. |
| 2725 } | 2756 } |
| 2726 | 2757 |
| 2727 | 2758 |
| 2728 void Assembler::LoadPatchableImmediate( | 2759 void Assembler::LoadPatchableImmediate( |
| 2729 Register rd, int32_t value, Condition cond) { | 2760 Register rd, int32_t value, Condition cond) { |
| (...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3538 b(failure); | 3569 b(failure); |
| 3539 } | 3570 } |
| 3540 } | 3571 } |
| 3541 | 3572 |
| 3542 | 3573 |
| 3543 void Assembler::Stop(const char* message) { | 3574 void Assembler::Stop(const char* message) { |
| 3544 if (FLAG_print_stop_message) { | 3575 if (FLAG_print_stop_message) { |
| 3545 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. | 3576 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. |
| 3546 LoadImmediate(R0, reinterpret_cast<int32_t>(message)); | 3577 LoadImmediate(R0, reinterpret_cast<int32_t>(message)); |
| 3547 // PrintStopMessage() preserves all registers. | 3578 // PrintStopMessage() preserves all registers. |
| 3548 BranchLink(&StubCode::PrintStopMessageLabel()); // Passing message in R0. | 3579 BranchLink(&StubCode::PrintStopMessage_entry()->label()); |
| 3549 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. | 3580 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. |
| 3550 } | 3581 } |
| 3551 // Emit the message address before the svc instruction, so that we can | 3582 // Emit the message address before the svc instruction, so that we can |
| 3552 // 'unstop' and continue execution in the simulator or jump to the next | 3583 // 'unstop' and continue execution in the simulator or jump to the next |
| 3553 // instruction in gdb. | 3584 // instruction in gdb. |
| 3554 Label stop; | 3585 Label stop; |
| 3555 b(&stop); | 3586 b(&stop); |
| 3556 Emit(reinterpret_cast<int32_t>(message)); | 3587 Emit(reinterpret_cast<int32_t>(message)); |
| 3557 Bind(&stop); | 3588 Bind(&stop); |
| 3558 bkpt(Instr::kStopMessageCode); | 3589 bkpt(Instr::kStopMessageCode); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3647 | 3678 |
| 3648 | 3679 |
| 3649 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3680 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3650 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3681 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 3651 return fpu_reg_names[reg]; | 3682 return fpu_reg_names[reg]; |
| 3652 } | 3683 } |
| 3653 | 3684 |
| 3654 } // namespace dart | 3685 } // namespace dart |
| 3655 | 3686 |
| 3656 #endif // defined TARGET_ARCH_ARM | 3687 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |