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