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