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

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

Powered by Google App Engine
This is Rietveld 408576698