Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: runtime/vm/flow_graph_compiler_mips.cc

Issue 539073002: Fixes for ARM/ARM64/MIPS parallel move resolver. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698