| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
| (...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1566 const Location source = move->src(); | 1566 const Location source = move->src(); |
| 1567 const Location destination = move->dest(); | 1567 const Location destination = move->dest(); |
| 1568 __ TraceSimMsg("ParallelMoveResolver::EmitMove"); | 1568 __ TraceSimMsg("ParallelMoveResolver::EmitMove"); |
| 1569 | 1569 |
| 1570 if (source.IsRegister()) { | 1570 if (source.IsRegister()) { |
| 1571 if (destination.IsRegister()) { | 1571 if (destination.IsRegister()) { |
| 1572 __ mov(destination.reg(), source.reg()); | 1572 __ mov(destination.reg(), source.reg()); |
| 1573 } else { | 1573 } else { |
| 1574 ASSERT(destination.IsStackSlot()); | 1574 ASSERT(destination.IsStackSlot()); |
| 1575 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1575 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1576 __ StoreToOffset(source.reg(), FP, dest_offset); | 1576 __ StoreToOffset(source.reg(), destination.base_reg(), dest_offset); |
| 1577 } | 1577 } |
| 1578 } else if (source.IsStackSlot()) { | 1578 } else if (source.IsStackSlot()) { |
| 1579 if (destination.IsRegister()) { | 1579 if (destination.IsRegister()) { |
| 1580 const intptr_t source_offset = source.ToStackSlotOffset(); | 1580 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1581 __ LoadFromOffset(destination.reg(), FP, source_offset); | 1581 __ LoadFromOffset(destination.reg(), source.base_reg(), source_offset); |
| 1582 } else { | 1582 } else { |
| 1583 ASSERT(destination.IsStackSlot()); | 1583 ASSERT(destination.IsStackSlot()); |
| 1584 const intptr_t source_offset = source.ToStackSlotOffset(); | 1584 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1585 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1585 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1586 __ LoadFromOffset(TMP, FP, source_offset); | 1586 ScratchRegisterScope tmp(this, kNoRegister); |
| 1587 __ StoreToOffset(TMP, FP, dest_offset); | 1587 __ LoadFromOffset(tmp.reg(), source.base_reg(), source_offset); |
| 1588 __ StoreToOffset(tmp.reg(), destination.base_reg(), dest_offset); |
| 1588 } | 1589 } |
| 1589 } else if (source.IsFpuRegister()) { | 1590 } else if (source.IsFpuRegister()) { |
| 1590 if (destination.IsFpuRegister()) { | 1591 if (destination.IsFpuRegister()) { |
| 1591 DRegister dst = destination.fpu_reg(); | 1592 DRegister dst = destination.fpu_reg(); |
| 1592 DRegister src = source.fpu_reg(); | 1593 DRegister src = source.fpu_reg(); |
| 1593 __ movd(dst, src); | 1594 __ movd(dst, src); |
| 1594 } else { | 1595 } else { |
| 1595 if (destination.IsDoubleStackSlot()) { | 1596 ASSERT(destination.IsDoubleStackSlot()); |
| 1596 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1597 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1597 DRegister src = source.fpu_reg(); | 1598 DRegister src = source.fpu_reg(); |
| 1598 __ StoreDToOffset(src, FP, dest_offset); | 1599 __ StoreDToOffset(src, destination.base_reg(), dest_offset); |
| 1599 } else { | |
| 1600 ASSERT(destination.IsQuadStackSlot()); | |
| 1601 UNIMPLEMENTED(); | |
| 1602 } | |
| 1603 } | 1600 } |
| 1604 } else if (source.IsDoubleStackSlot()) { | 1601 } else if (source.IsDoubleStackSlot()) { |
| 1605 if (destination.IsFpuRegister()) { | 1602 if (destination.IsFpuRegister()) { |
| 1606 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1603 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1607 DRegister dst = destination.fpu_reg(); | 1604 DRegister dst = destination.fpu_reg(); |
| 1608 __ LoadDFromOffset(dst, FP, dest_offset); | 1605 __ LoadDFromOffset(dst, source.base_reg(), source_offset); |
| 1609 } else { | 1606 } else { |
| 1610 ASSERT(destination.IsDoubleStackSlot()); | 1607 ASSERT(destination.IsDoubleStackSlot()); |
| 1611 const intptr_t source_offset = source.ToStackSlotOffset(); | 1608 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1612 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1609 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1613 __ LoadDFromOffset(DTMP, FP, source_offset); | 1610 __ LoadDFromOffset(DTMP, source.base_reg(), source_offset); |
| 1614 __ StoreDToOffset(DTMP, FP, dest_offset); | 1611 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1615 } | 1612 } |
| 1616 } else if (source.IsQuadStackSlot()) { | |
| 1617 UNIMPLEMENTED(); | |
| 1618 } else { | 1613 } else { |
| 1619 ASSERT(source.IsConstant()); | 1614 ASSERT(source.IsConstant()); |
| 1620 const Object& constant = source.constant(); | 1615 const Object& constant = source.constant(); |
| 1621 if (destination.IsRegister()) { | 1616 if (destination.IsRegister()) { |
| 1622 __ LoadObject(destination.reg(), constant); | 1617 __ LoadObject(destination.reg(), constant); |
| 1623 } else if (destination.IsFpuRegister()) { | 1618 } else if (destination.IsFpuRegister()) { |
| 1624 __ LoadObject(TMP, constant); | 1619 __ LoadObject(TMP, constant); |
| 1625 __ LoadDFromOffset(destination.fpu_reg(), TMP, | 1620 __ LoadDFromOffset(destination.fpu_reg(), TMP, |
| 1626 Double::value_offset() - kHeapObjectTag); | 1621 Double::value_offset() - kHeapObjectTag); |
| 1627 } else if (destination.IsDoubleStackSlot()) { | 1622 } else if (destination.IsDoubleStackSlot()) { |
| 1628 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1623 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1629 __ LoadObject(TMP, constant); | 1624 __ LoadObject(TMP, constant); |
| 1630 __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag); | 1625 __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag); |
| 1631 __ StoreDToOffset(DTMP, FP, dest_offset); | 1626 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1632 } else { | 1627 } else { |
| 1633 ASSERT(destination.IsStackSlot()); | 1628 ASSERT(destination.IsStackSlot()); |
| 1634 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1629 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1635 __ LoadObject(TMP, constant); | 1630 ScratchRegisterScope tmp(this, kNoRegister); |
| 1636 __ StoreToOffset(TMP, FP, dest_offset); | 1631 __ LoadObject(tmp.reg(), constant); |
| 1632 __ StoreToOffset(tmp.reg(), destination.base_reg(), dest_offset); |
| 1637 } | 1633 } |
| 1638 } | 1634 } |
| 1639 | 1635 |
| 1640 move->Eliminate(); | 1636 move->Eliminate(); |
| 1641 } | 1637 } |
| 1642 | 1638 |
| 1643 | 1639 |
| 1644 void ParallelMoveResolver::EmitSwap(int index) { | 1640 void ParallelMoveResolver::EmitSwap(int index) { |
| 1645 MoveOperands* move = moves_[index]; | 1641 MoveOperands* move = moves_[index]; |
| 1646 const Location source = move->src(); | 1642 const Location source = move->src(); |
| 1647 const Location destination = move->dest(); | 1643 const Location destination = move->dest(); |
| 1648 | 1644 |
| 1649 if (source.IsRegister() && destination.IsRegister()) { | 1645 if (source.IsRegister() && destination.IsRegister()) { |
| 1650 ASSERT(source.reg() != TMP); | 1646 ASSERT(source.reg() != TMP); |
| 1651 ASSERT(destination.reg() != TMP); | 1647 ASSERT(destination.reg() != TMP); |
| 1652 __ mov(TMP, source.reg()); | 1648 __ mov(TMP, source.reg()); |
| 1653 __ mov(source.reg(), destination.reg()); | 1649 __ mov(source.reg(), destination.reg()); |
| 1654 __ mov(destination.reg(), TMP); | 1650 __ mov(destination.reg(), TMP); |
| 1655 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1651 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1656 Exchange(source.reg(), destination.ToStackSlotOffset()); | 1652 Exchange(source.reg(), |
| 1653 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1657 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1654 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1658 Exchange(destination.reg(), source.ToStackSlotOffset()); | 1655 Exchange(destination.reg(), |
| 1656 source.base_reg(), source.ToStackSlotOffset()); |
| 1659 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1657 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1660 Exchange(source.ToStackSlotOffset(), destination.ToStackSlotOffset()); | 1658 Exchange(source.base_reg(), source.ToStackSlotOffset(), |
| 1659 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1661 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1660 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1662 DRegister dst = destination.fpu_reg(); | 1661 DRegister dst = destination.fpu_reg(); |
| 1663 DRegister src = source.fpu_reg(); | 1662 DRegister src = source.fpu_reg(); |
| 1664 __ movd(DTMP, src); | 1663 __ movd(DTMP, src); |
| 1665 __ movd(src, dst); | 1664 __ movd(src, dst); |
| 1666 __ movd(dst, DTMP); | 1665 __ movd(dst, DTMP); |
| 1667 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1666 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1668 ASSERT(destination.IsDoubleStackSlot() || | 1667 ASSERT(destination.IsDoubleStackSlot() || source.IsDoubleStackSlot()); |
| 1669 destination.IsQuadStackSlot() || | |
| 1670 source.IsDoubleStackSlot() || | |
| 1671 source.IsQuadStackSlot()); | |
| 1672 bool double_width = destination.IsDoubleStackSlot() || | |
| 1673 source.IsDoubleStackSlot(); | |
| 1674 DRegister reg = source.IsFpuRegister() ? source.fpu_reg() | 1668 DRegister reg = source.IsFpuRegister() ? source.fpu_reg() |
| 1675 : destination.fpu_reg(); | 1669 : destination.fpu_reg(); |
| 1670 Register base_reg = source.IsFpuRegister() |
| 1671 ? destination.base_reg() |
| 1672 : source.base_reg(); |
| 1676 const intptr_t slot_offset = source.IsFpuRegister() | 1673 const intptr_t slot_offset = source.IsFpuRegister() |
| 1677 ? destination.ToStackSlotOffset() | 1674 ? destination.ToStackSlotOffset() |
| 1678 : source.ToStackSlotOffset(); | 1675 : source.ToStackSlotOffset(); |
| 1679 | 1676 __ LoadDFromOffset(DTMP, base_reg, slot_offset); |
| 1680 if (double_width) { | 1677 __ StoreDToOffset(reg, base_reg, slot_offset); |
| 1681 __ LoadDFromOffset(DTMP, FP, slot_offset); | 1678 __ movd(reg, DTMP); |
| 1682 __ StoreDToOffset(reg, FP, slot_offset); | |
| 1683 __ movd(reg, DTMP); | |
| 1684 } else { | |
| 1685 UNIMPLEMENTED(); | |
| 1686 } | |
| 1687 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { | 1679 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { |
| 1688 const intptr_t source_offset = source.ToStackSlotOffset(); | 1680 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1689 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1681 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1690 | 1682 |
| 1691 ScratchFpuRegisterScope ensure_scratch(this, DTMP); | 1683 ScratchFpuRegisterScope ensure_scratch(this, DTMP); |
| 1692 DRegister scratch = ensure_scratch.reg(); | 1684 DRegister scratch = ensure_scratch.reg(); |
| 1693 __ LoadDFromOffset(DTMP, FP, source_offset); | 1685 __ LoadDFromOffset(DTMP, source.base_reg(), source_offset); |
| 1694 __ LoadDFromOffset(scratch, FP, dest_offset); | 1686 __ LoadDFromOffset(scratch, destination.base_reg(), dest_offset); |
| 1695 __ StoreDToOffset(DTMP, FP, dest_offset); | 1687 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1696 __ StoreDToOffset(scratch, FP, source_offset); | 1688 __ StoreDToOffset(scratch, source.base_reg(), source_offset); |
| 1697 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { | |
| 1698 UNIMPLEMENTED(); | |
| 1699 } else { | 1689 } else { |
| 1700 UNREACHABLE(); | 1690 UNREACHABLE(); |
| 1701 } | 1691 } |
| 1702 | 1692 |
| 1703 // The swap of source and destination has executed a move from source to | 1693 // The swap of source and destination has executed a move from source to |
| 1704 // destination. | 1694 // destination. |
| 1705 move->Eliminate(); | 1695 move->Eliminate(); |
| 1706 | 1696 |
| 1707 // Any unperformed (including pending) move with a source of either | 1697 // Any unperformed (including pending) move with a source of either |
| 1708 // this move's source or destination needs to have their source | 1698 // this move's source or destination needs to have their source |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1740 } | 1730 } |
| 1741 | 1731 |
| 1742 | 1732 |
| 1743 // Do not call or implement this function. Instead, use the form below that | 1733 // Do not call or implement this function. Instead, use the form below that |
| 1744 // uses offsets from the frame pointer instead of Addresses. | 1734 // uses offsets from the frame pointer instead of Addresses. |
| 1745 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1735 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1746 UNREACHABLE(); | 1736 UNREACHABLE(); |
| 1747 } | 1737 } |
| 1748 | 1738 |
| 1749 | 1739 |
| 1750 void ParallelMoveResolver::Exchange(Register reg, intptr_t stack_offset) { | 1740 void ParallelMoveResolver::Exchange(Register reg, |
| 1751 __ mov(TMP, reg); | 1741 Register base_reg, |
| 1752 __ LoadFromOffset(reg, FP, stack_offset); | 1742 intptr_t stack_offset) { |
| 1753 __ StoreToOffset(TMP, FP, stack_offset); | 1743 ScratchRegisterScope tmp(this, reg); |
| 1744 __ mov(tmp.reg(), reg); |
| 1745 __ LoadFromOffset(reg, base_reg, stack_offset); |
| 1746 __ StoreToOffset(tmp.reg(), base_reg, stack_offset); |
| 1754 } | 1747 } |
| 1755 | 1748 |
| 1756 | 1749 |
| 1757 void ParallelMoveResolver::Exchange(intptr_t stack_offset1, | 1750 void ParallelMoveResolver::Exchange(Register base_reg1, |
| 1751 intptr_t stack_offset1, |
| 1752 Register base_reg2, |
| 1758 intptr_t stack_offset2) { | 1753 intptr_t stack_offset2) { |
| 1759 ScratchRegisterScope ensure_scratch(this, TMP); | 1754 ScratchRegisterScope tmp1(this, kNoRegister); |
| 1760 __ LoadFromOffset(ensure_scratch.reg(), FP, stack_offset1); | 1755 ScratchRegisterScope tmp2(this, tmp1.reg()); |
| 1761 __ LoadFromOffset(TMP, FP, stack_offset2); | 1756 __ LoadFromOffset(tmp1.reg(), base_reg1, stack_offset1); |
| 1762 __ StoreToOffset(ensure_scratch.reg(), FP, stack_offset2); | 1757 __ LoadFromOffset(tmp2.reg(), base_reg2, stack_offset2); |
| 1763 __ StoreToOffset(TMP, FP, stack_offset1); | 1758 __ StoreToOffset(tmp1.reg(), base_reg1, stack_offset2); |
| 1759 __ StoreToOffset(tmp2.reg(), base_reg2, stack_offset1); |
| 1764 } | 1760 } |
| 1765 | 1761 |
| 1766 | 1762 |
| 1767 void ParallelMoveResolver::SpillScratch(Register reg) { | 1763 void ParallelMoveResolver::SpillScratch(Register reg) { |
| 1768 __ TraceSimMsg("ParallelMoveResolver::SpillScratch"); | 1764 __ TraceSimMsg("ParallelMoveResolver::SpillScratch"); |
| 1769 __ Push(reg); | 1765 __ Push(reg); |
| 1770 } | 1766 } |
| 1771 | 1767 |
| 1772 | 1768 |
| 1773 void ParallelMoveResolver::RestoreScratch(Register reg) { | 1769 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1789 __ AddImmediate(SP, kDoubleSize); | 1785 __ AddImmediate(SP, kDoubleSize); |
| 1790 } | 1786 } |
| 1791 | 1787 |
| 1792 | 1788 |
| 1793 #undef __ | 1789 #undef __ |
| 1794 | 1790 |
| 1795 | 1791 |
| 1796 } // namespace dart | 1792 } // namespace dart |
| 1797 | 1793 |
| 1798 #endif // defined TARGET_ARCH_MIPS | 1794 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |