Chromium Code Reviews| 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" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1496 | 1496 |
| 1497 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { | 1497 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { |
| 1498 // TODO(vegorov): consider saving only caller save (volatile) registers. | 1498 // TODO(vegorov): consider saving only caller save (volatile) registers. |
| 1499 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count(); | 1499 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count(); |
| 1500 if (fpu_regs_count > 0) { | 1500 if (fpu_regs_count > 0) { |
| 1501 __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize)); | 1501 __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize)); |
| 1502 // Store fpu registers with the lowest register number at the lowest | 1502 // Store fpu registers with the lowest register number at the lowest |
| 1503 // address. | 1503 // address. |
| 1504 intptr_t offset = 0; | 1504 intptr_t offset = 0; |
| 1505 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { | 1505 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { |
| 1506 DRegister fpu_reg = static_cast<DRegister>(reg_idx); | 1506 QRegister fpu_reg = static_cast<QRegister>(reg_idx); |
| 1507 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { | 1507 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { |
| 1508 __ vstrd(fpu_reg, Address(SP, offset)); | 1508 DRegister d1 = static_cast<DRegister>(fpu_reg * 2); |
| 1509 DRegister d2 = static_cast<DRegister>(fpu_reg * 2 + 1); | |
|
regis
2013/07/12 22:16:01
Use macros
zra
2013/07/12 23:22:18
Done.
| |
| 1510 __ vstrd(d1, Address(SP, offset)); | |
| 1511 __ vstrd(d2, Address(SP, offset + 2 * kWordSize)); | |
| 1509 offset += kFpuRegisterSize; | 1512 offset += kFpuRegisterSize; |
| 1510 } | 1513 } |
| 1511 } | 1514 } |
| 1512 ASSERT(offset == (fpu_regs_count * kFpuRegisterSize)); | 1515 ASSERT(offset == (fpu_regs_count * kFpuRegisterSize)); |
| 1513 } | 1516 } |
| 1514 | 1517 |
| 1515 // Store general purpose registers with the lowest register number at the | 1518 // Store general purpose registers with the lowest register number at the |
| 1516 // lowest address. | 1519 // lowest address. |
| 1517 const intptr_t cpu_registers = locs->live_registers()->cpu_registers(); | 1520 const intptr_t cpu_registers = locs->live_registers()->cpu_registers(); |
| 1518 ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0); | 1521 ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1529 ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0); | 1532 ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0); |
| 1530 if (cpu_registers != 0) { | 1533 if (cpu_registers != 0) { |
| 1531 __ PopList(cpu_registers); | 1534 __ PopList(cpu_registers); |
| 1532 } | 1535 } |
| 1533 | 1536 |
| 1534 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count(); | 1537 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count(); |
| 1535 if (fpu_regs_count > 0) { | 1538 if (fpu_regs_count > 0) { |
| 1536 // Fpu registers have the lowest register number at the lowest address. | 1539 // Fpu registers have the lowest register number at the lowest address. |
| 1537 intptr_t offset = 0; | 1540 intptr_t offset = 0; |
| 1538 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { | 1541 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { |
| 1539 DRegister fpu_reg = static_cast<DRegister>(reg_idx); | 1542 QRegister fpu_reg = static_cast<QRegister>(reg_idx); |
| 1540 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { | 1543 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { |
| 1541 __ vldrd(fpu_reg, Address(SP, offset)); | 1544 DRegister d1 = static_cast<DRegister>(fpu_reg * 2); |
| 1545 DRegister d2 = static_cast<DRegister>(fpu_reg * 2 + 1); | |
| 1546 __ vldrd(d1, Address(SP, offset)); | |
| 1547 __ vldrd(d2, Address(SP, offset + 2 * kWordSize)); | |
| 1542 offset += kFpuRegisterSize; | 1548 offset += kFpuRegisterSize; |
| 1543 } | 1549 } |
| 1544 } | 1550 } |
| 1545 ASSERT(offset == (fpu_regs_count * kFpuRegisterSize)); | 1551 ASSERT(offset == (fpu_regs_count * kFpuRegisterSize)); |
| 1546 __ AddImmediate(SP, offset); | 1552 __ AddImmediate(SP, offset); |
| 1547 } | 1553 } |
| 1548 } | 1554 } |
| 1549 | 1555 |
| 1550 | 1556 |
| 1551 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, | 1557 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1594 } | 1600 } |
| 1595 assembler()->Bind(&match_found); | 1601 assembler()->Bind(&match_found); |
| 1596 } | 1602 } |
| 1597 | 1603 |
| 1598 | 1604 |
| 1599 void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition, | 1605 void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition, |
| 1600 FpuRegister left, | 1606 FpuRegister left, |
| 1601 FpuRegister right, | 1607 FpuRegister right, |
| 1602 BranchInstr* branch) { | 1608 BranchInstr* branch) { |
| 1603 ASSERT(branch != NULL); | 1609 ASSERT(branch != NULL); |
| 1604 assembler()->vcmpd(left, right); | 1610 DRegister dleft = static_cast<DRegister>(left * 2); |
| 1611 DRegister dright = static_cast<DRegister>(right * 2); | |
| 1612 assembler()->vcmpd(dleft, dright); | |
| 1605 assembler()->vmstat(); | 1613 assembler()->vmstat(); |
| 1606 BlockEntryInstr* nan_result = (true_condition == NE) ? | 1614 BlockEntryInstr* nan_result = (true_condition == NE) ? |
| 1607 branch->true_successor() : branch->false_successor(); | 1615 branch->true_successor() : branch->false_successor(); |
| 1608 assembler()->b(GetJumpLabel(nan_result), VS); | 1616 assembler()->b(GetJumpLabel(nan_result), VS); |
| 1609 branch->EmitBranchOnCondition(this, true_condition); | 1617 branch->EmitBranchOnCondition(this, true_condition); |
| 1610 } | 1618 } |
| 1611 | 1619 |
| 1612 | 1620 |
| 1613 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition, | 1621 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition, |
| 1614 FpuRegister left, | 1622 FpuRegister left, |
| 1615 FpuRegister right, | 1623 FpuRegister right, |
| 1616 Register result) { | 1624 Register result) { |
| 1617 assembler()->vcmpd(left, right); | 1625 DRegister dleft = static_cast<DRegister>(left * 2); |
| 1626 DRegister dright = static_cast<DRegister>(right * 2); | |
| 1627 assembler()->vcmpd(dleft, dright); | |
| 1618 assembler()->vmstat(); | 1628 assembler()->vmstat(); |
| 1619 assembler()->LoadObject(result, Bool::False()); | 1629 assembler()->LoadObject(result, Bool::False()); |
| 1620 Label done; | 1630 Label done; |
| 1621 assembler()->b(&done, VS); // NaN -> false. | 1631 assembler()->b(&done, VS); // NaN -> false. |
| 1622 assembler()->LoadObject(result, Bool::True(), true_condition); | 1632 assembler()->LoadObject(result, Bool::True(), true_condition); |
| 1623 assembler()->Bind(&done); | 1633 assembler()->Bind(&done); |
| 1624 } | 1634 } |
| 1625 | 1635 |
| 1626 | 1636 |
| 1627 // Do not impelement or use this function. | 1637 // Do not impelement or use this function. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1681 } else if (source.IsStackSlot()) { | 1691 } else if (source.IsStackSlot()) { |
| 1682 if (destination.IsRegister()) { | 1692 if (destination.IsRegister()) { |
| 1683 __ ldr(destination.reg(), source.ToStackSlotAddress()); | 1693 __ ldr(destination.reg(), source.ToStackSlotAddress()); |
| 1684 } else { | 1694 } else { |
| 1685 ASSERT(destination.IsStackSlot()); | 1695 ASSERT(destination.IsStackSlot()); |
| 1686 MoveMemoryToMemory(destination.ToStackSlotAddress(), | 1696 MoveMemoryToMemory(destination.ToStackSlotAddress(), |
| 1687 source.ToStackSlotAddress()); | 1697 source.ToStackSlotAddress()); |
| 1688 } | 1698 } |
| 1689 } else if (source.IsFpuRegister()) { | 1699 } else if (source.IsFpuRegister()) { |
| 1690 if (destination.IsFpuRegister()) { | 1700 if (destination.IsFpuRegister()) { |
| 1691 __ vmovd(destination.fpu_reg(), source.fpu_reg()); | 1701 DRegister dst = static_cast<DRegister>(destination.fpu_reg() * 2); |
| 1702 DRegister src = static_cast<DRegister>(source.fpu_reg() * 2); | |
| 1703 __ vmovd(dst, src); | |
| 1692 } else { | 1704 } else { |
| 1693 if (destination.IsDoubleStackSlot()) { | 1705 if (destination.IsDoubleStackSlot()) { |
| 1694 __ vstrd(source.fpu_reg(), destination.ToStackSlotAddress()); | 1706 DRegister src = static_cast<DRegister>(source.fpu_reg() * 2); |
| 1707 __ vstrd(src, destination.ToStackSlotAddress()); | |
| 1695 } else { | 1708 } else { |
| 1696 ASSERT(destination.IsQuadStackSlot()); | 1709 ASSERT(destination.IsQuadStackSlot()); |
| 1697 UNIMPLEMENTED(); | 1710 UNIMPLEMENTED(); |
| 1698 } | 1711 } |
| 1699 } | 1712 } |
| 1700 } else if (source.IsDoubleStackSlot()) { | 1713 } else if (source.IsDoubleStackSlot()) { |
| 1701 if (destination.IsFpuRegister()) { | 1714 if (destination.IsFpuRegister()) { |
| 1702 __ vldrd(destination.fpu_reg(), source.ToStackSlotAddress()); | 1715 DRegister dst = static_cast<DRegister>(destination.fpu_reg() * 2); |
| 1716 __ vldrd(dst, source.ToStackSlotAddress()); | |
| 1703 } else { | 1717 } else { |
| 1704 ASSERT(destination.IsDoubleStackSlot()); | 1718 ASSERT(destination.IsDoubleStackSlot()); |
| 1705 __ vldrd(DTMP, source.ToStackSlotAddress()); | 1719 __ vldrd(DTMP, source.ToStackSlotAddress()); |
| 1706 __ vstrd(DTMP, destination.ToStackSlotAddress()); | 1720 __ vstrd(DTMP, destination.ToStackSlotAddress()); |
| 1707 } | 1721 } |
| 1708 } else if (source.IsQuadStackSlot()) { | 1722 } else if (source.IsQuadStackSlot()) { |
| 1709 UNIMPLEMENTED(); | 1723 UNIMPLEMENTED(); |
| 1710 } else { | 1724 } else { |
| 1711 ASSERT(source.IsConstant()); | 1725 ASSERT(source.IsConstant()); |
| 1712 if (destination.IsRegister()) { | 1726 if (destination.IsRegister()) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1733 __ mov(IP, ShifterOperand(source.reg())); | 1747 __ mov(IP, ShifterOperand(source.reg())); |
| 1734 __ mov(source.reg(), ShifterOperand(destination.reg())); | 1748 __ mov(source.reg(), ShifterOperand(destination.reg())); |
| 1735 __ mov(destination.reg(), ShifterOperand(IP)); | 1749 __ mov(destination.reg(), ShifterOperand(IP)); |
| 1736 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1750 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1737 Exchange(source.reg(), destination.ToStackSlotAddress()); | 1751 Exchange(source.reg(), destination.ToStackSlotAddress()); |
| 1738 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1752 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1739 Exchange(destination.reg(), source.ToStackSlotAddress()); | 1753 Exchange(destination.reg(), source.ToStackSlotAddress()); |
| 1740 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1754 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1741 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); | 1755 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); |
| 1742 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1756 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1743 __ vmovd(DTMP, source.fpu_reg()); | 1757 DRegister dst = static_cast<DRegister>(destination.fpu_reg() * 2); |
| 1744 __ vmovd(source.fpu_reg(), destination.fpu_reg()); | 1758 DRegister src = static_cast<DRegister>(source.fpu_reg() * 2); |
| 1745 __ vmovd(destination.fpu_reg(), DTMP); | 1759 __ vmovd(DTMP, src); |
| 1760 __ vmovd(src, dst); | |
| 1761 __ vmovd(dst, DTMP); | |
| 1746 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1762 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1747 ASSERT(destination.IsDoubleStackSlot() || | 1763 ASSERT(destination.IsDoubleStackSlot() || |
| 1748 destination.IsQuadStackSlot() || | 1764 destination.IsQuadStackSlot() || |
| 1749 source.IsDoubleStackSlot() || | 1765 source.IsDoubleStackSlot() || |
| 1750 source.IsQuadStackSlot()); | 1766 source.IsQuadStackSlot()); |
| 1751 bool double_width = destination.IsDoubleStackSlot() || | 1767 bool double_width = destination.IsDoubleStackSlot() || |
| 1752 source.IsDoubleStackSlot(); | 1768 source.IsDoubleStackSlot(); |
| 1753 DRegister reg = source.IsFpuRegister() ? source.fpu_reg() | 1769 QRegister qreg = source.IsFpuRegister() ? source.fpu_reg() |
| 1754 : destination.fpu_reg(); | 1770 : destination.fpu_reg(); |
| 1771 DRegister reg = static_cast<DRegister>(qreg * 2); | |
| 1755 const Address& slot_address = source.IsFpuRegister() | 1772 const Address& slot_address = source.IsFpuRegister() |
| 1756 ? destination.ToStackSlotAddress() | 1773 ? destination.ToStackSlotAddress() |
| 1757 : source.ToStackSlotAddress(); | 1774 : source.ToStackSlotAddress(); |
| 1758 | 1775 |
| 1759 if (double_width) { | 1776 if (double_width) { |
| 1760 __ vldrd(DTMP, slot_address); | 1777 __ vldrd(DTMP, slot_address); |
| 1761 __ vstrd(reg, slot_address); | 1778 __ vstrd(reg, slot_address); |
| 1762 __ vmovd(reg, DTMP); | 1779 __ vmovd(reg, DTMP); |
| 1763 } else { | 1780 } else { |
| 1764 UNIMPLEMENTED(); | 1781 UNIMPLEMENTED(); |
| 1765 } | 1782 } |
| 1766 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { | 1783 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { |
| 1767 const Address& source_slot_address = source.ToStackSlotAddress(); | 1784 const Address& source_slot_address = source.ToStackSlotAddress(); |
| 1768 const Address& destination_slot_address = destination.ToStackSlotAddress(); | 1785 const Address& destination_slot_address = destination.ToStackSlotAddress(); |
| 1769 | 1786 |
| 1770 ScratchFpuRegisterScope ensure_scratch(this, DTMP); | 1787 ScratchFpuRegisterScope ensure_scratch(this, QTMP); |
| 1788 DRegister scratch = static_cast<DRegister>(ensure_scratch.reg() * 2); | |
| 1771 __ vldrd(DTMP, source_slot_address); | 1789 __ vldrd(DTMP, source_slot_address); |
| 1772 __ vldrd(ensure_scratch.reg(), destination_slot_address); | 1790 __ vldrd(scratch, destination_slot_address); |
| 1773 __ vstrd(DTMP, destination_slot_address); | 1791 __ vstrd(DTMP, destination_slot_address); |
| 1774 __ vstrd(ensure_scratch.reg(), source_slot_address); | 1792 __ vstrd(scratch, source_slot_address); |
| 1775 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { | 1793 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { |
| 1776 UNIMPLEMENTED(); | 1794 UNIMPLEMENTED(); |
| 1777 } else { | 1795 } else { |
| 1778 UNREACHABLE(); | 1796 UNREACHABLE(); |
| 1779 } | 1797 } |
| 1780 | 1798 |
| 1781 // The swap of source and destination has executed a move from source to | 1799 // The swap of source and destination has executed a move from source to |
| 1782 // destination. | 1800 // destination. |
| 1783 move->Eliminate(); | 1801 move->Eliminate(); |
| 1784 | 1802 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1830 __ Push(reg); | 1848 __ Push(reg); |
| 1831 } | 1849 } |
| 1832 | 1850 |
| 1833 | 1851 |
| 1834 void ParallelMoveResolver::RestoreScratch(Register reg) { | 1852 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| 1835 __ Pop(reg); | 1853 __ Pop(reg); |
| 1836 } | 1854 } |
| 1837 | 1855 |
| 1838 | 1856 |
| 1839 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { | 1857 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { |
| 1840 __ vstrd(reg, Address(SP, -kDoubleSize, Address::PreIndex)); | 1858 DRegister dreg = static_cast<DRegister>(reg * 2); |
| 1859 __ vstrd(dreg, Address(SP, -kDoubleSize, Address::PreIndex)); | |
| 1841 } | 1860 } |
| 1842 | 1861 |
| 1843 | 1862 |
| 1844 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | 1863 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
| 1845 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); | 1864 DRegister dreg = static_cast<DRegister>(reg * 2); |
| 1865 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); | |
| 1846 } | 1866 } |
| 1847 | 1867 |
| 1848 | 1868 |
| 1849 #undef __ | 1869 #undef __ |
| 1850 | 1870 |
| 1851 } // namespace dart | 1871 } // namespace dart |
| 1852 | 1872 |
| 1853 #endif // defined TARGET_ARCH_ARM | 1873 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |