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

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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698