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

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

Issue 13801014: Fix bug in ParallelMoveResolver::EmitSwap: implement swaps of FPU spill slots. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 7 years, 8 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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 1578 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 } 1589 }
1590 } else if (source.IsFpuRegister()) { 1590 } else if (source.IsFpuRegister()) {
1591 if (destination.IsFpuRegister()) { 1591 if (destination.IsFpuRegister()) {
1592 // Optimization manual recommends using MOVAPS for register 1592 // Optimization manual recommends using MOVAPS for register
1593 // to register moves. 1593 // to register moves.
1594 __ movaps(destination.fpu_reg(), source.fpu_reg()); 1594 __ movaps(destination.fpu_reg(), source.fpu_reg());
1595 } else { 1595 } else {
1596 if (destination.IsDoubleStackSlot()) { 1596 if (destination.IsDoubleStackSlot()) {
1597 __ movsd(destination.ToStackSlotAddress(), source.fpu_reg()); 1597 __ movsd(destination.ToStackSlotAddress(), source.fpu_reg());
1598 } else { 1598 } else {
1599 ASSERT(destination.IsFloat32x4StackSlot() || 1599 ASSERT(destination.IsQuadStackSlot());
1600 destination.IsUint32x4StackSlot());
1601 __ movups(destination.ToStackSlotAddress(), source.fpu_reg()); 1600 __ movups(destination.ToStackSlotAddress(), source.fpu_reg());
1602 } 1601 }
1603 } 1602 }
1604 } else if (source.IsDoubleStackSlot()) { 1603 } else if (source.IsDoubleStackSlot()) {
1605 if (destination.IsFpuRegister()) { 1604 if (destination.IsFpuRegister()) {
1606 __ movsd(destination.fpu_reg(), source.ToStackSlotAddress()); 1605 __ movsd(destination.fpu_reg(), source.ToStackSlotAddress());
1607 } else { 1606 } else {
1608 ASSERT(destination.IsDoubleStackSlot()); 1607 ASSERT(destination.IsDoubleStackSlot());
1609 __ movsd(XMM0, source.ToStackSlotAddress()); 1608 __ movsd(XMM0, source.ToStackSlotAddress());
1610 __ movsd(destination.ToStackSlotAddress(), XMM0); 1609 __ movsd(destination.ToStackSlotAddress(), XMM0);
1611 } 1610 }
1612 } else if (source.IsFloat32x4StackSlot() || source.IsUint32x4StackSlot()) { 1611 } else if (source.IsQuadStackSlot()) {
1613 if (destination.IsFpuRegister()) { 1612 if (destination.IsFpuRegister()) {
1614 __ movups(destination.fpu_reg(), source.ToStackSlotAddress()); 1613 __ movups(destination.fpu_reg(), source.ToStackSlotAddress());
1615 } else { 1614 } else {
1616 ASSERT(destination.IsFloat32x4StackSlot() || 1615 ASSERT(destination.IsQuadStackSlot());
1617 destination.IsUint32x4StackSlot());
1618 __ movups(XMM0, source.ToStackSlotAddress()); 1616 __ movups(XMM0, source.ToStackSlotAddress());
1619 __ movups(destination.ToStackSlotAddress(), XMM0); 1617 __ movups(destination.ToStackSlotAddress(), XMM0);
1620 } 1618 }
1621 } else { 1619 } else {
1622 ASSERT(source.IsConstant()); 1620 ASSERT(source.IsConstant());
1623 if (destination.IsRegister()) { 1621 if (destination.IsRegister()) {
1624 const Object& constant = source.constant(); 1622 const Object& constant = source.constant();
1625 if (constant.IsSmi() && (Smi::Cast(constant).Value() == 0)) { 1623 if (constant.IsSmi() && (Smi::Cast(constant).Value() == 0)) {
1626 __ xorl(destination.reg(), destination.reg()); 1624 __ xorl(destination.reg(), destination.reg());
1627 } else { 1625 } else {
(...skipping 21 matching lines...) Expand all
1649 } else if (source.IsStackSlot() && destination.IsRegister()) { 1647 } else if (source.IsStackSlot() && destination.IsRegister()) {
1650 Exchange(destination.reg(), source.ToStackSlotAddress()); 1648 Exchange(destination.reg(), source.ToStackSlotAddress());
1651 } else if (source.IsStackSlot() && destination.IsStackSlot()) { 1649 } else if (source.IsStackSlot() && destination.IsStackSlot()) {
1652 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); 1650 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress());
1653 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { 1651 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
1654 __ movaps(XMM0, source.fpu_reg()); 1652 __ movaps(XMM0, source.fpu_reg());
1655 __ movaps(source.fpu_reg(), destination.fpu_reg()); 1653 __ movaps(source.fpu_reg(), destination.fpu_reg());
1656 __ movaps(destination.fpu_reg(), XMM0); 1654 __ movaps(destination.fpu_reg(), XMM0);
1657 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { 1655 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) {
1658 ASSERT(destination.IsDoubleStackSlot() || 1656 ASSERT(destination.IsDoubleStackSlot() ||
1659 destination.IsFloat32x4StackSlot() || 1657 destination.IsQuadStackSlot() ||
1660 destination.IsUint32x4StackSlot() ||
1661 source.IsDoubleStackSlot() || 1658 source.IsDoubleStackSlot() ||
1662 source.IsFloat32x4StackSlot() || 1659 source.IsQuadStackSlot());
1663 source.IsUint32x4StackSlot());
1664 bool double_width = destination.IsDoubleStackSlot() || 1660 bool double_width = destination.IsDoubleStackSlot() ||
1665 source.IsDoubleStackSlot(); 1661 source.IsDoubleStackSlot();
1666 XmmRegister reg = source.IsFpuRegister() ? source.fpu_reg() 1662 XmmRegister reg = source.IsFpuRegister() ? source.fpu_reg()
1667 : destination.fpu_reg(); 1663 : destination.fpu_reg();
1668 const Address& slot_address = source.IsFpuRegister() 1664 const Address& slot_address = source.IsFpuRegister()
1669 ? destination.ToStackSlotAddress() 1665 ? destination.ToStackSlotAddress()
1670 : source.ToStackSlotAddress(); 1666 : source.ToStackSlotAddress();
1671 1667
1672 if (double_width) { 1668 if (double_width) {
1673 __ movsd(XMM0, slot_address); 1669 __ movsd(XMM0, slot_address);
1674 __ movsd(slot_address, reg); 1670 __ movsd(slot_address, reg);
1675 } else { 1671 } else {
1676 __ movups(XMM0, slot_address); 1672 __ movups(XMM0, slot_address);
1677 __ movups(slot_address, reg); 1673 __ movups(slot_address, reg);
1678 } 1674 }
1679 __ movaps(reg, XMM0); 1675 __ movaps(reg, XMM0);
1676 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
1677 const Address& source_slot_address = source.ToStackSlotAddress();
1678 const Address& destination_slot_address = destination.ToStackSlotAddress();
1679
1680 ScratchFpuRegisterScope ensure_scratch(this, XMM0);
1681 __ movsd(XMM0, source_slot_address);
1682 __ movsd(ensure_scratch.reg(), destination_slot_address);
1683 __ movsd(destination_slot_address, XMM0);
1684 __ movsd(source_slot_address, ensure_scratch.reg());
1685 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) {
1686 const Address& source_slot_address = source.ToStackSlotAddress();
1687 const Address& destination_slot_address = destination.ToStackSlotAddress();
1688
1689 ScratchFpuRegisterScope ensure_scratch(this, XMM0);
1690 __ movups(XMM0, source_slot_address);
1691 __ movups(ensure_scratch.reg(), destination_slot_address);
1692 __ movups(destination_slot_address, XMM0);
1693 __ movups(source_slot_address, ensure_scratch.reg());
1680 } else { 1694 } else {
1681 UNREACHABLE(); 1695 UNREACHABLE();
1682 } 1696 }
1683 1697
1684 // The swap of source and destination has executed a move from source to 1698 // The swap of source and destination has executed a move from source to
1685 // destination. 1699 // destination.
1686 move->Eliminate(); 1700 move->Eliminate();
1687 1701
1688 // Any unperformed (including pending) move with a source of either 1702 // Any unperformed (including pending) move with a source of either
1689 // this move's source or destination needs to have their source 1703 // this move's source or destination needs to have their source
1690 // changed to reflect the state of affairs after the swap. 1704 // changed to reflect the state of affairs after the swap.
1691 for (int i = 0; i < moves_.length(); ++i) { 1705 for (int i = 0; i < moves_.length(); ++i) {
1692 const MoveOperands& other_move = *moves_[i]; 1706 const MoveOperands& other_move = *moves_[i];
1693 if (other_move.Blocks(source)) { 1707 if (other_move.Blocks(source)) {
1694 moves_[i]->set_src(destination); 1708 moves_[i]->set_src(destination);
1695 } else if (other_move.Blocks(destination)) { 1709 } else if (other_move.Blocks(destination)) {
1696 moves_[i]->set_src(source); 1710 moves_[i]->set_src(source);
1697 } 1711 }
1698 } 1712 }
1699 } 1713 }
1700 1714
1701 1715
1702 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, 1716 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst,
1703 const Address& src) { 1717 const Address& src) {
1704 // TODO(vegorov): allocate temporary register for such moves. 1718 ScratchRegisterScope ensure_scratch(this, kNoRegister);
1705 __ pushl(EAX); 1719 __ movl(ensure_scratch.reg(), src);
1706 __ movl(EAX, src); 1720 __ movl(dst, ensure_scratch.reg());
1707 __ movl(dst, EAX);
1708 __ popl(EAX);
1709 } 1721 }
1710 1722
1711 1723
1712 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { 1724 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) {
1713 // TODO(vegorov): allocate temporary register for such moves.
1714 if (obj.IsSmi() || obj.IsNull()) { 1725 if (obj.IsSmi() || obj.IsNull()) {
1715 __ movl(dst, Immediate(reinterpret_cast<int32_t>(obj.raw()))); 1726 __ movl(dst, Immediate(reinterpret_cast<int32_t>(obj.raw())));
1716 } else { 1727 } else {
1717 __ pushl(EAX); 1728 ScratchRegisterScope ensure_scratch(this, kNoRegister);
1718 __ LoadObject(EAX, obj); 1729 __ LoadObject(ensure_scratch.reg(), obj);
1719 __ movl(dst, EAX); 1730 __ movl(dst, ensure_scratch.reg());
1720 __ popl(EAX);
1721 } 1731 }
1722 } 1732 }
1723 1733
1724 1734
1725 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { 1735 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) {
1726 // TODO(vegorov): allocate temporary register for such moves. 1736 ScratchRegisterScope ensure_scratch(this, reg);
1727 Register scratch = (reg == EAX) ? ECX : EAX; 1737 __ movl(ensure_scratch.reg(), mem);
1728 __ pushl(scratch); 1738 __ movl(mem, reg);
1729 __ movl(scratch, mem); 1739 __ movl(reg, ensure_scratch.reg());
1730 __ xchgl(scratch, reg);
1731 __ movl(mem, scratch);
1732 __ popl(scratch);
1733 } 1740 }
1734 1741
1735 1742
1736 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1743 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1737 // TODO(vegorov): allocate temporary registers for such moves. 1744 ScratchRegisterScope ensure_scratch1(this, kNoRegister);
1738 __ pushl(EAX); 1745 ScratchRegisterScope ensure_scratch2(this, ensure_scratch1.reg());
1739 __ pushl(ECX); 1746 __ movl(ensure_scratch1.reg(), mem1);
1740 __ movl(EAX, mem1); 1747 __ movl(ensure_scratch2.reg(), mem2);
1741 __ movl(ECX, mem2); 1748 __ movl(mem2, ensure_scratch1.reg());
1742 __ movl(mem1, ECX); 1749 __ movl(mem1, ensure_scratch2.reg());
1743 __ movl(mem2, EAX);
1744 __ popl(ECX);
1745 __ popl(EAX);
1746 } 1750 }
1747 1751
1748 1752
1753 void ParallelMoveResolver::SpillScratch(Register reg) {
1754 __ pushl(reg);
1755 }
1756
1757
1758 void ParallelMoveResolver::RestoreScratch(Register reg) {
1759 __ popl(reg);
1760 }
1761
1762
1763 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
1764 __ subl(ESP, Immediate(kFpuRegisterSize));
1765 __ movups(Address(ESP, 0), reg);
1766 }
1767
1768
1769 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
1770 __ movups(reg, Address(ESP, 0));
1771 __ addl(ESP, Immediate(kFpuRegisterSize));
1772 }
1773
1774
1749 #undef __ 1775 #undef __
1750 1776
1751 } // namespace dart 1777 } // namespace dart
1752 1778
1753 #endif // defined TARGET_ARCH_IA32 1779 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698