| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 1485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1496 MoveOperands* move = moves_[index]; | 1496 MoveOperands* move = moves_[index]; |
| 1497 const Location source = move->src(); | 1497 const Location source = move->src(); |
| 1498 const Location destination = move->dest(); | 1498 const Location destination = move->dest(); |
| 1499 | 1499 |
| 1500 if (source.IsRegister()) { | 1500 if (source.IsRegister()) { |
| 1501 if (destination.IsRegister()) { | 1501 if (destination.IsRegister()) { |
| 1502 __ mov(destination.reg(), source.reg()); | 1502 __ mov(destination.reg(), source.reg()); |
| 1503 } else { | 1503 } else { |
| 1504 ASSERT(destination.IsStackSlot()); | 1504 ASSERT(destination.IsStackSlot()); |
| 1505 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1505 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1506 __ StoreToOffset(source.reg(), FP, dest_offset, PP); | 1506 __ StoreToOffset(source.reg(), destination.base_reg(), dest_offset, PP); |
| 1507 } | 1507 } |
| 1508 } else if (source.IsStackSlot()) { | 1508 } else if (source.IsStackSlot()) { |
| 1509 if (destination.IsRegister()) { | 1509 if (destination.IsRegister()) { |
| 1510 const intptr_t source_offset = source.ToStackSlotOffset(); | 1510 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1511 __ LoadFromOffset(destination.reg(), FP, source_offset, PP); | 1511 __ LoadFromOffset( |
| 1512 destination.reg(), source.base_reg(), source_offset, PP); |
| 1512 } else { | 1513 } else { |
| 1513 ASSERT(destination.IsStackSlot()); | 1514 ASSERT(destination.IsStackSlot()); |
| 1514 const intptr_t source_offset = source.ToStackSlotOffset(); | 1515 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1515 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1516 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1516 __ LoadFromOffset(TMP, FP, source_offset, PP); | 1517 ScratchRegisterScope tmp(this, kNoRegister); |
| 1517 __ StoreToOffset(TMP, FP, dest_offset, PP); | 1518 __ LoadFromOffset(tmp.reg(), source.base_reg(), source_offset, PP); |
| 1519 __ StoreToOffset(tmp.reg(), destination.base_reg(), dest_offset, PP); |
| 1518 } | 1520 } |
| 1519 } else if (source.IsFpuRegister()) { | 1521 } else if (source.IsFpuRegister()) { |
| 1520 if (destination.IsFpuRegister()) { | 1522 if (destination.IsFpuRegister()) { |
| 1521 __ vmov(destination.fpu_reg(), source.fpu_reg()); | 1523 __ vmov(destination.fpu_reg(), source.fpu_reg()); |
| 1522 } else { | 1524 } else { |
| 1523 if (destination.IsDoubleStackSlot()) { | 1525 if (destination.IsDoubleStackSlot()) { |
| 1524 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1526 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1525 VRegister src = source.fpu_reg(); | 1527 VRegister src = source.fpu_reg(); |
| 1526 __ StoreDToOffset(src, FP, dest_offset, PP); | 1528 __ StoreDToOffset(src, destination.base_reg(), dest_offset, PP); |
| 1527 } else { | 1529 } else { |
| 1528 ASSERT(destination.IsQuadStackSlot()); | 1530 ASSERT(destination.IsQuadStackSlot()); |
| 1529 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1531 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1530 __ StoreQToOffset(source.fpu_reg(), FP, dest_offset, PP); | 1532 __ StoreQToOffset( |
| 1533 source.fpu_reg(), destination.base_reg(), dest_offset, PP); |
| 1531 } | 1534 } |
| 1532 } | 1535 } |
| 1533 } else if (source.IsDoubleStackSlot()) { | 1536 } else if (source.IsDoubleStackSlot()) { |
| 1534 if (destination.IsFpuRegister()) { | 1537 if (destination.IsFpuRegister()) { |
| 1535 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1538 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1536 const VRegister dst = destination.fpu_reg(); | 1539 const VRegister dst = destination.fpu_reg(); |
| 1537 __ LoadDFromOffset(dst, FP, dest_offset, PP); | 1540 __ LoadDFromOffset(dst, source.base_reg(), source_offset, PP); |
| 1538 } else { | 1541 } else { |
| 1539 ASSERT(destination.IsDoubleStackSlot()); | 1542 ASSERT(destination.IsDoubleStackSlot()); |
| 1540 const intptr_t source_offset = source.ToStackSlotOffset(); | 1543 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1541 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1544 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1542 __ LoadDFromOffset(VTMP, FP, source_offset, PP); | 1545 __ LoadDFromOffset(VTMP, source.base_reg(), source_offset, PP); |
| 1543 __ StoreDToOffset(VTMP, FP, dest_offset, PP); | 1546 __ StoreDToOffset(VTMP, destination.base_reg(), dest_offset, PP); |
| 1544 } | 1547 } |
| 1545 } else if (source.IsQuadStackSlot()) { | 1548 } else if (source.IsQuadStackSlot()) { |
| 1546 if (destination.IsFpuRegister()) { | 1549 if (destination.IsFpuRegister()) { |
| 1547 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1550 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1548 __ LoadQFromOffset(destination.fpu_reg(), FP, dest_offset, PP); | 1551 __ LoadQFromOffset( |
| 1552 destination.fpu_reg(), source.base_reg(), source_offset, PP); |
| 1549 } else { | 1553 } else { |
| 1550 ASSERT(destination.IsQuadStackSlot()); | 1554 ASSERT(destination.IsQuadStackSlot()); |
| 1551 const intptr_t source_offset = source.ToStackSlotOffset(); | 1555 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1552 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1556 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1553 __ LoadQFromOffset(VTMP, FP, source_offset, PP); | 1557 __ LoadQFromOffset(VTMP, source.base_reg(), source_offset, PP); |
| 1554 __ StoreQToOffset(VTMP, FP, dest_offset, PP); | 1558 __ StoreQToOffset(VTMP, destination.base_reg(), dest_offset, PP); |
| 1555 } | 1559 } |
| 1556 } else { | 1560 } else { |
| 1557 ASSERT(source.IsConstant()); | 1561 ASSERT(source.IsConstant()); |
| 1558 const Object& constant = source.constant(); | 1562 const Object& constant = source.constant(); |
| 1559 if (destination.IsRegister()) { | 1563 if (destination.IsRegister()) { |
| 1560 __ LoadObject(destination.reg(), constant, PP); | 1564 __ LoadObject(destination.reg(), constant, PP); |
| 1561 } else if (destination.IsFpuRegister()) { | 1565 } else if (destination.IsFpuRegister()) { |
| 1562 const VRegister dst = destination.fpu_reg(); | 1566 const VRegister dst = destination.fpu_reg(); |
| 1563 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) { | 1567 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) { |
| 1564 __ veor(dst, dst, dst); | 1568 __ veor(dst, dst, dst); |
| 1565 } else { | 1569 } else { |
| 1566 __ LoadObject(TMP, constant, PP); | 1570 ScratchRegisterScope tmp(this, kNoRegister); |
| 1567 __ LoadDFieldFromOffset(dst, TMP, Double::value_offset(), PP); | 1571 __ LoadObject(tmp.reg(), constant, PP); |
| 1572 __ LoadDFieldFromOffset(dst, tmp.reg(), Double::value_offset(), PP); |
| 1568 } | 1573 } |
| 1569 } else if (destination.IsDoubleStackSlot()) { | 1574 } else if (destination.IsDoubleStackSlot()) { |
| 1570 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) { | 1575 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) { |
| 1571 __ veor(VTMP, VTMP, VTMP); | 1576 __ veor(VTMP, VTMP, VTMP); |
| 1572 } else { | 1577 } else { |
| 1573 __ LoadObject(TMP, constant, PP); | 1578 ScratchRegisterScope tmp(this, kNoRegister); |
| 1574 __ LoadDFieldFromOffset(VTMP, TMP, Double::value_offset(), PP); | 1579 __ LoadObject(tmp.reg(), constant, PP); |
| 1580 __ LoadDFieldFromOffset(VTMP, tmp.reg(), Double::value_offset(), PP); |
| 1575 } | 1581 } |
| 1576 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1582 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1577 __ StoreDToOffset(VTMP, FP, dest_offset, PP); | 1583 __ StoreDToOffset(VTMP, destination.base_reg(), dest_offset, PP); |
| 1578 } else { | 1584 } else { |
| 1579 ASSERT(destination.IsStackSlot()); | 1585 ASSERT(destination.IsStackSlot()); |
| 1580 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1586 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1581 __ LoadObject(TMP, constant, PP); | 1587 ScratchRegisterScope tmp(this, kNoRegister); |
| 1582 __ StoreToOffset(TMP, FP, dest_offset, PP); | 1588 __ LoadObject(tmp.reg(), constant, PP); |
| 1589 __ StoreToOffset(tmp.reg(), destination.base_reg(), dest_offset, PP); |
| 1583 } | 1590 } |
| 1584 } | 1591 } |
| 1585 | 1592 |
| 1586 move->Eliminate(); | 1593 move->Eliminate(); |
| 1587 } | 1594 } |
| 1588 | 1595 |
| 1589 | 1596 |
| 1590 void ParallelMoveResolver::EmitSwap(int index) { | 1597 void ParallelMoveResolver::EmitSwap(int index) { |
| 1591 MoveOperands* move = moves_[index]; | 1598 MoveOperands* move = moves_[index]; |
| 1592 const Location source = move->src(); | 1599 const Location source = move->src(); |
| 1593 const Location destination = move->dest(); | 1600 const Location destination = move->dest(); |
| 1594 | 1601 |
| 1595 if (source.IsRegister() && destination.IsRegister()) { | 1602 if (source.IsRegister() && destination.IsRegister()) { |
| 1596 ASSERT(source.reg() != TMP); | 1603 ASSERT(source.reg() != TMP); |
| 1597 ASSERT(destination.reg() != TMP); | 1604 ASSERT(destination.reg() != TMP); |
| 1598 __ mov(TMP, source.reg()); | 1605 __ mov(TMP, source.reg()); |
| 1599 __ mov(source.reg(), destination.reg()); | 1606 __ mov(source.reg(), destination.reg()); |
| 1600 __ mov(destination.reg(), TMP); | 1607 __ mov(destination.reg(), TMP); |
| 1601 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1608 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1602 Exchange(source.reg(), destination.ToStackSlotOffset()); | 1609 Exchange(source.reg(), |
| 1610 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1603 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1611 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1604 Exchange(destination.reg(), source.ToStackSlotOffset()); | 1612 Exchange(destination.reg(), |
| 1613 source.base_reg(), source.ToStackSlotOffset()); |
| 1605 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1614 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1606 Exchange(source.ToStackSlotOffset(), destination.ToStackSlotOffset()); | 1615 Exchange(source.base_reg(), source.ToStackSlotOffset(), |
| 1616 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1607 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1617 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1608 const VRegister dst = destination.fpu_reg(); | 1618 const VRegister dst = destination.fpu_reg(); |
| 1609 const VRegister src = source.fpu_reg(); | 1619 const VRegister src = source.fpu_reg(); |
| 1610 __ fmovdd(VTMP, src); | 1620 __ fmovdd(VTMP, src); |
| 1611 __ fmovdd(src, dst); | 1621 __ fmovdd(src, dst); |
| 1612 __ fmovdd(dst, VTMP); | 1622 __ fmovdd(dst, VTMP); |
| 1613 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1623 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1614 ASSERT(destination.IsDoubleStackSlot() || | 1624 ASSERT(destination.IsDoubleStackSlot() || |
| 1615 destination.IsQuadStackSlot() || | 1625 destination.IsQuadStackSlot() || |
| 1616 source.IsDoubleStackSlot() || | 1626 source.IsDoubleStackSlot() || |
| 1617 source.IsQuadStackSlot()); | 1627 source.IsQuadStackSlot()); |
| 1618 bool double_width = destination.IsDoubleStackSlot() || | 1628 bool double_width = destination.IsDoubleStackSlot() || |
| 1619 source.IsDoubleStackSlot(); | 1629 source.IsDoubleStackSlot(); |
| 1620 VRegister reg = source.IsFpuRegister() ? source.fpu_reg() | 1630 VRegister reg = source.IsFpuRegister() ? source.fpu_reg() |
| 1621 : destination.fpu_reg(); | 1631 : destination.fpu_reg(); |
| 1632 Register base_reg = source.IsFpuRegister() |
| 1633 ? destination.base_reg() |
| 1634 : source.base_reg(); |
| 1622 const intptr_t slot_offset = source.IsFpuRegister() | 1635 const intptr_t slot_offset = source.IsFpuRegister() |
| 1623 ? destination.ToStackSlotOffset() | 1636 ? destination.ToStackSlotOffset() |
| 1624 : source.ToStackSlotOffset(); | 1637 : source.ToStackSlotOffset(); |
| 1625 | 1638 |
| 1626 if (double_width) { | 1639 if (double_width) { |
| 1627 __ LoadDFromOffset(VTMP, FP, slot_offset, PP); | 1640 __ LoadDFromOffset(VTMP, base_reg, slot_offset, PP); |
| 1628 __ StoreDToOffset(reg, FP, slot_offset, PP); | 1641 __ StoreDToOffset(reg, base_reg, slot_offset, PP); |
| 1629 __ fmovdd(reg, VTMP); | 1642 __ fmovdd(reg, VTMP); |
| 1630 } else { | 1643 } else { |
| 1631 UNIMPLEMENTED(); | 1644 __ LoadQFromOffset(VTMP, base_reg, slot_offset, PP); |
| 1645 __ StoreQToOffset(reg, base_reg, slot_offset, PP); |
| 1646 __ fmovdd(reg, VTMP); |
| 1632 } | 1647 } |
| 1633 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { | 1648 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { |
| 1634 const intptr_t source_offset = source.ToStackSlotOffset(); | 1649 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1635 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1650 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1636 | 1651 |
| 1637 ScratchFpuRegisterScope ensure_scratch(this, VTMP); | 1652 ScratchFpuRegisterScope ensure_scratch(this, kNoFpuRegister); |
| 1638 VRegister scratch = ensure_scratch.reg(); | 1653 VRegister scratch = ensure_scratch.reg(); |
| 1639 __ LoadDFromOffset(VTMP, FP, source_offset, PP); | 1654 __ LoadDFromOffset(VTMP, source.base_reg(), source_offset, PP); |
| 1640 __ LoadDFromOffset(scratch, FP, dest_offset, PP); | 1655 __ LoadDFromOffset(scratch, destination.base_reg(), dest_offset, PP); |
| 1641 __ StoreDToOffset(VTMP, FP, dest_offset, PP); | 1656 __ StoreDToOffset(VTMP, destination.base_reg(), dest_offset, PP); |
| 1642 __ StoreDToOffset(scratch, FP, source_offset, PP); | 1657 __ StoreDToOffset(scratch, source.base_reg(), source_offset, PP); |
| 1643 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { | 1658 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { |
| 1644 UNIMPLEMENTED(); | 1659 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1660 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1661 |
| 1662 ScratchFpuRegisterScope ensure_scratch(this, kNoFpuRegister); |
| 1663 VRegister scratch = ensure_scratch.reg(); |
| 1664 __ LoadQFromOffset(VTMP, source.base_reg(), source_offset, PP); |
| 1665 __ LoadQFromOffset(scratch, destination.base_reg(), dest_offset, PP); |
| 1666 __ StoreQToOffset(VTMP, destination.base_reg(), dest_offset, PP); |
| 1667 __ StoreQToOffset(scratch, source.base_reg(), source_offset, PP); |
| 1645 } else { | 1668 } else { |
| 1646 UNREACHABLE(); | 1669 UNREACHABLE(); |
| 1647 } | 1670 } |
| 1648 | 1671 |
| 1649 // The swap of source and destination has executed a move from source to | 1672 // The swap of source and destination has executed a move from source to |
| 1650 // destination. | 1673 // destination. |
| 1651 move->Eliminate(); | 1674 move->Eliminate(); |
| 1652 | 1675 |
| 1653 // Any unperformed (including pending) move with a source of either | 1676 // Any unperformed (including pending) move with a source of either |
| 1654 // this move's source or destination needs to have their source | 1677 // this move's source or destination needs to have their source |
| 1655 // changed to reflect the state of affairs after the swap. | 1678 // changed to reflect the state of affairs after the swap. |
| 1656 for (int i = 0; i < moves_.length(); ++i) { | 1679 for (int i = 0; i < moves_.length(); ++i) { |
| 1657 const MoveOperands& other_move = *moves_[i]; | 1680 const MoveOperands& other_move = *moves_[i]; |
| 1658 if (other_move.Blocks(source)) { | 1681 if (other_move.Blocks(source)) { |
| 1659 moves_[i]->set_src(destination); | 1682 moves_[i]->set_src(destination); |
| 1660 } else if (other_move.Blocks(destination)) { | 1683 } else if (other_move.Blocks(destination)) { |
| 1661 moves_[i]->set_src(source); | 1684 moves_[i]->set_src(source); |
| 1662 } | 1685 } |
| 1663 } | 1686 } |
| 1664 } | 1687 } |
| 1665 | 1688 |
| 1666 | 1689 |
| 1667 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, | 1690 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, |
| 1668 const Address& src) { | 1691 const Address& src) { |
| 1669 UNIMPLEMENTED(); | 1692 UNREACHABLE(); |
| 1670 } | 1693 } |
| 1671 | 1694 |
| 1672 | 1695 |
| 1673 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { | 1696 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { |
| 1674 UNIMPLEMENTED(); | 1697 UNREACHABLE(); |
| 1675 } | 1698 } |
| 1676 | 1699 |
| 1677 | 1700 |
| 1678 // Do not call or implement this function. Instead, use the form below that | 1701 // Do not call or implement this function. Instead, use the form below that |
| 1679 // uses an offset from the frame pointer instead of an Address. | 1702 // uses an offset from the frame pointer instead of an Address. |
| 1680 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { | 1703 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { |
| 1681 UNREACHABLE(); | 1704 UNREACHABLE(); |
| 1682 } | 1705 } |
| 1683 | 1706 |
| 1684 | 1707 |
| 1685 // Do not call or implement this function. Instead, use the form below that | 1708 // Do not call or implement this function. Instead, use the form below that |
| 1686 // uses offsets from the frame pointer instead of Addresses. | 1709 // uses offsets from the frame pointer instead of Addresses. |
| 1687 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1710 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1688 UNREACHABLE(); | 1711 UNREACHABLE(); |
| 1689 } | 1712 } |
| 1690 | 1713 |
| 1691 | 1714 |
| 1692 void ParallelMoveResolver::Exchange(Register reg, intptr_t stack_offset) { | 1715 void ParallelMoveResolver::Exchange(Register reg, |
| 1693 UNIMPLEMENTED(); | 1716 Register base_reg, |
| 1717 intptr_t stack_offset) { |
| 1718 ScratchRegisterScope tmp(this, reg); |
| 1719 __ mov(tmp.reg(), reg); |
| 1720 __ LoadFromOffset(reg, base_reg, stack_offset, PP); |
| 1721 __ StoreToOffset(tmp.reg(), base_reg, stack_offset, PP); |
| 1694 } | 1722 } |
| 1695 | 1723 |
| 1696 | 1724 |
| 1697 void ParallelMoveResolver::Exchange(intptr_t stack_offset1, | 1725 void ParallelMoveResolver::Exchange(Register base_reg1, |
| 1726 intptr_t stack_offset1, |
| 1727 Register base_reg2, |
| 1698 intptr_t stack_offset2) { | 1728 intptr_t stack_offset2) { |
| 1699 UNIMPLEMENTED(); | 1729 ScratchRegisterScope tmp1(this, kNoRegister); |
| 1730 ScratchRegisterScope tmp2(this, tmp1.reg()); |
| 1731 __ LoadFromOffset(tmp1.reg(), base_reg1, stack_offset1, PP); |
| 1732 __ LoadFromOffset(tmp2.reg(), base_reg2, stack_offset2, PP); |
| 1733 __ StoreToOffset(tmp1.reg(), base_reg2, stack_offset2, PP); |
| 1734 __ StoreToOffset(tmp2.reg(), base_reg1, stack_offset1, PP); |
| 1700 } | 1735 } |
| 1701 | 1736 |
| 1702 | 1737 |
| 1703 void ParallelMoveResolver::SpillScratch(Register reg) { | 1738 void ParallelMoveResolver::SpillScratch(Register reg) { |
| 1704 UNIMPLEMENTED(); | 1739 __ Push(reg); |
| 1705 } | 1740 } |
| 1706 | 1741 |
| 1707 | 1742 |
| 1708 void ParallelMoveResolver::RestoreScratch(Register reg) { | 1743 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| 1709 UNIMPLEMENTED(); | 1744 __ Pop(reg); |
| 1710 } | 1745 } |
| 1711 | 1746 |
| 1712 | 1747 |
| 1713 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { | 1748 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { |
| 1714 UNIMPLEMENTED(); | 1749 __ PushDouble(reg); |
| 1715 } | 1750 } |
| 1716 | 1751 |
| 1717 | 1752 |
| 1718 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | 1753 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
| 1719 UNIMPLEMENTED(); | 1754 __ PopDouble(reg); |
| 1720 } | 1755 } |
| 1721 | 1756 |
| 1722 | 1757 |
| 1723 #undef __ | 1758 #undef __ |
| 1724 | 1759 |
| 1725 } // namespace dart | 1760 } // namespace dart |
| 1726 | 1761 |
| 1727 #endif // defined TARGET_ARCH_ARM64 | 1762 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |