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 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1508 MoveOperands* move = moves_[index]; | 1508 MoveOperands* move = moves_[index]; |
| 1509 const Location source = move->src(); | 1509 const Location source = move->src(); |
| 1510 const Location destination = move->dest(); | 1510 const Location destination = move->dest(); |
| 1511 | 1511 |
| 1512 if (source.IsRegister()) { | 1512 if (source.IsRegister()) { |
| 1513 if (destination.IsRegister()) { | 1513 if (destination.IsRegister()) { |
| 1514 __ mov(destination.reg(), Operand(source.reg())); | 1514 __ mov(destination.reg(), Operand(source.reg())); |
| 1515 } else { | 1515 } else { |
| 1516 ASSERT(destination.IsStackSlot()); | 1516 ASSERT(destination.IsStackSlot()); |
| 1517 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1517 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1518 __ StoreToOffset(kWord, source.reg(), FP, dest_offset); | 1518 __ StoreToOffset( |
| 1519 kWord, source.reg(), destination.base_reg(), dest_offset); | |
| 1519 } | 1520 } |
| 1520 } else if (source.IsStackSlot()) { | 1521 } else if (source.IsStackSlot()) { |
| 1521 if (destination.IsRegister()) { | 1522 if (destination.IsRegister()) { |
| 1522 const intptr_t source_offset = source.ToStackSlotOffset(); | 1523 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1523 __ LoadFromOffset(kWord, destination.reg(), FP, source_offset); | 1524 __ LoadFromOffset( |
| 1525 kWord, destination.reg(), source.base_reg(), source_offset); | |
| 1524 } else { | 1526 } else { |
| 1525 ASSERT(destination.IsStackSlot()); | 1527 ASSERT(destination.IsStackSlot()); |
| 1526 const intptr_t source_offset = source.ToStackSlotOffset(); | 1528 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1527 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1529 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1528 __ LoadFromOffset(kWord, TMP, FP, source_offset); | 1530 __ LoadFromOffset(kWord, TMP, source.base_reg(), source_offset); |
| 1529 __ StoreToOffset(kWord, TMP, FP, dest_offset); | 1531 __ StoreToOffset(kWord, TMP, destination.base_reg(), dest_offset); |
| 1530 } | 1532 } |
| 1531 } else if (source.IsFpuRegister()) { | 1533 } else if (source.IsFpuRegister()) { |
| 1532 if (destination.IsFpuRegister()) { | 1534 if (destination.IsFpuRegister()) { |
| 1533 if (TargetCPUFeatures::neon_supported()) { | 1535 if (TargetCPUFeatures::neon_supported()) { |
| 1534 __ vmovq(destination.fpu_reg(), source.fpu_reg()); | 1536 __ vmovq(destination.fpu_reg(), source.fpu_reg()); |
| 1535 } else { | 1537 } else { |
| 1536 // If we're not inlining simd values, then only the even numbered D | 1538 // If we're not inlining simd values, then only the even numbered D |
| 1537 // register will have anything in them. | 1539 // register will have anything in them. |
| 1538 __ vmovd(EvenDRegisterOf(destination.fpu_reg()), | 1540 __ vmovd(EvenDRegisterOf(destination.fpu_reg()), |
| 1539 EvenDRegisterOf(source.fpu_reg())); | 1541 EvenDRegisterOf(source.fpu_reg())); |
| 1540 } | 1542 } |
| 1541 } else { | 1543 } else { |
| 1542 if (destination.IsDoubleStackSlot()) { | 1544 if (destination.IsDoubleStackSlot()) { |
| 1543 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1545 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1544 DRegister src = EvenDRegisterOf(source.fpu_reg()); | 1546 DRegister src = EvenDRegisterOf(source.fpu_reg()); |
| 1545 __ StoreDToOffset(src, FP, dest_offset); | 1547 __ StoreDToOffset(src, destination.base_reg(), dest_offset); |
| 1546 } else { | 1548 } else { |
| 1547 ASSERT(destination.IsQuadStackSlot()); | 1549 ASSERT(destination.IsQuadStackSlot()); |
| 1548 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1550 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1549 const DRegister dsrc0 = EvenDRegisterOf(source.fpu_reg()); | 1551 const DRegister dsrc0 = EvenDRegisterOf(source.fpu_reg()); |
| 1550 __ StoreMultipleDToOffset(dsrc0, 2, FP, dest_offset); | 1552 __ StoreMultipleDToOffset( |
| 1553 dsrc0, 2, destination.base_reg(), dest_offset); | |
| 1551 } | 1554 } |
| 1552 } | 1555 } |
| 1553 } else if (source.IsDoubleStackSlot()) { | 1556 } else if (source.IsDoubleStackSlot()) { |
| 1554 if (destination.IsFpuRegister()) { | 1557 if (destination.IsFpuRegister()) { |
| 1555 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1558 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1556 const DRegister dst = EvenDRegisterOf(destination.fpu_reg()); | 1559 const DRegister dst = EvenDRegisterOf(destination.fpu_reg()); |
| 1557 __ LoadDFromOffset(dst, FP, dest_offset); | 1560 __ LoadDFromOffset(dst, source.base_reg(), source_offset); |
| 1558 } else { | 1561 } else { |
| 1559 ASSERT(destination.IsDoubleStackSlot()); | 1562 ASSERT(destination.IsDoubleStackSlot()); |
| 1560 const intptr_t source_offset = source.ToStackSlotOffset(); | 1563 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1561 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1564 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1562 __ LoadDFromOffset(DTMP, FP, source_offset); | 1565 __ LoadDFromOffset(DTMP, source.base_reg(), source_offset); |
| 1563 __ StoreDToOffset(DTMP, FP, dest_offset); | 1566 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1564 } | 1567 } |
| 1565 } else if (source.IsQuadStackSlot()) { | 1568 } else if (source.IsQuadStackSlot()) { |
| 1566 if (destination.IsFpuRegister()) { | 1569 if (destination.IsFpuRegister()) { |
| 1567 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1570 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1568 const DRegister dst0 = EvenDRegisterOf(destination.fpu_reg()); | 1571 const DRegister dst0 = EvenDRegisterOf(destination.fpu_reg()); |
| 1569 __ LoadMultipleDFromOffset(dst0, 2, FP, dest_offset); | 1572 __ LoadMultipleDFromOffset(dst0, 2, source.base_reg(), source_offset); |
| 1570 } else { | 1573 } else { |
| 1571 ASSERT(destination.IsQuadStackSlot()); | 1574 ASSERT(destination.IsQuadStackSlot()); |
| 1572 const intptr_t source_offset = source.ToStackSlotOffset(); | 1575 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1573 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1576 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1574 const DRegister dtmp0 = DTMP; | 1577 const DRegister dtmp0 = DTMP; |
| 1575 __ LoadMultipleDFromOffset(dtmp0, 2, FP, source_offset); | 1578 __ LoadMultipleDFromOffset(dtmp0, 2, source.base_reg(), source_offset); |
| 1576 __ StoreMultipleDToOffset(dtmp0, 2, FP, dest_offset); | 1579 __ StoreMultipleDToOffset(dtmp0, 2, destination.base_reg(), dest_offset); |
| 1577 } | 1580 } |
| 1578 } else { | 1581 } else { |
| 1579 ASSERT(source.IsConstant()); | 1582 ASSERT(source.IsConstant()); |
| 1580 const Object& constant = source.constant(); | 1583 const Object& constant = source.constant(); |
| 1581 if (destination.IsRegister()) { | 1584 if (destination.IsRegister()) { |
| 1582 if (source.constant_instruction()->representation() == kUnboxedInt32) { | 1585 if (source.constant_instruction()->representation() == kUnboxedInt32) { |
| 1583 __ LoadImmediate(destination.reg(), Smi::Cast(constant).Value()); | 1586 __ LoadImmediate(destination.reg(), Smi::Cast(constant).Value()); |
| 1584 } else { | 1587 } else { |
| 1585 __ LoadObject(destination.reg(), constant); | 1588 __ LoadObject(destination.reg(), constant); |
| 1586 } | 1589 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1598 } else if (destination.IsDoubleStackSlot()) { | 1601 } else if (destination.IsDoubleStackSlot()) { |
| 1599 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0) && | 1602 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0) && |
| 1600 TargetCPUFeatures::neon_supported()) { | 1603 TargetCPUFeatures::neon_supported()) { |
| 1601 __ veorq(QTMP, QTMP, QTMP); | 1604 __ veorq(QTMP, QTMP, QTMP); |
| 1602 } else { | 1605 } else { |
| 1603 __ LoadObject(TMP, constant); | 1606 __ LoadObject(TMP, constant); |
| 1604 __ AddImmediate(TMP, TMP, Double::value_offset() - kHeapObjectTag); | 1607 __ AddImmediate(TMP, TMP, Double::value_offset() - kHeapObjectTag); |
| 1605 __ vldrd(DTMP, Address(TMP, 0)); | 1608 __ vldrd(DTMP, Address(TMP, 0)); |
| 1606 } | 1609 } |
| 1607 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1610 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1608 __ StoreDToOffset(DTMP, FP, dest_offset); | 1611 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1609 } else { | 1612 } else { |
| 1610 ASSERT(destination.IsStackSlot()); | 1613 ASSERT(destination.IsStackSlot()); |
| 1611 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1614 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1612 if (source.constant_instruction()->representation() == kUnboxedInt32) { | 1615 if (source.constant_instruction()->representation() == kUnboxedInt32) { |
| 1613 __ LoadImmediate(TMP, Smi::Cast(constant).Value()); | 1616 __ LoadImmediate(TMP, Smi::Cast(constant).Value()); |
| 1614 } else { | 1617 } else { |
| 1615 __ LoadObject(TMP, constant); | 1618 __ LoadObject(TMP, constant); |
| 1616 } | 1619 } |
| 1617 __ StoreToOffset(kWord, TMP, FP, dest_offset); | 1620 __ StoreToOffset(kWord, TMP, destination.base_reg(), dest_offset); |
| 1618 } | 1621 } |
| 1619 } | 1622 } |
| 1620 | 1623 |
| 1621 move->Eliminate(); | 1624 move->Eliminate(); |
| 1622 } | 1625 } |
| 1623 | 1626 |
| 1624 | 1627 |
| 1625 void ParallelMoveResolver::EmitSwap(int index) { | 1628 void ParallelMoveResolver::EmitSwap(int index) { |
| 1626 MoveOperands* move = moves_[index]; | 1629 MoveOperands* move = moves_[index]; |
| 1627 const Location source = move->src(); | 1630 const Location source = move->src(); |
| 1628 const Location destination = move->dest(); | 1631 const Location destination = move->dest(); |
| 1629 | 1632 |
| 1630 if (source.IsRegister() && destination.IsRegister()) { | 1633 if (source.IsRegister() && destination.IsRegister()) { |
| 1631 ASSERT(source.reg() != IP); | 1634 ASSERT(source.reg() != IP); |
| 1632 ASSERT(destination.reg() != IP); | 1635 ASSERT(destination.reg() != IP); |
| 1633 __ mov(IP, Operand(source.reg())); | 1636 __ mov(IP, Operand(source.reg())); |
| 1634 __ mov(source.reg(), Operand(destination.reg())); | 1637 __ mov(source.reg(), Operand(destination.reg())); |
| 1635 __ mov(destination.reg(), Operand(IP)); | 1638 __ mov(destination.reg(), Operand(IP)); |
| 1636 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1639 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1637 Exchange(source.reg(), destination.ToStackSlotOffset()); | 1640 Exchange(source.reg(), |
| 1641 destination.base_reg(), destination.ToStackSlotOffset()); | |
| 1638 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1642 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1639 Exchange(destination.reg(), source.ToStackSlotOffset()); | 1643 Exchange(destination.reg(), |
| 1644 source.base_reg(), source.ToStackSlotOffset()); | |
| 1640 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1645 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1641 Exchange(source.ToStackSlotOffset(), destination.ToStackSlotOffset()); | 1646 Exchange(source.base_reg(), source.ToStackSlotOffset(), |
| 1647 destination.base_reg(), destination.ToStackSlotOffset()); | |
| 1642 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1648 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1643 const DRegister dst = EvenDRegisterOf(destination.fpu_reg()); | 1649 const DRegister dst = EvenDRegisterOf(destination.fpu_reg()); |
| 1644 DRegister src = EvenDRegisterOf(source.fpu_reg()); | 1650 DRegister src = EvenDRegisterOf(source.fpu_reg()); |
| 1645 __ vmovd(DTMP, src); | 1651 __ vmovd(DTMP, src); |
| 1646 __ vmovd(src, dst); | 1652 __ vmovd(src, dst); |
| 1647 __ vmovd(dst, DTMP); | 1653 __ vmovd(dst, DTMP); |
| 1648 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1654 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1649 ASSERT(destination.IsDoubleStackSlot() || | 1655 ASSERT(destination.IsDoubleStackSlot() || |
| 1650 destination.IsQuadStackSlot() || | 1656 destination.IsQuadStackSlot() || |
| 1651 source.IsDoubleStackSlot() || | 1657 source.IsDoubleStackSlot() || |
| 1652 source.IsQuadStackSlot()); | 1658 source.IsQuadStackSlot()); |
| 1653 bool double_width = destination.IsDoubleStackSlot() || | 1659 bool double_width = destination.IsDoubleStackSlot() || |
| 1654 source.IsDoubleStackSlot(); | 1660 source.IsDoubleStackSlot(); |
| 1655 QRegister qreg = source.IsFpuRegister() ? source.fpu_reg() | 1661 QRegister qreg = source.IsFpuRegister() ? source.fpu_reg() |
| 1656 : destination.fpu_reg(); | 1662 : destination.fpu_reg(); |
| 1657 DRegister reg = EvenDRegisterOf(qreg); | 1663 DRegister reg = EvenDRegisterOf(qreg); |
| 1664 Register base_reg = source.IsFpuRegister() | |
|
zra
2014/09/04 16:05:38
Not sure I follow what's going on here. Is there a
Florian Schneider
2014/09/04 16:17:24
This is just the case of FpuRegister/DoubleStackSl
| |
| 1665 ? destination.base_reg() | |
| 1666 : source.base_reg(); | |
| 1658 const intptr_t slot_offset = source.IsFpuRegister() | 1667 const intptr_t slot_offset = source.IsFpuRegister() |
| 1659 ? destination.ToStackSlotOffset() | 1668 ? destination.ToStackSlotOffset() |
| 1660 : source.ToStackSlotOffset(); | 1669 : source.ToStackSlotOffset(); |
| 1661 | 1670 |
| 1662 if (double_width) { | 1671 if (double_width) { |
| 1663 __ LoadDFromOffset(DTMP, FP, slot_offset); | 1672 __ LoadDFromOffset(DTMP, base_reg, slot_offset); |
| 1664 __ StoreDToOffset(reg, FP, slot_offset); | 1673 __ StoreDToOffset(reg, base_reg, slot_offset); |
| 1665 __ vmovd(reg, DTMP); | 1674 __ vmovd(reg, DTMP); |
| 1666 } else { | 1675 } else { |
| 1667 UNIMPLEMENTED(); | 1676 __ LoadMultipleDFromOffset(DTMP, 2, base_reg, slot_offset); |
| 1677 __ StoreMultipleDToOffset(reg, 2, base_reg, slot_offset); | |
| 1678 __ vmovq(qreg, QTMP); | |
| 1668 } | 1679 } |
| 1669 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { | 1680 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { |
| 1670 const intptr_t source_offset = source.ToStackSlotOffset(); | 1681 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1671 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1682 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1672 | 1683 |
| 1673 ScratchFpuRegisterScope ensure_scratch(this, QTMP); | 1684 ScratchFpuRegisterScope ensure_scratch(this, kNoQRegister); |
| 1674 DRegister scratch = EvenDRegisterOf(ensure_scratch.reg()); | 1685 DRegister scratch = EvenDRegisterOf(ensure_scratch.reg()); |
| 1675 __ LoadDFromOffset(DTMP, FP, source_offset); | 1686 __ LoadDFromOffset(DTMP, source.base_reg(), source_offset); |
| 1676 __ LoadDFromOffset(scratch, FP, dest_offset); | 1687 __ LoadDFromOffset(scratch, destination.base_reg(), dest_offset); |
| 1677 __ StoreDToOffset(DTMP, FP, dest_offset); | 1688 __ StoreDToOffset(DTMP, destination.base_reg(), dest_offset); |
| 1678 __ StoreDToOffset(scratch, FP, source_offset); | 1689 __ StoreDToOffset(scratch, destination.base_reg(), source_offset); |
| 1679 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { | 1690 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { |
| 1680 UNIMPLEMENTED(); | 1691 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1692 const intptr_t dest_offset = destination.ToStackSlotOffset(); | |
| 1693 | |
| 1694 ScratchFpuRegisterScope ensure_scratch(this, kNoQRegister); | |
| 1695 DRegister scratch = EvenDRegisterOf(ensure_scratch.reg()); | |
| 1696 __ LoadMultipleDFromOffset(DTMP, 2, source.base_reg(), source_offset); | |
| 1697 __ LoadMultipleDFromOffset(scratch, 2, destination.base_reg(), dest_offset); | |
| 1698 __ StoreMultipleDToOffset(DTMP, 2, destination.base_reg(), dest_offset); | |
| 1699 __ StoreMultipleDToOffset( | |
| 1700 scratch, 2, destination.base_reg(), source_offset); | |
| 1681 } else { | 1701 } else { |
| 1682 UNREACHABLE(); | 1702 UNREACHABLE(); |
| 1683 } | 1703 } |
| 1684 | 1704 |
| 1685 // The swap of source and destination has executed a move from source to | 1705 // The swap of source and destination has executed a move from source to |
| 1686 // destination. | 1706 // destination. |
| 1687 move->Eliminate(); | 1707 move->Eliminate(); |
| 1688 | 1708 |
| 1689 // Any unperformed (including pending) move with a source of either | 1709 // Any unperformed (including pending) move with a source of either |
| 1690 // this move's source or destination needs to have their source | 1710 // this move's source or destination needs to have their source |
| 1691 // changed to reflect the state of affairs after the swap. | 1711 // changed to reflect the state of affairs after the swap. |
| 1692 for (int i = 0; i < moves_.length(); ++i) { | 1712 for (int i = 0; i < moves_.length(); ++i) { |
| 1693 const MoveOperands& other_move = *moves_[i]; | 1713 const MoveOperands& other_move = *moves_[i]; |
| 1694 if (other_move.Blocks(source)) { | 1714 if (other_move.Blocks(source)) { |
| 1695 moves_[i]->set_src(destination); | 1715 moves_[i]->set_src(destination); |
| 1696 } else if (other_move.Blocks(destination)) { | 1716 } else if (other_move.Blocks(destination)) { |
| 1697 moves_[i]->set_src(source); | 1717 moves_[i]->set_src(source); |
| 1698 } | 1718 } |
| 1699 } | 1719 } |
| 1700 } | 1720 } |
| 1701 | 1721 |
| 1702 | 1722 |
| 1703 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, | 1723 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, |
| 1704 const Address& src) { | 1724 const Address& src) { |
| 1705 __ ldr(IP, src); | 1725 UNREACHABLE(); |
| 1706 __ str(IP, dst); | |
| 1707 } | 1726 } |
| 1708 | 1727 |
| 1709 | 1728 |
| 1710 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { | 1729 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { |
| 1711 __ LoadObject(IP, obj); | 1730 UNREACHABLE(); |
| 1712 __ str(IP, dst); | |
| 1713 } | 1731 } |
| 1714 | 1732 |
| 1715 | 1733 |
| 1716 // Do not call or implement this function. Instead, use the form below that | 1734 // Do not call or implement this function. Instead, use the form below that |
| 1717 // uses an offset from the frame pointer instead of an Address. | 1735 // uses an offset from the frame pointer instead of an Address. |
| 1718 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { | 1736 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { |
| 1719 UNREACHABLE(); | 1737 UNREACHABLE(); |
| 1720 } | 1738 } |
| 1721 | 1739 |
| 1722 | 1740 |
| 1723 // Do not call or implement this function. Instead, use the form below that | 1741 // Do not call or implement this function. Instead, use the form below that |
| 1724 // uses offsets from the frame pointer instead of Addresses. | 1742 // uses offsets from the frame pointer instead of Addresses. |
| 1725 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1743 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1726 UNREACHABLE(); | 1744 UNREACHABLE(); |
| 1727 } | 1745 } |
| 1728 | 1746 |
| 1729 | 1747 |
| 1730 void ParallelMoveResolver::Exchange(Register reg, intptr_t stack_offset) { | 1748 void ParallelMoveResolver::Exchange(Register reg, |
| 1731 __ mov(TMP, Operand(reg)); | 1749 Register base_reg, |
| 1732 __ LoadFromOffset(kWord, reg, FP, stack_offset); | 1750 intptr_t stack_offset) { |
| 1733 __ StoreToOffset(kWord, TMP, FP, stack_offset); | 1751 ScratchRegisterScope tmp(this, reg); |
| 1752 __ mov(tmp.reg(), Operand(reg)); | |
| 1753 __ LoadFromOffset(kWord, reg, base_reg, stack_offset); | |
| 1754 __ StoreToOffset(kWord, tmp.reg(), base_reg, stack_offset); | |
| 1734 } | 1755 } |
| 1735 | 1756 |
| 1736 | 1757 |
| 1737 void ParallelMoveResolver::Exchange(intptr_t stack_offset1, | 1758 void ParallelMoveResolver::Exchange(Register base_reg1, |
| 1759 intptr_t stack_offset1, | |
| 1760 Register base_reg2, | |
| 1738 intptr_t stack_offset2) { | 1761 intptr_t stack_offset2) { |
| 1739 ScratchRegisterScope ensure_scratch(this, IP); | 1762 ScratchRegisterScope tmp1(this, kNoRegister); |
| 1740 __ LoadFromOffset(kWord, ensure_scratch.reg(), FP, stack_offset1); | 1763 ScratchRegisterScope tmp2(this, tmp1.reg()); |
| 1741 __ LoadFromOffset(kWord, TMP, FP, stack_offset2); | 1764 __ LoadFromOffset(kWord, tmp1.reg(), base_reg1, stack_offset1); |
| 1742 __ StoreToOffset(kWord, ensure_scratch.reg(), FP, stack_offset2); | 1765 __ LoadFromOffset(kWord, tmp2.reg(), base_reg2, stack_offset2); |
| 1743 __ StoreToOffset(kWord, TMP, FP, stack_offset1); | 1766 __ StoreToOffset(kWord, tmp1.reg(), base_reg2, stack_offset2); |
| 1767 __ StoreToOffset(kWord, tmp2.reg(), base_reg1, stack_offset1); | |
| 1744 } | 1768 } |
| 1745 | 1769 |
| 1746 | 1770 |
| 1747 void ParallelMoveResolver::SpillScratch(Register reg) { | 1771 void ParallelMoveResolver::SpillScratch(Register reg) { |
| 1748 __ Push(reg); | 1772 __ Push(reg); |
| 1749 } | 1773 } |
| 1750 | 1774 |
| 1751 | 1775 |
| 1752 void ParallelMoveResolver::RestoreScratch(Register reg) { | 1776 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| 1753 __ Pop(reg); | 1777 __ Pop(reg); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1764 DRegister dreg = EvenDRegisterOf(reg); | 1788 DRegister dreg = EvenDRegisterOf(reg); |
| 1765 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); | 1789 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); |
| 1766 } | 1790 } |
| 1767 | 1791 |
| 1768 | 1792 |
| 1769 #undef __ | 1793 #undef __ |
| 1770 | 1794 |
| 1771 } // namespace dart | 1795 } // namespace dart |
| 1772 | 1796 |
| 1773 #endif // defined TARGET_ARCH_ARM | 1797 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |