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

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

Powered by Google App Engine
This is Rietveld 408576698