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

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

Powered by Google App Engine
This is Rietveld 408576698