| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 bool FlowGraphCompiler::SupportsUnboxedSimd128() { | 53 bool FlowGraphCompiler::SupportsUnboxedSimd128() { |
| 54 return TargetCPUFeatures::neon_supported() && FLAG_enable_simd_inline; | 54 return TargetCPUFeatures::neon_supported() && FLAG_enable_simd_inline; |
| 55 } | 55 } |
| 56 | 56 |
| 57 | 57 |
| 58 bool FlowGraphCompiler::SupportsSinCos() { | 58 bool FlowGraphCompiler::SupportsSinCos() { |
| 59 return false; | 59 return false; |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 void FlowGraphCompiler::EnterIntrinsicMode() { |
| 64 ASSERT(!intrinsic_mode()); |
| 65 intrinsic_mode_ = true; |
| 66 assembler()->set_allow_constant_pool(false); |
| 67 } |
| 68 |
| 69 |
| 70 void FlowGraphCompiler::ExitIntrinsicMode() { |
| 71 ASSERT(intrinsic_mode()); |
| 72 intrinsic_mode_ = false; |
| 73 assembler()->set_allow_constant_pool(true); |
| 74 } |
| 75 |
| 76 |
| 63 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, | 77 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
| 64 DeoptInfoBuilder* builder, | 78 DeoptInfoBuilder* builder, |
| 65 const Array& deopt_table) { | 79 const Array& deopt_table) { |
| 66 if (deopt_env_ == NULL) { | 80 if (deopt_env_ == NULL) { |
| 67 return DeoptInfo::null(); | 81 return DeoptInfo::null(); |
| 68 } | 82 } |
| 69 | 83 |
| 70 intptr_t stack_height = compiler->StackSize(); | 84 intptr_t stack_height = compiler->StackSize(); |
| 71 AllocateIncomingParametersRecursive(deopt_env_, &stack_height); | 85 AllocateIncomingParametersRecursive(deopt_env_, &stack_height); |
| 72 | 86 |
| (...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 MoveOperands* move = moves_[index]; | 1543 MoveOperands* move = moves_[index]; |
| 1530 const Location source = move->src(); | 1544 const Location source = move->src(); |
| 1531 const Location destination = move->dest(); | 1545 const Location destination = move->dest(); |
| 1532 | 1546 |
| 1533 if (source.IsRegister()) { | 1547 if (source.IsRegister()) { |
| 1534 if (destination.IsRegister()) { | 1548 if (destination.IsRegister()) { |
| 1535 __ mov(destination.reg(), Operand(source.reg())); | 1549 __ mov(destination.reg(), Operand(source.reg())); |
| 1536 } else { | 1550 } else { |
| 1537 ASSERT(destination.IsStackSlot()); | 1551 ASSERT(destination.IsStackSlot()); |
| 1538 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1552 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1539 __ StoreToOffset(kWord, source.reg(), FP, dest_offset); | 1553 __ StoreToOffset( |
| 1554 kWord, source.reg(), destination.base_reg(), dest_offset); |
| 1540 } | 1555 } |
| 1541 } else if (source.IsStackSlot()) { | 1556 } else if (source.IsStackSlot()) { |
| 1542 if (destination.IsRegister()) { | 1557 if (destination.IsRegister()) { |
| 1543 const intptr_t source_offset = source.ToStackSlotOffset(); | 1558 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1544 __ LoadFromOffset(kWord, destination.reg(), FP, source_offset); | 1559 __ LoadFromOffset( |
| 1560 kWord, destination.reg(), source.base_reg(), source_offset); |
| 1545 } else { | 1561 } else { |
| 1546 ASSERT(destination.IsStackSlot()); | 1562 ASSERT(destination.IsStackSlot()); |
| 1547 const intptr_t source_offset = source.ToStackSlotOffset(); | 1563 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1548 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1564 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1549 __ LoadFromOffset(kWord, TMP, FP, source_offset); | 1565 __ LoadFromOffset(kWord, TMP, source.base_reg(), source_offset); |
| 1550 __ StoreToOffset(kWord, TMP, FP, dest_offset); | 1566 __ StoreToOffset(kWord, TMP, destination.base_reg(), dest_offset); |
| 1551 } | 1567 } |
| 1552 } else if (source.IsFpuRegister()) { | 1568 } else if (source.IsFpuRegister()) { |
| 1553 if (destination.IsFpuRegister()) { | 1569 if (destination.IsFpuRegister()) { |
| 1554 if (TargetCPUFeatures::neon_supported()) { | 1570 if (TargetCPUFeatures::neon_supported()) { |
| 1555 __ vmovq(destination.fpu_reg(), source.fpu_reg()); | 1571 __ vmovq(destination.fpu_reg(), source.fpu_reg()); |
| 1556 } else { | 1572 } else { |
| 1557 // If we're not inlining simd values, then only the even numbered D | 1573 // If we're not inlining simd values, then only the even numbered D |
| 1558 // register will have anything in them. | 1574 // register will have anything in them. |
| 1559 __ vmovd(EvenDRegisterOf(destination.fpu_reg()), | 1575 __ vmovd(EvenDRegisterOf(destination.fpu_reg()), |
| 1560 EvenDRegisterOf(source.fpu_reg())); | 1576 EvenDRegisterOf(source.fpu_reg())); |
| 1561 } | 1577 } |
| 1562 } else { | 1578 } else { |
| 1563 if (destination.IsDoubleStackSlot()) { | 1579 if (destination.IsDoubleStackSlot()) { |
| 1564 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1580 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1565 DRegister src = EvenDRegisterOf(source.fpu_reg()); | 1581 DRegister src = EvenDRegisterOf(source.fpu_reg()); |
| 1566 __ StoreDToOffset(src, FP, dest_offset); | 1582 __ StoreDToOffset(src, destination.base_reg(), dest_offset); |
| 1567 } else { | 1583 } else { |
| 1568 ASSERT(destination.IsQuadStackSlot()); | 1584 ASSERT(destination.IsQuadStackSlot()); |
| 1569 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1585 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1570 const DRegister dsrc0 = EvenDRegisterOf(source.fpu_reg()); | 1586 const DRegister dsrc0 = EvenDRegisterOf(source.fpu_reg()); |
| 1571 __ StoreMultipleDToOffset(dsrc0, 2, FP, dest_offset); | 1587 __ StoreMultipleDToOffset( |
| 1588 dsrc0, 2, destination.base_reg(), dest_offset); |
| 1572 } | 1589 } |
| 1573 } | 1590 } |
| 1574 } else if (source.IsDoubleStackSlot()) { | 1591 } else if (source.IsDoubleStackSlot()) { |
| 1575 if (destination.IsFpuRegister()) { | 1592 if (destination.IsFpuRegister()) { |
| 1576 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1593 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1577 const DRegister dst = EvenDRegisterOf(destination.fpu_reg()); | 1594 const DRegister dst = EvenDRegisterOf(destination.fpu_reg()); |
| 1578 __ LoadDFromOffset(dst, FP, dest_offset); | 1595 __ LoadDFromOffset(dst, source.base_reg(), source_offset); |
| 1579 } else { | 1596 } else { |
| 1580 ASSERT(destination.IsDoubleStackSlot()); | 1597 ASSERT(destination.IsDoubleStackSlot()); |
| 1581 const intptr_t source_offset = source.ToStackSlotOffset(); | 1598 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1582 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1599 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1583 __ LoadDFromOffset(DTMP, FP, source_offset); | 1600 __ LoadDFromOffset(DTMP, source.base_reg(), source_offset); |
| 1584 __ StoreDToOffset(DTMP, FP, dest_offset); | 1601 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1585 } | 1602 } |
| 1586 } else if (source.IsQuadStackSlot()) { | 1603 } else if (source.IsQuadStackSlot()) { |
| 1587 if (destination.IsFpuRegister()) { | 1604 if (destination.IsFpuRegister()) { |
| 1588 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1605 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1589 const DRegister dst0 = EvenDRegisterOf(destination.fpu_reg()); | 1606 const DRegister dst0 = EvenDRegisterOf(destination.fpu_reg()); |
| 1590 __ LoadMultipleDFromOffset(dst0, 2, FP, dest_offset); | 1607 __ LoadMultipleDFromOffset(dst0, 2, source.base_reg(), source_offset); |
| 1591 } else { | 1608 } else { |
| 1592 ASSERT(destination.IsQuadStackSlot()); | 1609 ASSERT(destination.IsQuadStackSlot()); |
| 1593 const intptr_t source_offset = source.ToStackSlotOffset(); | 1610 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1594 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1611 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1595 const DRegister dtmp0 = DTMP; | 1612 const DRegister dtmp0 = DTMP; |
| 1596 __ LoadMultipleDFromOffset(dtmp0, 2, FP, source_offset); | 1613 __ LoadMultipleDFromOffset(dtmp0, 2, source.base_reg(), source_offset); |
| 1597 __ StoreMultipleDToOffset(dtmp0, 2, FP, dest_offset); | 1614 __ StoreMultipleDToOffset(dtmp0, 2, destination.base_reg(), dest_offset); |
| 1598 } | 1615 } |
| 1599 } else { | 1616 } else { |
| 1600 ASSERT(source.IsConstant()); | 1617 ASSERT(source.IsConstant()); |
| 1601 const Object& constant = source.constant(); | 1618 const Object& constant = source.constant(); |
| 1602 if (destination.IsRegister()) { | 1619 if (destination.IsRegister()) { |
| 1603 if (source.constant_instruction()->representation() == kUnboxedInt32) { | 1620 if (source.constant_instruction()->representation() == kUnboxedInt32) { |
| 1604 __ LoadImmediate(destination.reg(), Smi::Cast(constant).Value()); | 1621 __ LoadImmediate(destination.reg(), Smi::Cast(constant).Value()); |
| 1605 } else { | 1622 } else { |
| 1606 __ LoadObject(destination.reg(), constant); | 1623 __ LoadObject(destination.reg(), constant); |
| 1607 } | 1624 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1619 } else if (destination.IsDoubleStackSlot()) { | 1636 } else if (destination.IsDoubleStackSlot()) { |
| 1620 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0) && | 1637 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0) && |
| 1621 TargetCPUFeatures::neon_supported()) { | 1638 TargetCPUFeatures::neon_supported()) { |
| 1622 __ veorq(QTMP, QTMP, QTMP); | 1639 __ veorq(QTMP, QTMP, QTMP); |
| 1623 } else { | 1640 } else { |
| 1624 __ LoadObject(TMP, constant); | 1641 __ LoadObject(TMP, constant); |
| 1625 __ AddImmediate(TMP, TMP, Double::value_offset() - kHeapObjectTag); | 1642 __ AddImmediate(TMP, TMP, Double::value_offset() - kHeapObjectTag); |
| 1626 __ vldrd(DTMP, Address(TMP, 0)); | 1643 __ vldrd(DTMP, Address(TMP, 0)); |
| 1627 } | 1644 } |
| 1628 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1645 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1629 __ StoreDToOffset(DTMP, FP, dest_offset); | 1646 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1630 } else { | 1647 } else { |
| 1631 ASSERT(destination.IsStackSlot()); | 1648 ASSERT(destination.IsStackSlot()); |
| 1632 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1649 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1633 if (source.constant_instruction()->representation() == kUnboxedInt32) { | 1650 if (source.constant_instruction()->representation() == kUnboxedInt32) { |
| 1634 __ LoadImmediate(TMP, Smi::Cast(constant).Value()); | 1651 __ LoadImmediate(TMP, Smi::Cast(constant).Value()); |
| 1635 } else { | 1652 } else { |
| 1636 __ LoadObject(TMP, constant); | 1653 __ LoadObject(TMP, constant); |
| 1637 } | 1654 } |
| 1638 __ StoreToOffset(kWord, TMP, FP, dest_offset); | 1655 __ StoreToOffset(kWord, TMP, destination.base_reg(), dest_offset); |
| 1639 } | 1656 } |
| 1640 } | 1657 } |
| 1641 | 1658 |
| 1642 move->Eliminate(); | 1659 move->Eliminate(); |
| 1643 } | 1660 } |
| 1644 | 1661 |
| 1645 | 1662 |
| 1646 void ParallelMoveResolver::EmitSwap(int index) { | 1663 void ParallelMoveResolver::EmitSwap(int index) { |
| 1647 MoveOperands* move = moves_[index]; | 1664 MoveOperands* move = moves_[index]; |
| 1648 const Location source = move->src(); | 1665 const Location source = move->src(); |
| 1649 const Location destination = move->dest(); | 1666 const Location destination = move->dest(); |
| 1650 | 1667 |
| 1651 if (source.IsRegister() && destination.IsRegister()) { | 1668 if (source.IsRegister() && destination.IsRegister()) { |
| 1652 ASSERT(source.reg() != IP); | 1669 ASSERT(source.reg() != IP); |
| 1653 ASSERT(destination.reg() != IP); | 1670 ASSERT(destination.reg() != IP); |
| 1654 __ mov(IP, Operand(source.reg())); | 1671 __ mov(IP, Operand(source.reg())); |
| 1655 __ mov(source.reg(), Operand(destination.reg())); | 1672 __ mov(source.reg(), Operand(destination.reg())); |
| 1656 __ mov(destination.reg(), Operand(IP)); | 1673 __ mov(destination.reg(), Operand(IP)); |
| 1657 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1674 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1658 Exchange(source.reg(), destination.ToStackSlotOffset()); | 1675 Exchange(source.reg(), |
| 1676 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1659 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1677 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1660 Exchange(destination.reg(), source.ToStackSlotOffset()); | 1678 Exchange(destination.reg(), |
| 1679 source.base_reg(), source.ToStackSlotOffset()); |
| 1661 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1680 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1662 Exchange(source.ToStackSlotOffset(), destination.ToStackSlotOffset()); | 1681 Exchange(source.base_reg(), source.ToStackSlotOffset(), |
| 1682 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1663 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1683 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1664 const DRegister dst = EvenDRegisterOf(destination.fpu_reg()); | 1684 const DRegister dst = EvenDRegisterOf(destination.fpu_reg()); |
| 1665 DRegister src = EvenDRegisterOf(source.fpu_reg()); | 1685 DRegister src = EvenDRegisterOf(source.fpu_reg()); |
| 1666 __ vmovd(DTMP, src); | 1686 __ vmovd(DTMP, src); |
| 1667 __ vmovd(src, dst); | 1687 __ vmovd(src, dst); |
| 1668 __ vmovd(dst, DTMP); | 1688 __ vmovd(dst, DTMP); |
| 1669 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1689 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1670 ASSERT(destination.IsDoubleStackSlot() || | 1690 ASSERT(destination.IsDoubleStackSlot() || |
| 1671 destination.IsQuadStackSlot() || | 1691 destination.IsQuadStackSlot() || |
| 1672 source.IsDoubleStackSlot() || | 1692 source.IsDoubleStackSlot() || |
| 1673 source.IsQuadStackSlot()); | 1693 source.IsQuadStackSlot()); |
| 1674 bool double_width = destination.IsDoubleStackSlot() || | 1694 bool double_width = destination.IsDoubleStackSlot() || |
| 1675 source.IsDoubleStackSlot(); | 1695 source.IsDoubleStackSlot(); |
| 1676 QRegister qreg = source.IsFpuRegister() ? source.fpu_reg() | 1696 QRegister qreg = source.IsFpuRegister() ? source.fpu_reg() |
| 1677 : destination.fpu_reg(); | 1697 : destination.fpu_reg(); |
| 1678 DRegister reg = EvenDRegisterOf(qreg); | 1698 DRegister reg = EvenDRegisterOf(qreg); |
| 1679 const intptr_t slot_offset = source.IsFpuRegister() | 1699 const intptr_t slot_offset = source.IsFpuRegister() |
| 1680 ? destination.ToStackSlotOffset() | 1700 ? destination.ToStackSlotOffset() |
| 1681 : source.ToStackSlotOffset(); | 1701 : source.ToStackSlotOffset(); |
| 1702 Register base_reg = source.IsFpuRegister() |
| 1703 ? destination.base_reg() |
| 1704 : source.base_reg(); |
| 1682 | 1705 |
| 1683 if (double_width) { | 1706 if (double_width) { |
| 1684 __ LoadDFromOffset(DTMP, FP, slot_offset); | 1707 __ LoadDFromOffset(DTMP, base_reg, slot_offset); |
| 1685 __ StoreDToOffset(reg, FP, slot_offset); | 1708 __ StoreDToOffset(reg, base_reg, slot_offset); |
| 1686 __ vmovd(reg, DTMP); | 1709 __ vmovd(reg, DTMP); |
| 1687 } else { | 1710 } else { |
| 1688 UNIMPLEMENTED(); | 1711 UNIMPLEMENTED(); |
| 1689 } | 1712 } |
| 1690 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { | 1713 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { |
| 1691 const intptr_t source_offset = source.ToStackSlotOffset(); | 1714 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1692 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1715 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1693 | 1716 |
| 1694 ScratchFpuRegisterScope ensure_scratch(this, QTMP); | 1717 ScratchFpuRegisterScope ensure_scratch(this, QTMP); |
| 1695 DRegister scratch = EvenDRegisterOf(ensure_scratch.reg()); | 1718 DRegister scratch = EvenDRegisterOf(ensure_scratch.reg()); |
| 1696 __ LoadDFromOffset(DTMP, FP, source_offset); | 1719 __ LoadDFromOffset(DTMP, source.base_reg(), source_offset); |
| 1697 __ LoadDFromOffset(scratch, FP, dest_offset); | 1720 __ LoadDFromOffset(scratch, destination.base_reg(), dest_offset); |
| 1698 __ StoreDToOffset(DTMP, FP, dest_offset); | 1721 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1699 __ StoreDToOffset(scratch, FP, source_offset); | 1722 __ StoreDToOffset(scratch, destination.base_reg(), source_offset); |
| 1700 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { | 1723 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { |
| 1701 UNIMPLEMENTED(); | 1724 UNIMPLEMENTED(); |
| 1702 } else { | 1725 } else { |
| 1703 UNREACHABLE(); | 1726 UNREACHABLE(); |
| 1704 } | 1727 } |
| 1705 | 1728 |
| 1706 // The swap of source and destination has executed a move from source to | 1729 // The swap of source and destination has executed a move from source to |
| 1707 // destination. | 1730 // destination. |
| 1708 move->Eliminate(); | 1731 move->Eliminate(); |
| 1709 | 1732 |
| 1710 // Any unperformed (including pending) move with a source of either | 1733 // Any unperformed (including pending) move with a source of either |
| 1711 // this move's source or destination needs to have their source | 1734 // this move's source or destination needs to have their source |
| 1712 // changed to reflect the state of affairs after the swap. | 1735 // changed to reflect the state of affairs after the swap. |
| 1713 for (int i = 0; i < moves_.length(); ++i) { | 1736 for (int i = 0; i < moves_.length(); ++i) { |
| 1714 const MoveOperands& other_move = *moves_[i]; | 1737 const MoveOperands& other_move = *moves_[i]; |
| 1715 if (other_move.Blocks(source)) { | 1738 if (other_move.Blocks(source)) { |
| 1716 moves_[i]->set_src(destination); | 1739 moves_[i]->set_src(destination); |
| 1717 } else if (other_move.Blocks(destination)) { | 1740 } else if (other_move.Blocks(destination)) { |
| 1718 moves_[i]->set_src(source); | 1741 moves_[i]->set_src(source); |
| 1719 } | 1742 } |
| 1720 } | 1743 } |
| 1721 } | 1744 } |
| 1722 | 1745 |
| 1723 | 1746 |
| 1724 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, | 1747 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, |
| 1725 const Address& src) { | 1748 const Address& src) { |
| 1726 __ ldr(IP, src); | 1749 UNREACHABLE(); |
| 1727 __ str(IP, dst); | |
| 1728 } | 1750 } |
| 1729 | 1751 |
| 1730 | 1752 |
| 1731 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { | 1753 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { |
| 1732 __ LoadObject(IP, obj); | 1754 UNREACHABLE(); |
| 1733 __ str(IP, dst); | |
| 1734 } | 1755 } |
| 1735 | 1756 |
| 1736 | 1757 |
| 1737 // Do not call or implement this function. Instead, use the form below that | 1758 // Do not call or implement this function. Instead, use the form below that |
| 1738 // uses an offset from the frame pointer instead of an Address. | 1759 // uses an offset from the frame pointer instead of an Address. |
| 1739 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { | 1760 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { |
| 1740 UNREACHABLE(); | 1761 UNREACHABLE(); |
| 1741 } | 1762 } |
| 1742 | 1763 |
| 1743 | 1764 |
| 1744 // Do not call or implement this function. Instead, use the form below that | 1765 // Do not call or implement this function. Instead, use the form below that |
| 1745 // uses offsets from the frame pointer instead of Addresses. | 1766 // uses offsets from the frame pointer instead of Addresses. |
| 1746 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1767 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1747 UNREACHABLE(); | 1768 UNREACHABLE(); |
| 1748 } | 1769 } |
| 1749 | 1770 |
| 1750 | 1771 |
| 1751 void ParallelMoveResolver::Exchange(Register reg, intptr_t stack_offset) { | 1772 void ParallelMoveResolver::Exchange(Register reg, |
| 1752 __ mov(TMP, Operand(reg)); | 1773 Register base_reg, |
| 1753 __ LoadFromOffset(kWord, reg, FP, stack_offset); | 1774 intptr_t stack_offset) { |
| 1754 __ StoreToOffset(kWord, TMP, FP, stack_offset); | 1775 ScratchRegisterScope tmp(this, kNoRegister); |
| 1776 __ mov(tmp.reg(), Operand(reg)); |
| 1777 __ LoadFromOffset(kWord, reg, base_reg, stack_offset); |
| 1778 __ StoreToOffset(kWord, tmp.reg(), base_reg, stack_offset); |
| 1755 } | 1779 } |
| 1756 | 1780 |
| 1757 | 1781 |
| 1758 void ParallelMoveResolver::Exchange(intptr_t stack_offset1, | 1782 void ParallelMoveResolver::Exchange(Register base_reg1, |
| 1783 intptr_t stack_offset1, |
| 1784 Register base_reg2, |
| 1759 intptr_t stack_offset2) { | 1785 intptr_t stack_offset2) { |
| 1760 ScratchRegisterScope ensure_scratch(this, IP); | 1786 ScratchRegisterScope tmp1(this, kNoRegister); |
| 1761 __ LoadFromOffset(kWord, ensure_scratch.reg(), FP, stack_offset1); | 1787 ScratchRegisterScope tmp2(this, tmp1.reg()); |
| 1762 __ LoadFromOffset(kWord, TMP, FP, stack_offset2); | 1788 __ LoadFromOffset(kWord, tmp1.reg(), base_reg1, stack_offset1); |
| 1763 __ StoreToOffset(kWord, ensure_scratch.reg(), FP, stack_offset2); | 1789 __ LoadFromOffset(kWord, tmp2.reg(), base_reg2, stack_offset2); |
| 1764 __ StoreToOffset(kWord, TMP, FP, stack_offset1); | 1790 __ StoreToOffset(kWord, tmp1.reg(), base_reg2, stack_offset2); |
| 1791 __ StoreToOffset(kWord, tmp2.reg(), base_reg1, stack_offset1); |
| 1765 } | 1792 } |
| 1766 | 1793 |
| 1767 | 1794 |
| 1768 void ParallelMoveResolver::SpillScratch(Register reg) { | 1795 void ParallelMoveResolver::SpillScratch(Register reg) { |
| 1769 __ Push(reg); | 1796 __ Push(reg); |
| 1770 } | 1797 } |
| 1771 | 1798 |
| 1772 | 1799 |
| 1773 void ParallelMoveResolver::RestoreScratch(Register reg) { | 1800 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| 1774 __ Pop(reg); | 1801 __ Pop(reg); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1785 DRegister dreg = EvenDRegisterOf(reg); | 1812 DRegister dreg = EvenDRegisterOf(reg); |
| 1786 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); | 1813 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); |
| 1787 } | 1814 } |
| 1788 | 1815 |
| 1789 | 1816 |
| 1790 #undef __ | 1817 #undef __ |
| 1791 | 1818 |
| 1792 } // namespace dart | 1819 } // namespace dart |
| 1793 | 1820 |
| 1794 #endif // defined TARGET_ARCH_ARM | 1821 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |