| 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_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 | 9 |
| 10 #include "vm/runtime_entry.h" |
| 10 #include "vm/stub_code.h" | 11 #include "vm/stub_code.h" |
| 11 | 12 |
| 12 namespace dart { | 13 namespace dart { |
| 13 | 14 |
| 14 // TODO(regis): Enable this flag after PrintStopMessage stub is implemented. | 15 // TODO(regis): Enable this flag after PrintStopMessage stub is implemented. |
| 15 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); | 16 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); |
| 16 | 17 |
| 17 | 18 |
| 18 // Instruction encoding bits. | 19 // Instruction encoding bits. |
| 19 enum { | 20 enum { |
| (...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 | 1119 |
| 1119 void Assembler::MarkExceptionHandler(Label* label) { | 1120 void Assembler::MarkExceptionHandler(Label* label) { |
| 1120 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); | 1121 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); |
| 1121 Label l; | 1122 Label l; |
| 1122 b(&l); | 1123 b(&l); |
| 1123 EmitBranch(AL, label, false); | 1124 EmitBranch(AL, label, false); |
| 1124 Bind(&l); | 1125 Bind(&l); |
| 1125 } | 1126 } |
| 1126 | 1127 |
| 1127 | 1128 |
| 1129 void Assembler::Drop(intptr_t stack_elements) { |
| 1130 ASSERT(stack_elements >= 0); |
| 1131 if (stack_elements > 0) { |
| 1132 AddImmediate(SP, SP, stack_elements * kWordSize); |
| 1133 } |
| 1134 } |
| 1135 |
| 1136 |
| 1128 void Assembler::LoadObject(Register rd, const Object& object) { | 1137 void Assembler::LoadObject(Register rd, const Object& object) { |
| 1129 if (object.IsNull() || | 1138 if (object.IsNull() || |
| 1130 object.IsSmi() || | 1139 object.IsSmi() || |
| 1131 (object.raw() == Bool::True().raw()) || | 1140 (object.raw() == Bool::True().raw()) || |
| 1132 (object.raw() == Bool::False().raw())) { | 1141 (object.raw() == Bool::False().raw())) { |
| 1133 // This object is never relocated; do not use object pool. | 1142 // This object is never relocated; do not use object pool. |
| 1134 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); | 1143 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); |
| 1135 return; | 1144 return; |
| 1136 } | 1145 } |
| 1137 const int32_t offset = | 1146 const int32_t offset = |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1654 void Assembler::Ret() { | 1663 void Assembler::Ret() { |
| 1655 bx(LR); | 1664 bx(LR); |
| 1656 } | 1665 } |
| 1657 | 1666 |
| 1658 | 1667 |
| 1659 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 1668 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { |
| 1660 // Reserve space for arguments and align frame before entering | 1669 // Reserve space for arguments and align frame before entering |
| 1661 // the C++ world. | 1670 // the C++ world. |
| 1662 AddImmediate(SP, -frame_space); | 1671 AddImmediate(SP, -frame_space); |
| 1663 if (OS::ActivationFrameAlignment() > 0) { | 1672 if (OS::ActivationFrameAlignment() > 0) { |
| 1664 and_(SP, SP, ShifterOperand(~(OS::ActivationFrameAlignment() - 1))); | 1673 bic(SP, SP, ShifterOperand(OS::ActivationFrameAlignment() - 1)); |
| 1665 } | 1674 } |
| 1666 } | 1675 } |
| 1667 | 1676 |
| 1668 | 1677 |
| 1678 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { |
| 1679 // Preserve volatile CPU registers. |
| 1680 EnterFrame(kDartVolatileCpuRegs | (1 << FP), 0); |
| 1681 |
| 1682 // Preserve all volatile FPU registers. |
| 1683 // TODO(regis): Use vstmd instruction once supported. |
| 1684 // vstmd(DB_W, SP, kDartFirstVolatileFpuReg, kDartLastVolatileFpuReg); |
| 1685 |
| 1686 ReserveAlignedFrameSpace(frame_space); |
| 1687 } |
| 1688 |
| 1689 |
| 1690 void Assembler::LeaveCallRuntimeFrame() { |
| 1691 // SP might have been modified to reserve space for arguments |
| 1692 // and ensure proper alignment of the stack frame. |
| 1693 // We need to restore it before restoring registers. |
| 1694 const intptr_t kPushedRegistersSize = |
| 1695 kDartVolatileCpuRegCount * kWordSize; |
| 1696 // TODO(regis): + kDartVolatileFpuRegCount * 2 * kWordSize; |
| 1697 AddImmediate(SP, FP, -kPushedRegistersSize); |
| 1698 |
| 1699 // Restore all volatile FPU registers. |
| 1700 // TODO(regis): Use vldmd instruction once supported. |
| 1701 // vldmd(IA_W, SP, kDartFirstVolatileFpuReg, kDartLastVolatileFpuReg); |
| 1702 |
| 1703 // Restore volatile CPU registers. |
| 1704 LeaveFrame(kDartVolatileCpuRegs | (1 << FP)); |
| 1705 } |
| 1706 |
| 1707 |
| 1708 void Assembler::CallRuntime(const RuntimeEntry& entry) { |
| 1709 entry.Call(this); |
| 1710 } |
| 1711 |
| 1712 |
| 1669 void Assembler::Stop(const char* message) { | 1713 void Assembler::Stop(const char* message) { |
| 1670 if (FLAG_print_stop_message) { | 1714 if (FLAG_print_stop_message) { |
| 1671 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. | 1715 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. |
| 1672 LoadImmediate(R0, reinterpret_cast<int32_t>(message)); | 1716 LoadImmediate(R0, reinterpret_cast<int32_t>(message)); |
| 1673 // PrintStopMessage() preserves all registers. | 1717 // PrintStopMessage() preserves all registers. |
| 1674 BranchLink(&StubCode::PrintStopMessageLabel()); // Passing message in R0. | 1718 BranchLink(&StubCode::PrintStopMessageLabel()); // Passing message in R0. |
| 1675 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. | 1719 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. |
| 1676 } | 1720 } |
| 1677 // Emit the message address before the svc instruction, so that we can | 1721 // Emit the message address before the svc instruction, so that we can |
| 1678 // 'unstop' and continue execution in the simulator or jump to the next | 1722 // 'unstop' and continue execution in the simulator or jump to the next |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 // Do not reuse an existing entry, since each reference may be patched | 1777 // Do not reuse an existing entry, since each reference may be patched |
| 1734 // independently. | 1778 // independently. |
| 1735 object_pool_.Add(smi); | 1779 object_pool_.Add(smi); |
| 1736 return object_pool_.Length() - 1; | 1780 return object_pool_.Length() - 1; |
| 1737 } | 1781 } |
| 1738 | 1782 |
| 1739 } // namespace dart | 1783 } // namespace dart |
| 1740 | 1784 |
| 1741 #endif // defined TARGET_ARCH_ARM | 1785 #endif // defined TARGET_ARCH_ARM |
| 1742 | 1786 |
| OLD | NEW |