| 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 bool FlowGraphCompiler::SupportsUnboxedSimd128() { | 48 bool FlowGraphCompiler::SupportsUnboxedSimd128() { |
| 49 return FLAG_enable_simd_inline; | 49 return FLAG_enable_simd_inline; |
| 50 } | 50 } |
| 51 | 51 |
| 52 | 52 |
| 53 bool FlowGraphCompiler::SupportsSinCos() { | 53 bool FlowGraphCompiler::SupportsSinCos() { |
| 54 return false; | 54 return false; |
| 55 } | 55 } |
| 56 | 56 |
| 57 | 57 |
| 58 void FlowGraphCompiler::EnterIntrinsicMode() { |
| 59 ASSERT(!intrinsic_mode()); |
| 60 intrinsic_mode_ = true; |
| 61 assembler()->set_allow_constant_pool(false); |
| 62 } |
| 63 |
| 64 |
| 65 void FlowGraphCompiler::ExitIntrinsicMode() { |
| 66 ASSERT(intrinsic_mode()); |
| 67 intrinsic_mode_ = false; |
| 68 assembler()->set_allow_constant_pool(true); |
| 69 } |
| 70 |
| 71 |
| 58 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, | 72 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
| 59 DeoptInfoBuilder* builder, | 73 DeoptInfoBuilder* builder, |
| 60 const Array& deopt_table) { | 74 const Array& deopt_table) { |
| 61 if (deopt_env_ == NULL) { | 75 if (deopt_env_ == NULL) { |
| 62 return DeoptInfo::null(); | 76 return DeoptInfo::null(); |
| 63 } | 77 } |
| 64 | 78 |
| 65 intptr_t stack_height = compiler->StackSize(); | 79 intptr_t stack_height = compiler->StackSize(); |
| 66 AllocateIncomingParametersRecursive(deopt_env_, &stack_height); | 80 AllocateIncomingParametersRecursive(deopt_env_, &stack_height); |
| 67 | 81 |
| (...skipping 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 MoveOperands* move = moves_[index]; | 1528 MoveOperands* move = moves_[index]; |
| 1515 const Location source = move->src(); | 1529 const Location source = move->src(); |
| 1516 const Location destination = move->dest(); | 1530 const Location destination = move->dest(); |
| 1517 | 1531 |
| 1518 if (source.IsRegister()) { | 1532 if (source.IsRegister()) { |
| 1519 if (destination.IsRegister()) { | 1533 if (destination.IsRegister()) { |
| 1520 __ mov(destination.reg(), source.reg()); | 1534 __ mov(destination.reg(), source.reg()); |
| 1521 } else { | 1535 } else { |
| 1522 ASSERT(destination.IsStackSlot()); | 1536 ASSERT(destination.IsStackSlot()); |
| 1523 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1537 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1524 __ StoreToOffset(source.reg(), FP, dest_offset, PP); | 1538 __ StoreToOffset(source.reg(), destination.base_reg(), dest_offset, PP); |
| 1525 } | 1539 } |
| 1526 } else if (source.IsStackSlot()) { | 1540 } else if (source.IsStackSlot()) { |
| 1527 if (destination.IsRegister()) { | 1541 if (destination.IsRegister()) { |
| 1528 const intptr_t source_offset = source.ToStackSlotOffset(); | 1542 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1529 __ LoadFromOffset(destination.reg(), FP, source_offset, PP); | 1543 __ LoadFromOffset( |
| 1544 destination.reg(), source.base_reg(), source_offset, PP); |
| 1530 } else { | 1545 } else { |
| 1531 ASSERT(destination.IsStackSlot()); | 1546 ASSERT(destination.IsStackSlot()); |
| 1532 const intptr_t source_offset = source.ToStackSlotOffset(); | 1547 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1533 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1548 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1534 __ LoadFromOffset(TMP, FP, source_offset, PP); | 1549 ScratchRegisterScope tmp(this, kNoRegister); |
| 1535 __ StoreToOffset(TMP, FP, dest_offset, PP); | 1550 __ LoadFromOffset(tmp.reg(), source.base_reg(), source_offset, PP); |
| 1551 __ StoreToOffset(tmp.reg(), destination.base_reg(), dest_offset, PP); |
| 1536 } | 1552 } |
| 1537 } else if (source.IsFpuRegister()) { | 1553 } else if (source.IsFpuRegister()) { |
| 1538 if (destination.IsFpuRegister()) { | 1554 if (destination.IsFpuRegister()) { |
| 1539 __ vmov(destination.fpu_reg(), source.fpu_reg()); | 1555 __ vmov(destination.fpu_reg(), source.fpu_reg()); |
| 1540 } else { | 1556 } else { |
| 1541 if (destination.IsDoubleStackSlot()) { | 1557 if (destination.IsDoubleStackSlot()) { |
| 1542 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1558 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1543 VRegister src = source.fpu_reg(); | 1559 VRegister src = source.fpu_reg(); |
| 1544 __ StoreDToOffset(src, FP, dest_offset, PP); | 1560 __ StoreDToOffset(src, destination.base_reg(), dest_offset, PP); |
| 1545 } else { | 1561 } else { |
| 1546 ASSERT(destination.IsQuadStackSlot()); | 1562 ASSERT(destination.IsQuadStackSlot()); |
| 1547 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1563 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1548 __ StoreQToOffset(source.fpu_reg(), FP, dest_offset, PP); | 1564 __ StoreQToOffset( |
| 1565 source.fpu_reg(), destination.base_reg(), dest_offset, PP); |
| 1549 } | 1566 } |
| 1550 } | 1567 } |
| 1551 } else if (source.IsDoubleStackSlot()) { | 1568 } else if (source.IsDoubleStackSlot()) { |
| 1552 if (destination.IsFpuRegister()) { | 1569 if (destination.IsFpuRegister()) { |
| 1553 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1570 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1554 const VRegister dst = destination.fpu_reg(); | 1571 const VRegister dst = destination.fpu_reg(); |
| 1555 __ LoadDFromOffset(dst, FP, dest_offset, PP); | 1572 __ LoadDFromOffset(dst, source.base_reg(), source_offset, PP); |
| 1556 } else { | 1573 } else { |
| 1557 ASSERT(destination.IsDoubleStackSlot()); | 1574 ASSERT(destination.IsDoubleStackSlot()); |
| 1558 const intptr_t source_offset = source.ToStackSlotOffset(); | 1575 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1559 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1576 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1560 __ LoadDFromOffset(VTMP, FP, source_offset, PP); | 1577 __ LoadDFromOffset(VTMP, source.base_reg(), source_offset, PP); |
| 1561 __ StoreDToOffset(VTMP, FP, dest_offset, PP); | 1578 __ StoreDToOffset(VTMP, destination.base_reg(), dest_offset, PP); |
| 1562 } | 1579 } |
| 1563 } else if (source.IsQuadStackSlot()) { | 1580 } else if (source.IsQuadStackSlot()) { |
| 1564 if (destination.IsFpuRegister()) { | 1581 if (destination.IsFpuRegister()) { |
| 1565 const intptr_t dest_offset = source.ToStackSlotOffset(); | 1582 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1566 __ LoadQFromOffset(destination.fpu_reg(), FP, dest_offset, PP); | 1583 __ LoadQFromOffset( |
| 1584 destination.fpu_reg(), source.base_reg(), source_offset, PP); |
| 1567 } else { | 1585 } else { |
| 1568 ASSERT(destination.IsQuadStackSlot()); | 1586 ASSERT(destination.IsQuadStackSlot()); |
| 1569 const intptr_t source_offset = source.ToStackSlotOffset(); | 1587 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1570 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1588 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1571 __ LoadQFromOffset(VTMP, FP, source_offset, PP); | 1589 __ LoadQFromOffset(VTMP, source.base_reg(), source_offset, PP); |
| 1572 __ StoreQToOffset(VTMP, FP, dest_offset, PP); | 1590 __ StoreQToOffset(VTMP, destination.base_reg(), dest_offset, PP); |
| 1573 } | 1591 } |
| 1574 } else { | 1592 } else { |
| 1575 ASSERT(source.IsConstant()); | 1593 ASSERT(source.IsConstant()); |
| 1576 const Object& constant = source.constant(); | 1594 const Object& constant = source.constant(); |
| 1577 if (destination.IsRegister()) { | 1595 if (destination.IsRegister()) { |
| 1578 __ LoadObject(destination.reg(), constant, PP); | 1596 __ LoadObject(destination.reg(), constant, PP); |
| 1579 } else if (destination.IsFpuRegister()) { | 1597 } else if (destination.IsFpuRegister()) { |
| 1580 const VRegister dst = destination.fpu_reg(); | 1598 const VRegister dst = destination.fpu_reg(); |
| 1581 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) { | 1599 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) { |
| 1582 __ veor(dst, dst, dst); | 1600 __ veor(dst, dst, dst); |
| 1583 } else { | 1601 } else { |
| 1584 __ LoadObject(TMP, constant, PP); | 1602 ScratchRegisterScope tmp(this, kNoRegister); |
| 1585 __ LoadDFieldFromOffset(dst, TMP, Double::value_offset(), PP); | 1603 __ LoadObject(tmp.reg(), constant, PP); |
| 1604 __ LoadDFieldFromOffset(dst, tmp.reg(), Double::value_offset(), PP); |
| 1586 } | 1605 } |
| 1587 } else if (destination.IsDoubleStackSlot()) { | 1606 } else if (destination.IsDoubleStackSlot()) { |
| 1588 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) { | 1607 if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) { |
| 1589 __ veor(VTMP, VTMP, VTMP); | 1608 __ veor(VTMP, VTMP, VTMP); |
| 1590 } else { | 1609 } else { |
| 1591 __ LoadObject(TMP, constant, PP); | 1610 ScratchRegisterScope tmp(this, kNoRegister); |
| 1592 __ LoadDFieldFromOffset(VTMP, TMP, Double::value_offset(), PP); | 1611 __ LoadObject(tmp.reg(), constant, PP); |
| 1612 __ LoadDFieldFromOffset(VTMP, tmp.reg(), Double::value_offset(), PP); |
| 1593 } | 1613 } |
| 1594 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1614 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1595 __ StoreDToOffset(VTMP, FP, dest_offset, PP); | 1615 __ StoreDToOffset(VTMP, destination.base_reg(), dest_offset, PP); |
| 1596 } else { | 1616 } else { |
| 1597 ASSERT(destination.IsStackSlot()); | 1617 ASSERT(destination.IsStackSlot()); |
| 1598 const intptr_t dest_offset = destination.ToStackSlotOffset(); | 1618 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1599 __ LoadObject(TMP, constant, PP); | 1619 ScratchRegisterScope tmp(this, kNoRegister); |
| 1600 __ StoreToOffset(TMP, FP, dest_offset, PP); | 1620 __ LoadObject(tmp.reg(), constant, PP); |
| 1621 __ StoreToOffset(tmp.reg(), destination.base_reg(), dest_offset, PP); |
| 1601 } | 1622 } |
| 1602 } | 1623 } |
| 1603 | 1624 |
| 1604 move->Eliminate(); | 1625 move->Eliminate(); |
| 1605 } | 1626 } |
| 1606 | 1627 |
| 1607 | 1628 |
| 1608 void ParallelMoveResolver::EmitSwap(int index) { | 1629 void ParallelMoveResolver::EmitSwap(int index) { |
| 1609 MoveOperands* move = moves_[index]; | 1630 MoveOperands* move = moves_[index]; |
| 1610 const Location source = move->src(); | 1631 const Location source = move->src(); |
| 1611 const Location destination = move->dest(); | 1632 const Location destination = move->dest(); |
| 1612 | 1633 |
| 1613 if (source.IsRegister() && destination.IsRegister()) { | 1634 if (source.IsRegister() && destination.IsRegister()) { |
| 1614 ASSERT(source.reg() != TMP); | 1635 ASSERT(source.reg() != TMP); |
| 1615 ASSERT(destination.reg() != TMP); | 1636 ASSERT(destination.reg() != TMP); |
| 1616 __ mov(TMP, source.reg()); | 1637 __ mov(TMP, source.reg()); |
| 1617 __ mov(source.reg(), destination.reg()); | 1638 __ mov(source.reg(), destination.reg()); |
| 1618 __ mov(destination.reg(), TMP); | 1639 __ mov(destination.reg(), TMP); |
| 1619 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1640 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1620 Exchange(source.reg(), destination.ToStackSlotOffset()); | 1641 Exchange(source.reg(), |
| 1642 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1621 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1643 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1622 Exchange(destination.reg(), source.ToStackSlotOffset()); | 1644 Exchange(destination.reg(), |
| 1645 source.base_reg(), source.ToStackSlotOffset()); |
| 1623 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1646 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1624 Exchange(source.ToStackSlotOffset(), destination.ToStackSlotOffset()); | 1647 Exchange(source.base_reg(), source.ToStackSlotOffset(), |
| 1648 destination.base_reg(), destination.ToStackSlotOffset()); |
| 1625 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1649 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1626 const VRegister dst = destination.fpu_reg(); | 1650 const VRegister dst = destination.fpu_reg(); |
| 1627 const VRegister src = source.fpu_reg(); | 1651 const VRegister src = source.fpu_reg(); |
| 1628 __ fmovdd(VTMP, src); | 1652 __ fmovdd(VTMP, src); |
| 1629 __ fmovdd(src, dst); | 1653 __ fmovdd(src, dst); |
| 1630 __ fmovdd(dst, VTMP); | 1654 __ fmovdd(dst, VTMP); |
| 1631 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1655 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1632 ASSERT(destination.IsDoubleStackSlot() || | 1656 ASSERT(destination.IsDoubleStackSlot() || |
| 1633 destination.IsQuadStackSlot() || | 1657 destination.IsQuadStackSlot() || |
| 1634 source.IsDoubleStackSlot() || | 1658 source.IsDoubleStackSlot() || |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1677 moves_[i]->set_src(destination); | 1701 moves_[i]->set_src(destination); |
| 1678 } else if (other_move.Blocks(destination)) { | 1702 } else if (other_move.Blocks(destination)) { |
| 1679 moves_[i]->set_src(source); | 1703 moves_[i]->set_src(source); |
| 1680 } | 1704 } |
| 1681 } | 1705 } |
| 1682 } | 1706 } |
| 1683 | 1707 |
| 1684 | 1708 |
| 1685 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, | 1709 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, |
| 1686 const Address& src) { | 1710 const Address& src) { |
| 1687 UNIMPLEMENTED(); | 1711 UNREACHABLE(); |
| 1688 } | 1712 } |
| 1689 | 1713 |
| 1690 | 1714 |
| 1691 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { | 1715 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { |
| 1692 UNIMPLEMENTED(); | 1716 UNREACHABLE(); |
| 1693 } | 1717 } |
| 1694 | 1718 |
| 1695 | 1719 |
| 1696 // Do not call or implement this function. Instead, use the form below that | 1720 // Do not call or implement this function. Instead, use the form below that |
| 1697 // uses an offset from the frame pointer instead of an Address. | 1721 // uses an offset from the frame pointer instead of an Address. |
| 1698 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { | 1722 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { |
| 1699 UNREACHABLE(); | 1723 UNREACHABLE(); |
| 1700 } | 1724 } |
| 1701 | 1725 |
| 1702 | 1726 |
| 1703 // Do not call or implement this function. Instead, use the form below that | 1727 // Do not call or implement this function. Instead, use the form below that |
| 1704 // uses offsets from the frame pointer instead of Addresses. | 1728 // uses offsets from the frame pointer instead of Addresses. |
| 1705 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1729 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1706 UNREACHABLE(); | 1730 UNREACHABLE(); |
| 1707 } | 1731 } |
| 1708 | 1732 |
| 1709 | 1733 |
| 1710 void ParallelMoveResolver::Exchange(Register reg, intptr_t stack_offset) { | 1734 void ParallelMoveResolver::Exchange(Register reg, |
| 1711 UNIMPLEMENTED(); | 1735 Register base_reg, |
| 1736 intptr_t stack_offset) { |
| 1737 ScratchRegisterScope tmp(this, kNoRegister); |
| 1738 __ mov(tmp.reg(), reg); |
| 1739 __ LoadFromOffset(reg, base_reg, stack_offset, PP); |
| 1740 __ StoreToOffset(tmp.reg(), base_reg, stack_offset, PP); |
| 1712 } | 1741 } |
| 1713 | 1742 |
| 1714 | 1743 |
| 1715 void ParallelMoveResolver::Exchange(intptr_t stack_offset1, | 1744 void ParallelMoveResolver::Exchange(Register base_reg1, |
| 1745 intptr_t stack_offset1, |
| 1746 Register base_reg2, |
| 1716 intptr_t stack_offset2) { | 1747 intptr_t stack_offset2) { |
| 1717 UNIMPLEMENTED(); | 1748 ScratchRegisterScope tmp1(this, kNoRegister); |
| 1749 ScratchRegisterScope tmp2(this, tmp1.reg()); |
| 1750 __ LoadFromOffset(tmp1.reg(), base_reg1, stack_offset1, PP); |
| 1751 __ LoadFromOffset(tmp2.reg(), base_reg2, stack_offset2, PP); |
| 1752 __ StoreToOffset(tmp1.reg(), base_reg2, stack_offset2, PP); |
| 1753 __ StoreToOffset(tmp2.reg(), base_reg1, stack_offset1, PP); |
| 1718 } | 1754 } |
| 1719 | 1755 |
| 1720 | 1756 |
| 1721 void ParallelMoveResolver::SpillScratch(Register reg) { | 1757 void ParallelMoveResolver::SpillScratch(Register reg) { |
| 1722 UNIMPLEMENTED(); | 1758 __ Push(reg); |
| 1723 } | 1759 } |
| 1724 | 1760 |
| 1725 | 1761 |
| 1726 void ParallelMoveResolver::RestoreScratch(Register reg) { | 1762 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| 1727 UNIMPLEMENTED(); | 1763 __ Pop(reg); |
| 1728 } | 1764 } |
| 1729 | 1765 |
| 1730 | 1766 |
| 1731 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { | 1767 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { |
| 1732 UNIMPLEMENTED(); | 1768 __ PushDouble(reg); |
| 1733 } | 1769 } |
| 1734 | 1770 |
| 1735 | 1771 |
| 1736 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | 1772 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
| 1737 UNIMPLEMENTED(); | 1773 __ PopDouble(reg); |
| 1738 } | 1774 } |
| 1739 | 1775 |
| 1740 | 1776 |
| 1741 #undef __ | 1777 #undef __ |
| 1742 | 1778 |
| 1743 } // namespace dart | 1779 } // namespace dart |
| 1744 | 1780 |
| 1745 #endif // defined TARGET_ARCH_ARM64 | 1781 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |