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

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

Issue 18684008: Begins implementation of ARM neon instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1500 1500
1501 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { 1501 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
1502 // TODO(vegorov): consider saving only caller save (volatile) registers. 1502 // TODO(vegorov): consider saving only caller save (volatile) registers.
1503 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count(); 1503 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count();
1504 if (fpu_regs_count > 0) { 1504 if (fpu_regs_count > 0) {
1505 __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize)); 1505 __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize));
1506 // Store fpu registers with the lowest register number at the lowest 1506 // Store fpu registers with the lowest register number at the lowest
1507 // address. 1507 // address.
1508 intptr_t offset = 0; 1508 intptr_t offset = 0;
1509 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { 1509 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) {
1510 DRegister fpu_reg = static_cast<DRegister>(reg_idx); 1510 QRegister fpu_reg = static_cast<QRegister>(reg_idx);
1511 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { 1511 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) {
1512 __ vstrd(fpu_reg, Address(SP, offset)); 1512 DRegister d1 = EvenDRegisterOf(fpu_reg);
1513 DRegister d2 = OddDRegisterOf(fpu_reg);
1514 __ vstrd(d1, Address(SP, offset));
1515 __ vstrd(d2, Address(SP, offset + 2 * kWordSize));
regis 2013/07/16 00:18:42 Fine for now, but you should add a TODO (my name i
1513 offset += kFpuRegisterSize; 1516 offset += kFpuRegisterSize;
1514 } 1517 }
1515 } 1518 }
1516 ASSERT(offset == (fpu_regs_count * kFpuRegisterSize)); 1519 ASSERT(offset == (fpu_regs_count * kFpuRegisterSize));
1517 } 1520 }
1518 1521
1519 // Store general purpose registers with the lowest register number at the 1522 // Store general purpose registers with the lowest register number at the
1520 // lowest address. 1523 // lowest address.
1521 const intptr_t cpu_registers = locs->live_registers()->cpu_registers(); 1524 const intptr_t cpu_registers = locs->live_registers()->cpu_registers();
1522 ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0); 1525 ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0);
(...skipping 10 matching lines...) Expand all
1533 ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0); 1536 ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0);
1534 if (cpu_registers != 0) { 1537 if (cpu_registers != 0) {
1535 __ PopList(cpu_registers); 1538 __ PopList(cpu_registers);
1536 } 1539 }
1537 1540
1538 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count(); 1541 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count();
1539 if (fpu_regs_count > 0) { 1542 if (fpu_regs_count > 0) {
1540 // Fpu registers have the lowest register number at the lowest address. 1543 // Fpu registers have the lowest register number at the lowest address.
1541 intptr_t offset = 0; 1544 intptr_t offset = 0;
1542 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { 1545 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) {
1543 DRegister fpu_reg = static_cast<DRegister>(reg_idx); 1546 QRegister fpu_reg = static_cast<QRegister>(reg_idx);
1544 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { 1547 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) {
1545 __ vldrd(fpu_reg, Address(SP, offset)); 1548 DRegister d1 = EvenDRegisterOf(fpu_reg);
1549 DRegister d2 = OddDRegisterOf(fpu_reg);
1550 __ vldrd(d1, Address(SP, offset));
1551 __ vldrd(d2, Address(SP, offset + 2 * kWordSize));
regis 2013/07/16 00:18:42 TODO(regis): Use vldm instruction.
1546 offset += kFpuRegisterSize; 1552 offset += kFpuRegisterSize;
1547 } 1553 }
1548 } 1554 }
1549 ASSERT(offset == (fpu_regs_count * kFpuRegisterSize)); 1555 ASSERT(offset == (fpu_regs_count * kFpuRegisterSize));
1550 __ AddImmediate(SP, offset); 1556 __ AddImmediate(SP, offset);
1551 } 1557 }
1552 } 1558 }
1553 1559
1554 1560
1555 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1561 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 } 1604 }
1599 assembler()->Bind(&match_found); 1605 assembler()->Bind(&match_found);
1600 } 1606 }
1601 1607
1602 1608
1603 void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition, 1609 void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition,
1604 FpuRegister left, 1610 FpuRegister left,
1605 FpuRegister right, 1611 FpuRegister right,
1606 BranchInstr* branch) { 1612 BranchInstr* branch) {
1607 ASSERT(branch != NULL); 1613 ASSERT(branch != NULL);
1608 assembler()->vcmpd(left, right); 1614 DRegister dleft = EvenDRegisterOf(left);
1615 DRegister dright = EvenDRegisterOf(right);
1616 assembler()->vcmpd(dleft, dright);
1609 assembler()->vmstat(); 1617 assembler()->vmstat();
1610 BlockEntryInstr* nan_result = (true_condition == NE) ? 1618 BlockEntryInstr* nan_result = (true_condition == NE) ?
1611 branch->true_successor() : branch->false_successor(); 1619 branch->true_successor() : branch->false_successor();
1612 assembler()->b(GetJumpLabel(nan_result), VS); 1620 assembler()->b(GetJumpLabel(nan_result), VS);
1613 branch->EmitBranchOnCondition(this, true_condition); 1621 branch->EmitBranchOnCondition(this, true_condition);
1614 } 1622 }
1615 1623
1616 1624
1617 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition, 1625 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition,
1618 FpuRegister left, 1626 FpuRegister left,
1619 FpuRegister right, 1627 FpuRegister right,
1620 Register result) { 1628 Register result) {
1621 assembler()->vcmpd(left, right); 1629 DRegister dleft = EvenDRegisterOf(left);
1630 DRegister dright = EvenDRegisterOf(right);
1631 assembler()->vcmpd(dleft, dright);
1622 assembler()->vmstat(); 1632 assembler()->vmstat();
1623 assembler()->LoadObject(result, Bool::False()); 1633 assembler()->LoadObject(result, Bool::False());
1624 Label done; 1634 Label done;
1625 assembler()->b(&done, VS); // NaN -> false. 1635 assembler()->b(&done, VS); // NaN -> false.
1626 assembler()->LoadObject(result, Bool::True(), true_condition); 1636 assembler()->LoadObject(result, Bool::True(), true_condition);
1627 assembler()->Bind(&done); 1637 assembler()->Bind(&done);
1628 } 1638 }
1629 1639
1630 1640
1631 // Do not implement or use this function. 1641 // Do not implement or use this function.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 } else if (source.IsStackSlot()) { 1695 } else if (source.IsStackSlot()) {
1686 if (destination.IsRegister()) { 1696 if (destination.IsRegister()) {
1687 __ ldr(destination.reg(), source.ToStackSlotAddress()); 1697 __ ldr(destination.reg(), source.ToStackSlotAddress());
1688 } else { 1698 } else {
1689 ASSERT(destination.IsStackSlot()); 1699 ASSERT(destination.IsStackSlot());
1690 MoveMemoryToMemory(destination.ToStackSlotAddress(), 1700 MoveMemoryToMemory(destination.ToStackSlotAddress(),
1691 source.ToStackSlotAddress()); 1701 source.ToStackSlotAddress());
1692 } 1702 }
1693 } else if (source.IsFpuRegister()) { 1703 } else if (source.IsFpuRegister()) {
1694 if (destination.IsFpuRegister()) { 1704 if (destination.IsFpuRegister()) {
1695 __ vmovd(destination.fpu_reg(), source.fpu_reg()); 1705 DRegister dst = EvenDRegisterOf(destination.fpu_reg());
1706 DRegister src = EvenDRegisterOf(source.fpu_reg());
1707 __ vmovd(dst, src);
1696 } else { 1708 } else {
1697 if (destination.IsDoubleStackSlot()) { 1709 if (destination.IsDoubleStackSlot()) {
1698 __ vstrd(source.fpu_reg(), destination.ToStackSlotAddress()); 1710 DRegister src = EvenDRegisterOf(source.fpu_reg());
1711 __ vstrd(src, destination.ToStackSlotAddress());
1699 } else { 1712 } else {
1700 ASSERT(destination.IsQuadStackSlot()); 1713 ASSERT(destination.IsQuadStackSlot());
1701 UNIMPLEMENTED(); 1714 UNIMPLEMENTED();
1702 } 1715 }
1703 } 1716 }
1704 } else if (source.IsDoubleStackSlot()) { 1717 } else if (source.IsDoubleStackSlot()) {
1705 if (destination.IsFpuRegister()) { 1718 if (destination.IsFpuRegister()) {
1706 __ vldrd(destination.fpu_reg(), source.ToStackSlotAddress()); 1719 DRegister dst = EvenDRegisterOf(destination.fpu_reg());
1720 __ vldrd(dst, source.ToStackSlotAddress());
1707 } else { 1721 } else {
1708 ASSERT(destination.IsDoubleStackSlot()); 1722 ASSERT(destination.IsDoubleStackSlot());
1709 __ vldrd(DTMP, source.ToStackSlotAddress()); 1723 __ vldrd(DTMP, source.ToStackSlotAddress());
1710 __ vstrd(DTMP, destination.ToStackSlotAddress()); 1724 __ vstrd(DTMP, destination.ToStackSlotAddress());
1711 } 1725 }
1712 } else if (source.IsQuadStackSlot()) { 1726 } else if (source.IsQuadStackSlot()) {
1713 UNIMPLEMENTED(); 1727 UNIMPLEMENTED();
1714 } else { 1728 } else {
1715 ASSERT(source.IsConstant()); 1729 ASSERT(source.IsConstant());
1716 if (destination.IsRegister()) { 1730 if (destination.IsRegister()) {
(...skipping 20 matching lines...) Expand all
1737 __ mov(IP, ShifterOperand(source.reg())); 1751 __ mov(IP, ShifterOperand(source.reg()));
1738 __ mov(source.reg(), ShifterOperand(destination.reg())); 1752 __ mov(source.reg(), ShifterOperand(destination.reg()));
1739 __ mov(destination.reg(), ShifterOperand(IP)); 1753 __ mov(destination.reg(), ShifterOperand(IP));
1740 } else if (source.IsRegister() && destination.IsStackSlot()) { 1754 } else if (source.IsRegister() && destination.IsStackSlot()) {
1741 Exchange(source.reg(), destination.ToStackSlotAddress()); 1755 Exchange(source.reg(), destination.ToStackSlotAddress());
1742 } else if (source.IsStackSlot() && destination.IsRegister()) { 1756 } else if (source.IsStackSlot() && destination.IsRegister()) {
1743 Exchange(destination.reg(), source.ToStackSlotAddress()); 1757 Exchange(destination.reg(), source.ToStackSlotAddress());
1744 } else if (source.IsStackSlot() && destination.IsStackSlot()) { 1758 } else if (source.IsStackSlot() && destination.IsStackSlot()) {
1745 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); 1759 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress());
1746 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { 1760 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
1747 __ vmovd(DTMP, source.fpu_reg()); 1761 DRegister dst = EvenDRegisterOf(destination.fpu_reg());
1748 __ vmovd(source.fpu_reg(), destination.fpu_reg()); 1762 DRegister src = EvenDRegisterOf(source.fpu_reg());
1749 __ vmovd(destination.fpu_reg(), DTMP); 1763 __ vmovd(DTMP, src);
1764 __ vmovd(src, dst);
1765 __ vmovd(dst, DTMP);
1750 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { 1766 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) {
1751 ASSERT(destination.IsDoubleStackSlot() || 1767 ASSERT(destination.IsDoubleStackSlot() ||
1752 destination.IsQuadStackSlot() || 1768 destination.IsQuadStackSlot() ||
1753 source.IsDoubleStackSlot() || 1769 source.IsDoubleStackSlot() ||
1754 source.IsQuadStackSlot()); 1770 source.IsQuadStackSlot());
1755 bool double_width = destination.IsDoubleStackSlot() || 1771 bool double_width = destination.IsDoubleStackSlot() ||
1756 source.IsDoubleStackSlot(); 1772 source.IsDoubleStackSlot();
1757 DRegister reg = source.IsFpuRegister() ? source.fpu_reg() 1773 QRegister qreg = source.IsFpuRegister() ? source.fpu_reg()
1758 : destination.fpu_reg(); 1774 : destination.fpu_reg();
1775 DRegister reg = EvenDRegisterOf(qreg);
1759 const Address& slot_address = source.IsFpuRegister() 1776 const Address& slot_address = source.IsFpuRegister()
1760 ? destination.ToStackSlotAddress() 1777 ? destination.ToStackSlotAddress()
1761 : source.ToStackSlotAddress(); 1778 : source.ToStackSlotAddress();
1762 1779
1763 if (double_width) { 1780 if (double_width) {
1764 __ vldrd(DTMP, slot_address); 1781 __ vldrd(DTMP, slot_address);
1765 __ vstrd(reg, slot_address); 1782 __ vstrd(reg, slot_address);
1766 __ vmovd(reg, DTMP); 1783 __ vmovd(reg, DTMP);
1767 } else { 1784 } else {
1768 UNIMPLEMENTED(); 1785 UNIMPLEMENTED();
1769 } 1786 }
1770 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { 1787 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
1771 const Address& source_slot_address = source.ToStackSlotAddress(); 1788 const Address& source_slot_address = source.ToStackSlotAddress();
1772 const Address& destination_slot_address = destination.ToStackSlotAddress(); 1789 const Address& destination_slot_address = destination.ToStackSlotAddress();
1773 1790
1774 ScratchFpuRegisterScope ensure_scratch(this, DTMP); 1791 ScratchFpuRegisterScope ensure_scratch(this, QTMP);
1792 DRegister scratch = EvenDRegisterOf(ensure_scratch.reg());
1775 __ vldrd(DTMP, source_slot_address); 1793 __ vldrd(DTMP, source_slot_address);
1776 __ vldrd(ensure_scratch.reg(), destination_slot_address); 1794 __ vldrd(scratch, destination_slot_address);
1777 __ vstrd(DTMP, destination_slot_address); 1795 __ vstrd(DTMP, destination_slot_address);
1778 __ vstrd(ensure_scratch.reg(), source_slot_address); 1796 __ vstrd(scratch, source_slot_address);
1779 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { 1797 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) {
1780 UNIMPLEMENTED(); 1798 UNIMPLEMENTED();
1781 } else { 1799 } else {
1782 UNREACHABLE(); 1800 UNREACHABLE();
1783 } 1801 }
1784 1802
1785 // The swap of source and destination has executed a move from source to 1803 // The swap of source and destination has executed a move from source to
1786 // destination. 1804 // destination.
1787 move->Eliminate(); 1805 move->Eliminate();
1788 1806
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1834 __ Push(reg); 1852 __ Push(reg);
1835 } 1853 }
1836 1854
1837 1855
1838 void ParallelMoveResolver::RestoreScratch(Register reg) { 1856 void ParallelMoveResolver::RestoreScratch(Register reg) {
1839 __ Pop(reg); 1857 __ Pop(reg);
1840 } 1858 }
1841 1859
1842 1860
1843 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { 1861 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
1844 __ vstrd(reg, Address(SP, -kDoubleSize, Address::PreIndex)); 1862 DRegister dreg = EvenDRegisterOf(reg);
1863 __ vstrd(dreg, Address(SP, -kDoubleSize, Address::PreIndex));
1845 } 1864 }
1846 1865
1847 1866
1848 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 1867 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
1849 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); 1868 DRegister dreg = EvenDRegisterOf(reg);
1869 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1850 } 1870 }
1851 1871
1852 1872
1853 #undef __ 1873 #undef __
1854 1874
1855 } // namespace dart 1875 } // namespace dart
1856 1876
1857 #endif // defined TARGET_ARCH_ARM 1877 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698