Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: runtime/vm/flow_graph_compiler_arm.cc

Issue 513213002: Generate some intrinsics using our IR. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698