| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 __ LoadObject(RAX, loc.constant()); | 760 __ LoadObject(RAX, loc.constant()); |
| 761 __ movq(dest, RAX); | 761 __ movq(dest, RAX); |
| 762 } else if (loc.IsRegister()) { | 762 } else if (loc.IsRegister()) { |
| 763 if (*push_emitted && loc.reg() == RAX) { | 763 if (*push_emitted && loc.reg() == RAX) { |
| 764 __ movq(RAX, Address(RSP, 0)); | 764 __ movq(RAX, Address(RSP, 0)); |
| 765 __ movq(dest, RAX); | 765 __ movq(dest, RAX); |
| 766 } else { | 766 } else { |
| 767 __ movq(dest, loc.reg()); | 767 __ movq(dest, loc.reg()); |
| 768 } | 768 } |
| 769 } else { | 769 } else { |
| 770 Address src = loc.ToStackSlotAddress(); | 770 const Address& src = Address::StackSlotAddress(loc); |
| 771 if (!src.Equals(dest)) { | 771 if (!src.Equals(dest)) { |
| 772 if (!*push_emitted) { | 772 if (!*push_emitted) { |
| 773 __ pushq(RAX); | 773 __ pushq(RAX); |
| 774 *push_emitted = true; | 774 *push_emitted = true; |
| 775 } | 775 } |
| 776 __ movq(RAX, src); | 776 __ movq(RAX, src); |
| 777 __ movq(dest, RAX); | 777 __ movq(dest, RAX); |
| 778 } | 778 } |
| 779 } | 779 } |
| 780 } | 780 } |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1716 void ParallelMoveResolver::EmitMove(int index) { | 1716 void ParallelMoveResolver::EmitMove(int index) { |
| 1717 MoveOperands* move = moves_[index]; | 1717 MoveOperands* move = moves_[index]; |
| 1718 const Location source = move->src(); | 1718 const Location source = move->src(); |
| 1719 const Location destination = move->dest(); | 1719 const Location destination = move->dest(); |
| 1720 | 1720 |
| 1721 if (source.IsRegister()) { | 1721 if (source.IsRegister()) { |
| 1722 if (destination.IsRegister()) { | 1722 if (destination.IsRegister()) { |
| 1723 __ movq(destination.reg(), source.reg()); | 1723 __ movq(destination.reg(), source.reg()); |
| 1724 } else { | 1724 } else { |
| 1725 ASSERT(destination.IsStackSlot()); | 1725 ASSERT(destination.IsStackSlot()); |
| 1726 __ movq(destination.ToStackSlotAddress(), source.reg()); | 1726 __ movq(Address::StackSlotAddress(destination), source.reg()); |
| 1727 } | 1727 } |
| 1728 } else if (source.IsStackSlot()) { | 1728 } else if (source.IsStackSlot()) { |
| 1729 if (destination.IsRegister()) { | 1729 if (destination.IsRegister()) { |
| 1730 __ movq(destination.reg(), source.ToStackSlotAddress()); | 1730 __ movq(destination.reg(), Address::StackSlotAddress(source)); |
| 1731 } else { | 1731 } else { |
| 1732 ASSERT(destination.IsStackSlot()); | 1732 ASSERT(destination.IsStackSlot()); |
| 1733 MoveMemoryToMemory(destination.ToStackSlotAddress(), | 1733 MoveMemoryToMemory(Address::StackSlotAddress(destination), |
| 1734 source.ToStackSlotAddress()); | 1734 Address::StackSlotAddress(source)); |
| 1735 } | 1735 } |
| 1736 } else if (source.IsFpuRegister()) { | 1736 } else if (source.IsFpuRegister()) { |
| 1737 if (destination.IsFpuRegister()) { | 1737 if (destination.IsFpuRegister()) { |
| 1738 // Optimization manual recommends using MOVAPS for register | 1738 // Optimization manual recommends using MOVAPS for register |
| 1739 // to register moves. | 1739 // to register moves. |
| 1740 __ movaps(destination.fpu_reg(), source.fpu_reg()); | 1740 __ movaps(destination.fpu_reg(), source.fpu_reg()); |
| 1741 } else { | 1741 } else { |
| 1742 if (destination.IsDoubleStackSlot()) { | 1742 if (destination.IsDoubleStackSlot()) { |
| 1743 __ movsd(destination.ToStackSlotAddress(), source.fpu_reg()); | 1743 __ movsd(Address::StackSlotAddress(destination), source.fpu_reg()); |
| 1744 } else { | 1744 } else { |
| 1745 ASSERT(destination.IsQuadStackSlot()); | 1745 ASSERT(destination.IsQuadStackSlot()); |
| 1746 __ movups(destination.ToStackSlotAddress(), source.fpu_reg()); | 1746 __ movups(Address::StackSlotAddress(destination), source.fpu_reg()); |
| 1747 } | 1747 } |
| 1748 } | 1748 } |
| 1749 } else if (source.IsDoubleStackSlot()) { | 1749 } else if (source.IsDoubleStackSlot()) { |
| 1750 if (destination.IsFpuRegister()) { | 1750 if (destination.IsFpuRegister()) { |
| 1751 __ movsd(destination.fpu_reg(), source.ToStackSlotAddress()); | 1751 __ movsd(destination.fpu_reg(), Address::StackSlotAddress(source)); |
| 1752 } else { | 1752 } else { |
| 1753 ASSERT(destination.IsDoubleStackSlot()); | 1753 ASSERT(destination.IsDoubleStackSlot()); |
| 1754 __ movsd(XMM0, source.ToStackSlotAddress()); | 1754 __ movsd(XMM0, Address::StackSlotAddress(source)); |
| 1755 __ movsd(destination.ToStackSlotAddress(), XMM0); | 1755 __ movsd(Address::StackSlotAddress(destination), XMM0); |
| 1756 } | 1756 } |
| 1757 } else if (source.IsQuadStackSlot()) { | 1757 } else if (source.IsQuadStackSlot()) { |
| 1758 if (destination.IsFpuRegister()) { | 1758 if (destination.IsFpuRegister()) { |
| 1759 __ movups(destination.fpu_reg(), source.ToStackSlotAddress()); | 1759 __ movups(destination.fpu_reg(), Address::StackSlotAddress(source)); |
| 1760 } else { | 1760 } else { |
| 1761 ASSERT(destination.IsQuadStackSlot()); | 1761 ASSERT(destination.IsQuadStackSlot()); |
| 1762 __ movups(XMM0, source.ToStackSlotAddress()); | 1762 __ movups(XMM0, Address::StackSlotAddress(source)); |
| 1763 __ movups(destination.ToStackSlotAddress(), XMM0); | 1763 __ movups(Address::StackSlotAddress(destination), XMM0); |
| 1764 } | 1764 } |
| 1765 } else { | 1765 } else { |
| 1766 ASSERT(source.IsConstant()); | 1766 ASSERT(source.IsConstant()); |
| 1767 if (destination.IsRegister()) { | 1767 if (destination.IsRegister()) { |
| 1768 const Object& constant = source.constant(); | 1768 const Object& constant = source.constant(); |
| 1769 if (constant.IsSmi() && (Smi::Cast(constant).Value() == 0)) { | 1769 if (constant.IsSmi() && (Smi::Cast(constant).Value() == 0)) { |
| 1770 __ xorq(destination.reg(), destination.reg()); | 1770 __ xorq(destination.reg(), destination.reg()); |
| 1771 } else { | 1771 } else { |
| 1772 __ LoadObject(destination.reg(), constant); | 1772 __ LoadObject(destination.reg(), constant); |
| 1773 } | 1773 } |
| 1774 } else { | 1774 } else { |
| 1775 ASSERT(destination.IsStackSlot()); | 1775 ASSERT(destination.IsStackSlot()); |
| 1776 StoreObject(destination.ToStackSlotAddress(), source.constant()); | 1776 StoreObject(Address::StackSlotAddress(destination), source.constant()); |
| 1777 } | 1777 } |
| 1778 } | 1778 } |
| 1779 | 1779 |
| 1780 move->Eliminate(); | 1780 move->Eliminate(); |
| 1781 } | 1781 } |
| 1782 | 1782 |
| 1783 | 1783 |
| 1784 void ParallelMoveResolver::EmitSwap(int index) { | 1784 void ParallelMoveResolver::EmitSwap(int index) { |
| 1785 MoveOperands* move = moves_[index]; | 1785 MoveOperands* move = moves_[index]; |
| 1786 const Location source = move->src(); | 1786 const Location source = move->src(); |
| 1787 const Location destination = move->dest(); | 1787 const Location destination = move->dest(); |
| 1788 | 1788 |
| 1789 if (source.IsRegister() && destination.IsRegister()) { | 1789 if (source.IsRegister() && destination.IsRegister()) { |
| 1790 __ xchgq(destination.reg(), source.reg()); | 1790 __ xchgq(destination.reg(), source.reg()); |
| 1791 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1791 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1792 Exchange(source.reg(), destination.ToStackSlotAddress()); | 1792 Exchange(source.reg(), Address::StackSlotAddress(destination)); |
| 1793 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1793 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1794 Exchange(destination.reg(), source.ToStackSlotAddress()); | 1794 Exchange(destination.reg(), Address::StackSlotAddress(source)); |
| 1795 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1795 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1796 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); | 1796 Exchange(Address::StackSlotAddress(destination), |
| 1797 Address::StackSlotAddress(source)); |
| 1797 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1798 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1798 __ movaps(XMM0, source.fpu_reg()); | 1799 __ movaps(XMM0, source.fpu_reg()); |
| 1799 __ movaps(source.fpu_reg(), destination.fpu_reg()); | 1800 __ movaps(source.fpu_reg(), destination.fpu_reg()); |
| 1800 __ movaps(destination.fpu_reg(), XMM0); | 1801 __ movaps(destination.fpu_reg(), XMM0); |
| 1801 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1802 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1802 ASSERT(destination.IsDoubleStackSlot() || | 1803 ASSERT(destination.IsDoubleStackSlot() || |
| 1803 destination.IsQuadStackSlot() || | 1804 destination.IsQuadStackSlot() || |
| 1804 source.IsDoubleStackSlot() || | 1805 source.IsDoubleStackSlot() || |
| 1805 source.IsQuadStackSlot()); | 1806 source.IsQuadStackSlot()); |
| 1806 bool double_width = destination.IsDoubleStackSlot() || | 1807 bool double_width = destination.IsDoubleStackSlot() || |
| 1807 source.IsDoubleStackSlot(); | 1808 source.IsDoubleStackSlot(); |
| 1808 XmmRegister reg = source.IsFpuRegister() ? source.fpu_reg() | 1809 XmmRegister reg = source.IsFpuRegister() ? source.fpu_reg() |
| 1809 : destination.fpu_reg(); | 1810 : destination.fpu_reg(); |
| 1810 Address slot_address = source.IsFpuRegister() | 1811 Address slot_address = source.IsFpuRegister() |
| 1811 ? destination.ToStackSlotAddress() | 1812 ? Address::StackSlotAddress(destination) |
| 1812 : source.ToStackSlotAddress(); | 1813 : Address::StackSlotAddress(source); |
| 1813 | 1814 |
| 1814 if (double_width) { | 1815 if (double_width) { |
| 1815 __ movsd(XMM0, slot_address); | 1816 __ movsd(XMM0, slot_address); |
| 1816 __ movsd(slot_address, reg); | 1817 __ movsd(slot_address, reg); |
| 1817 } else { | 1818 } else { |
| 1818 __ movups(XMM0, slot_address); | 1819 __ movups(XMM0, slot_address); |
| 1819 __ movups(slot_address, reg); | 1820 __ movups(slot_address, reg); |
| 1820 } | 1821 } |
| 1821 __ movaps(reg, XMM0); | 1822 __ movaps(reg, XMM0); |
| 1822 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { | 1823 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { |
| 1823 const Address& source_slot_address = source.ToStackSlotAddress(); | 1824 const Address& source_slot_address = Address::StackSlotAddress(source); |
| 1824 const Address& destination_slot_address = destination.ToStackSlotAddress(); | 1825 const Address& destination_slot_address = |
| 1826 Address::StackSlotAddress(destination); |
| 1825 | 1827 |
| 1826 ScratchFpuRegisterScope ensure_scratch(this, XMM0); | 1828 ScratchFpuRegisterScope ensure_scratch(this, XMM0); |
| 1827 __ movsd(XMM0, source_slot_address); | 1829 __ movsd(XMM0, source_slot_address); |
| 1828 __ movsd(ensure_scratch.reg(), destination_slot_address); | 1830 __ movsd(ensure_scratch.reg(), destination_slot_address); |
| 1829 __ movsd(destination_slot_address, XMM0); | 1831 __ movsd(destination_slot_address, XMM0); |
| 1830 __ movsd(source_slot_address, ensure_scratch.reg()); | 1832 __ movsd(source_slot_address, ensure_scratch.reg()); |
| 1831 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { | 1833 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { |
| 1832 const Address& source_slot_address = source.ToStackSlotAddress(); | 1834 const Address& source_slot_address = Address::StackSlotAddress(source); |
| 1833 const Address& destination_slot_address = destination.ToStackSlotAddress(); | 1835 const Address& destination_slot_address = |
| 1836 Address::StackSlotAddress(destination); |
| 1834 | 1837 |
| 1835 ScratchFpuRegisterScope ensure_scratch(this, XMM0); | 1838 ScratchFpuRegisterScope ensure_scratch(this, XMM0); |
| 1836 __ movups(XMM0, source_slot_address); | 1839 __ movups(XMM0, source_slot_address); |
| 1837 __ movups(ensure_scratch.reg(), destination_slot_address); | 1840 __ movups(ensure_scratch.reg(), destination_slot_address); |
| 1838 __ movups(destination_slot_address, XMM0); | 1841 __ movups(destination_slot_address, XMM0); |
| 1839 __ movups(source_slot_address, ensure_scratch.reg()); | 1842 __ movups(source_slot_address, ensure_scratch.reg()); |
| 1840 } else { | 1843 } else { |
| 1841 UNREACHABLE(); | 1844 UNREACHABLE(); |
| 1842 } | 1845 } |
| 1843 | 1846 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1900 __ movups(reg, Address(RSP, 0)); | 1903 __ movups(reg, Address(RSP, 0)); |
| 1901 __ addq(RSP, Immediate(kFpuRegisterSize)); | 1904 __ addq(RSP, Immediate(kFpuRegisterSize)); |
| 1902 } | 1905 } |
| 1903 | 1906 |
| 1904 | 1907 |
| 1905 #undef __ | 1908 #undef __ |
| 1906 | 1909 |
| 1907 } // namespace dart | 1910 } // namespace dart |
| 1908 | 1911 |
| 1909 #endif // defined TARGET_ARCH_X64 | 1912 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |