| 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 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 } else { | 1574 } else { |
| 1575 // Make sure that class CallPattern is able to decode this load from the | 1575 // Make sure that class CallPattern is able to decode this load from the |
| 1576 // object pool. | 1576 // object pool. |
| 1577 const int32_t offset = | 1577 const int32_t offset = |
| 1578 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); | 1578 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); |
| 1579 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond); | 1579 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond); |
| 1580 } | 1580 } |
| 1581 } | 1581 } |
| 1582 | 1582 |
| 1583 | 1583 |
| 1584 void Assembler::LoadExternalLabel(Register rd, |
| 1585 const ExternalLabel* label, |
| 1586 Patchability patchable, |
| 1587 Condition cond) { |
| 1588 const int32_t offset = ObjectPool::element_offset( |
| 1589 object_pool_wrapper_.FindExternalLabel(label, patchable)); |
| 1590 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond); |
| 1591 } |
| 1592 |
| 1593 |
| 1584 void Assembler::PushObject(const Object& object) { | 1594 void Assembler::PushObject(const Object& object) { |
| 1585 LoadObject(IP, object); | 1595 LoadObject(IP, object); |
| 1586 Push(IP); | 1596 Push(IP); |
| 1587 } | 1597 } |
| 1588 | 1598 |
| 1589 | 1599 |
| 1590 void Assembler::CompareObject(Register rn, const Object& object) { | 1600 void Assembler::CompareObject(Register rn, const Object& object) { |
| 1591 ASSERT(rn != IP); | 1601 ASSERT(rn != IP); |
| 1592 if (object.IsSmi()) { | 1602 if (object.IsSmi()) { |
| 1593 CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw())); | 1603 CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw())); |
| (...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2648 bx(IP); | 2658 bx(IP); |
| 2649 } | 2659 } |
| 2650 | 2660 |
| 2651 | 2661 |
| 2652 void Assembler::BranchLink(const ExternalLabel* label) { | 2662 void Assembler::BranchLink(const ExternalLabel* label) { |
| 2653 LoadImmediate(LR, label->address()); // Target address is never patched. | 2663 LoadImmediate(LR, label->address()); // Target address is never patched. |
| 2654 blx(LR); // Use blx instruction so that the return branch prediction works. | 2664 blx(LR); // Use blx instruction so that the return branch prediction works. |
| 2655 } | 2665 } |
| 2656 | 2666 |
| 2657 | 2667 |
| 2658 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { | 2668 void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) { |
| 2659 // Make sure that class CallPattern is able to patch the label referred | 2669 // Make sure that class CallPattern is able to patch the label referred |
| 2660 // to by this code sequence. | 2670 // to by this code sequence. |
| 2661 // For added code robustness, use 'blx lr' in a patchable sequence and | 2671 // For added code robustness, use 'blx lr' in a patchable sequence and |
| 2662 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). | 2672 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). |
| 2663 const int32_t offset = ObjectPool::element_offset( | 2673 const int32_t offset = ObjectPool::element_offset( |
| 2664 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); | 2674 object_pool_wrapper_.FindExternalLabel(label, patchable)); |
| 2665 LoadWordFromPoolOffset(LR, offset - kHeapObjectTag); | 2675 LoadWordFromPoolOffset(LR, offset - kHeapObjectTag); |
| 2666 blx(LR); // Use blx instruction so that the return branch prediction works. | 2676 blx(LR); // Use blx instruction so that the return branch prediction works. |
| 2667 } | 2677 } |
| 2668 | 2678 |
| 2669 | 2679 |
| 2680 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { |
| 2681 BranchLink(label, kPatchable); |
| 2682 } |
| 2683 |
| 2684 |
| 2670 void Assembler::BranchLinkOffset(Register base, int32_t offset) { | 2685 void Assembler::BranchLinkOffset(Register base, int32_t offset) { |
| 2671 ASSERT(base != PC); | 2686 ASSERT(base != PC); |
| 2672 ASSERT(base != IP); | 2687 ASSERT(base != IP); |
| 2673 LoadFromOffset(kWord, IP, base, offset); | 2688 LoadFromOffset(kWord, IP, base, offset); |
| 2674 blx(IP); // Use blx instruction so that the return branch prediction works. | 2689 blx(IP); // Use blx instruction so that the return branch prediction works. |
| 2675 } | 2690 } |
| 2676 | 2691 |
| 2677 | 2692 |
| 2678 void Assembler::LoadPatchableImmediate( | 2693 void Assembler::LoadPatchableImmediate( |
| 2679 Register rd, int32_t value, Condition cond) { | 2694 Register rd, int32_t value, Condition cond) { |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3275 } | 3290 } |
| 3276 | 3291 |
| 3277 | 3292 |
| 3278 void Assembler::LeaveDartFrame() { | 3293 void Assembler::LeaveDartFrame() { |
| 3279 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); | 3294 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); |
| 3280 // Adjust SP for PC pushed in EnterDartFrame. | 3295 // Adjust SP for PC pushed in EnterDartFrame. |
| 3281 AddImmediate(SP, kWordSize); | 3296 AddImmediate(SP, kWordSize); |
| 3282 } | 3297 } |
| 3283 | 3298 |
| 3284 | 3299 |
| 3285 void Assembler::EnterStubFrame(bool load_pp) { | 3300 void Assembler::EnterStubFrame() { |
| 3286 // Push 0 as saved PC for stub frames. | 3301 // Push 0 as saved PC for stub frames. |
| 3287 mov(IP, Operand(LR)); | 3302 mov(IP, Operand(LR)); |
| 3288 mov(LR, Operand(0)); | 3303 mov(LR, Operand(0)); |
| 3289 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR); | 3304 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR); |
| 3290 EnterFrame(regs, 0); | 3305 EnterFrame(regs, 0); |
| 3291 if (load_pp) { | 3306 // Setup pool pointer for this stub. |
| 3292 // Setup pool pointer for this stub. | 3307 LoadPoolPointer(); |
| 3293 LoadPoolPointer(); | |
| 3294 } | |
| 3295 } | 3308 } |
| 3296 | 3309 |
| 3297 | 3310 |
| 3298 void Assembler::LeaveStubFrame() { | 3311 void Assembler::LeaveStubFrame() { |
| 3299 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); | 3312 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); |
| 3300 // Adjust SP for null PC pushed in EnterStubFrame. | 3313 // Adjust SP for null PC pushed in EnterStubFrame. |
| 3301 AddImmediate(SP, kWordSize); | 3314 AddImmediate(SP, kWordSize); |
| 3302 } | 3315 } |
| 3303 | 3316 |
| 3304 | 3317 |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3569 | 3582 |
| 3570 | 3583 |
| 3571 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3584 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3572 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3585 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 3573 return fpu_reg_names[reg]; | 3586 return fpu_reg_names[reg]; |
| 3574 } | 3587 } |
| 3575 | 3588 |
| 3576 } // namespace dart | 3589 } // namespace dart |
| 3577 | 3590 |
| 3578 #endif // defined TARGET_ARCH_ARM | 3591 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |