| 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 bool FlowGraphCompiler::SupportsUnboxedSimd128() { | 49 bool FlowGraphCompiler::SupportsUnboxedSimd128() { |
| 50 return false; | 50 return false; |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 bool FlowGraphCompiler::SupportsSinCos() { | 54 bool FlowGraphCompiler::SupportsSinCos() { |
| 55 return false; | 55 return false; |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 void FlowGraphCompiler::EnterIntrinsicMode() { |
| 60 ASSERT(!intrinsic_mode()); |
| 61 intrinsic_mode_ = true; |
| 62 assembler()->set_allow_constant_pool(false); |
| 63 } |
| 64 |
| 65 |
| 66 void FlowGraphCompiler::ExitIntrinsicMode() { |
| 67 ASSERT(intrinsic_mode()); |
| 68 intrinsic_mode_ = false; |
| 69 assembler()->set_allow_constant_pool(true); |
| 70 } |
| 71 |
| 72 |
| 59 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, | 73 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
| 60 DeoptInfoBuilder* builder, | 74 DeoptInfoBuilder* builder, |
| 61 const Array& deopt_table) { | 75 const Array& deopt_table) { |
| 62 if (deopt_env_ == NULL) { | 76 if (deopt_env_ == NULL) { |
| 63 return DeoptInfo::null(); | 77 return DeoptInfo::null(); |
| 64 } | 78 } |
| 65 | 79 |
| 66 intptr_t stack_height = compiler->StackSize(); | 80 intptr_t stack_height = compiler->StackSize(); |
| 67 AllocateIncomingParametersRecursive(deopt_env_, &stack_height); | 81 AllocateIncomingParametersRecursive(deopt_env_, &stack_height); |
| 68 | 82 |
| (...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1587 const Location source = move->src(); | 1601 const Location source = move->src(); |
| 1588 const Location destination = move->dest(); | 1602 const Location destination = move->dest(); |
| 1589 __ TraceSimMsg("ParallelMoveResolver::EmitMove"); | 1603 __ TraceSimMsg("ParallelMoveResolver::EmitMove"); |
| 1590 | 1604 |
| 1591 if (source.IsRegister()) { | 1605 if (source.IsRegister()) { |
| 1592 if (destination.IsRegister()) { | 1606 if (destination.IsRegister()) { |
| 1593 __ mov(destination.reg(), source.reg()); | 1607 __ mov(destination.reg(), source.reg()); |
| 1594 } else { | 1608 } else { |
| 1595 ASSERT(destination.IsStackSlot()); | 1609 ASSERT(destination.IsStackSlot()); |
| 1596 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1610 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1597 __ StoreToOffset(source.reg(), FP, dest_offset); | 1611 __ StoreToOffset(source.reg(), destination.base_reg(), dest_offset); |
| 1598 } | 1612 } |
| 1599 } else if (source.IsStackSlot()) { | 1613 } else if (source.IsStackSlot()) { |
| 1600 if (destination.IsRegister()) { | 1614 if (destination.IsRegister()) { |
| 1601 const intptr_t source_offset = source.ToStackSlotOffset(); | 1615 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1602 __ LoadFromOffset(destination.reg(), FP, source_offset); | 1616 __ LoadFromOffset(destination.reg(), source.base_reg(), source_offset); |
| 1603 } else { | 1617 } else { |
| 1604 ASSERT(destination.IsStackSlot()); | 1618 ASSERT(destination.IsStackSlot()); |
| 1605 const intptr_t source_offset = source.ToStackSlotOffset(); | 1619 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1606 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1620 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1607 __ LoadFromOffset(TMP, FP, source_offset); | 1621 ScratchRegisterScope tmp(this, kNoRegister); |
| 1608 __ StoreToOffset(TMP, FP, dest_offset); | 1622 __ LoadFromOffset(tmp.reg(), source.base_reg(), source_offset); |
| 1623 __ StoreToOffset(tmp.reg(), destination.base_reg(), dest_offset); |
| 1609 } | 1624 } |
| 1610 } else if (source.IsFpuRegister()) { | 1625 } else if (source.IsFpuRegister()) { |
| 1611 if (destination.IsFpuRegister()) { | 1626 if (destination.IsFpuRegister()) { |
| 1612 DRegister dst = destination.fpu_reg(); | 1627 DRegister dst = destination.fpu_reg(); |
| 1613 DRegister src = source.fpu_reg(); | 1628 DRegister src = source.fpu_reg(); |
| 1614 __ movd(dst, src); | 1629 __ movd(dst, src); |
| 1615 } else { | 1630 } else { |
| 1616 if (destination.IsDoubleStackSlot()) { | 1631 if (destination.IsDoubleStackSlot()) { |
| 1617 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1632 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1618 DRegister src = source.fpu_reg(); | 1633 DRegister src = source.fpu_reg(); |
| 1619 __ StoreDToOffset(src, FP, dest_offset); | 1634 __ StoreDToOffset(src, destination.base_reg(), dest_offset); |
| 1620 } else { | 1635 } else { |
| 1621 ASSERT(destination.IsQuadStackSlot()); | 1636 ASSERT(destination.IsQuadStackSlot()); |
| 1622 UNIMPLEMENTED(); | 1637 UNIMPLEMENTED(); |
| 1623 } | 1638 } |
| 1624 } | 1639 } |
| 1625 } else if (source.IsDoubleStackSlot()) { | 1640 } else if (source.IsDoubleStackSlot()) { |
| 1626 if (destination.IsFpuRegister()) { | 1641 if (destination.IsFpuRegister()) { |
| 1627 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1642 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1628 DRegister dst = destination.fpu_reg(); | 1643 DRegister dst = destination.fpu_reg(); |
| 1629 __ LoadDFromOffset(dst, FP, dest_offset); | 1644 __ LoadDFromOffset(dst, source.base_reg(), source_offset); |
| 1630 } else { | 1645 } else { |
| 1631 ASSERT(destination.IsDoubleStackSlot()); | 1646 ASSERT(destination.IsDoubleStackSlot()); |
| 1632 const intptr_t source_offset = source.ToStackSlotOffset(); | 1647 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1633 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1648 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1634 __ LoadDFromOffset(DTMP, FP, source_offset); | 1649 __ LoadDFromOffset(DTMP, source.base_reg(), source_offset); |
| 1635 __ StoreDToOffset(DTMP, FP, dest_offset); | 1650 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1636 } | 1651 } |
| 1637 } else if (source.IsQuadStackSlot()) { | 1652 } else if (source.IsQuadStackSlot()) { |
| 1638 UNIMPLEMENTED(); | 1653 UNIMPLEMENTED(); |
| 1639 } else { | 1654 } else { |
| 1640 ASSERT(source.IsConstant()); | 1655 ASSERT(source.IsConstant()); |
| 1641 const Object& constant = source.constant(); | 1656 const Object& constant = source.constant(); |
| 1642 if (destination.IsRegister()) { | 1657 if (destination.IsRegister()) { |
| 1643 __ LoadObject(destination.reg(), constant); | 1658 __ LoadObject(destination.reg(), constant); |
| 1644 } else if (destination.IsFpuRegister()) { | 1659 } else if (destination.IsFpuRegister()) { |
| 1645 __ LoadObject(TMP, constant); | 1660 __ LoadObject(TMP, constant); |
| 1646 __ LoadDFromOffset(destination.fpu_reg(), TMP, | 1661 __ LoadDFromOffset(destination.fpu_reg(), TMP, |
| 1647 Double::value_offset() - kHeapObjectTag); | 1662 Double::value_offset() - kHeapObjectTag); |
| 1648 } else if (destination.IsDoubleStackSlot()) { | 1663 } else if (destination.IsDoubleStackSlot()) { |
| 1649 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1664 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1650 __ LoadObject(TMP, constant); | 1665 __ LoadObject(TMP, constant); |
| 1651 __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag); | 1666 __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag); |
| 1652 __ StoreDToOffset(DTMP, FP, dest_offset); | 1667 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1653 } else { | 1668 } else { |
| 1654 ASSERT(destination.IsStackSlot()); | 1669 ASSERT(destination.IsStackSlot()); |
| 1655 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1670 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1656 __ LoadObject(TMP, constant); | 1671 ScratchRegisterScope tmp(this, kNoRegister); |
| 1657 __ StoreToOffset(TMP, FP, dest_offset); | 1672 __ LoadObject(tmp.reg(), constant); |
| 1673 __ StoreToOffset(tmp.reg(), destination.base_reg(), dest_offset); |
| 1658 } | 1674 } |
| 1659 } | 1675 } |
| 1660 | 1676 |
| 1661 move->Eliminate(); | 1677 move->Eliminate(); |
| 1662 } | 1678 } |
| 1663 | 1679 |
| 1664 | 1680 |
| 1665 void ParallelMoveResolver::EmitSwap(int index) { | 1681 void ParallelMoveResolver::EmitSwap(int index) { |
| 1666 MoveOperands* move = moves_[index]; | 1682 MoveOperands* move = moves_[index]; |
| 1667 const Location source = move->src(); | 1683 const Location source = move->src(); |
| 1668 const Location destination = move->dest(); | 1684 const Location destination = move->dest(); |
| 1669 | 1685 |
| 1670 if (source.IsRegister() && destination.IsRegister()) { | 1686 if (source.IsRegister() && destination.IsRegister()) { |
| 1671 ASSERT(source.reg() != TMP); | 1687 ASSERT(source.reg() != TMP); |
| 1672 ASSERT(destination.reg() != TMP); | 1688 ASSERT(destination.reg() != TMP); |
| 1673 __ mov(TMP, source.reg()); | 1689 __ mov(TMP, source.reg()); |
| 1674 __ mov(source.reg(), destination.reg()); | 1690 __ mov(source.reg(), destination.reg()); |
| 1675 __ mov(destination.reg(), TMP); | 1691 __ mov(destination.reg(), TMP); |
| 1676 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1692 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1677 Exchange(source.reg(), destination.ToStackSlotOffset()); | 1693 Exchange(source.reg(), |
| 1694 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1678 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1695 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1679 Exchange(destination.reg(), source.ToStackSlotOffset()); | 1696 Exchange(destination.reg(), |
| 1697 source.base_reg(), source.ToStackSlotOffset()); |
| 1680 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1698 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1681 Exchange(source.ToStackSlotOffset(), destination.ToStackSlotOffset()); | 1699 Exchange(source.base_reg(), source.ToStackSlotOffset(), |
| 1700 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1682 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1701 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1683 DRegister dst = destination.fpu_reg(); | 1702 DRegister dst = destination.fpu_reg(); |
| 1684 DRegister src = source.fpu_reg(); | 1703 DRegister src = source.fpu_reg(); |
| 1685 __ movd(DTMP, src); | 1704 __ movd(DTMP, src); |
| 1686 __ movd(src, dst); | 1705 __ movd(src, dst); |
| 1687 __ movd(dst, DTMP); | 1706 __ movd(dst, DTMP); |
| 1688 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1707 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1689 ASSERT(destination.IsDoubleStackSlot() || | 1708 ASSERT(destination.IsDoubleStackSlot() || |
| 1690 destination.IsQuadStackSlot() || | 1709 destination.IsQuadStackSlot() || |
| 1691 source.IsDoubleStackSlot() || | 1710 source.IsDoubleStackSlot() || |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 } | 1780 } |
| 1762 | 1781 |
| 1763 | 1782 |
| 1764 // Do not call or implement this function. Instead, use the form below that | 1783 // Do not call or implement this function. Instead, use the form below that |
| 1765 // uses offsets from the frame pointer instead of Addresses. | 1784 // uses offsets from the frame pointer instead of Addresses. |
| 1766 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1785 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1767 UNREACHABLE(); | 1786 UNREACHABLE(); |
| 1768 } | 1787 } |
| 1769 | 1788 |
| 1770 | 1789 |
| 1771 void ParallelMoveResolver::Exchange(Register reg, intptr_t stack_offset) { | 1790 void ParallelMoveResolver::Exchange(Register reg, |
| 1772 __ mov(TMP, reg); | 1791 Register base_reg, |
| 1773 __ LoadFromOffset(reg, FP, stack_offset); | 1792 intptr_t stack_offset) { |
| 1774 __ StoreToOffset(TMP, FP, stack_offset); | 1793 ScratchRegisterScope tmp(this, kNoRegister); |
| 1794 __ mov(tmp.reg(), reg); |
| 1795 __ LoadFromOffset(reg, base_reg, stack_offset); |
| 1796 __ StoreToOffset(tmp.reg(), base_reg, stack_offset); |
| 1775 } | 1797 } |
| 1776 | 1798 |
| 1777 | 1799 |
| 1778 void ParallelMoveResolver::Exchange(intptr_t stack_offset1, | 1800 void ParallelMoveResolver::Exchange(Register base_reg1, |
| 1801 intptr_t stack_offset1, |
| 1802 Register base_reg2, |
| 1779 intptr_t stack_offset2) { | 1803 intptr_t stack_offset2) { |
| 1780 ScratchRegisterScope ensure_scratch(this, TMP); | 1804 ScratchRegisterScope tmp1(this, kNoRegister); |
| 1781 __ LoadFromOffset(ensure_scratch.reg(), FP, stack_offset1); | 1805 ScratchRegisterScope tmp2(this, tmp1.reg()); |
| 1782 __ LoadFromOffset(TMP, FP, stack_offset2); | 1806 __ LoadFromOffset(tmp1.reg(), base_reg1, stack_offset1); |
| 1783 __ StoreToOffset(ensure_scratch.reg(), FP, stack_offset2); | 1807 __ LoadFromOffset(tmp2.reg(), base_reg2, stack_offset2); |
| 1784 __ StoreToOffset(TMP, FP, stack_offset1); | 1808 __ StoreToOffset(tmp1.reg(), base_reg1, stack_offset2); |
| 1809 __ StoreToOffset(tmp2.reg(), base_reg2, stack_offset1); |
| 1785 } | 1810 } |
| 1786 | 1811 |
| 1787 | 1812 |
| 1788 void ParallelMoveResolver::SpillScratch(Register reg) { | 1813 void ParallelMoveResolver::SpillScratch(Register reg) { |
| 1789 __ TraceSimMsg("ParallelMoveResolver::SpillScratch"); | 1814 __ TraceSimMsg("ParallelMoveResolver::SpillScratch"); |
| 1790 __ Push(reg); | 1815 __ Push(reg); |
| 1791 } | 1816 } |
| 1792 | 1817 |
| 1793 | 1818 |
| 1794 void ParallelMoveResolver::RestoreScratch(Register reg) { | 1819 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1810 __ AddImmediate(SP, kDoubleSize); | 1835 __ AddImmediate(SP, kDoubleSize); |
| 1811 } | 1836 } |
| 1812 | 1837 |
| 1813 | 1838 |
| 1814 #undef __ | 1839 #undef __ |
| 1815 | 1840 |
| 1816 | 1841 |
| 1817 } // namespace dart | 1842 } // namespace dart |
| 1818 | 1843 |
| 1819 #endif // defined TARGET_ARCH_MIPS | 1844 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |