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

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

Issue 19464002: Replaces Location::ToStackSlotAddress() with Location::ToStackSlotOffset() (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 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 } else if (instr->MayThrow() && 730 } else if (instr->MayThrow() &&
731 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { 731 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
732 // Optimized try-block: Sync locals to fixed stack locations. 732 // Optimized try-block: Sync locals to fixed stack locations.
733 EmitTrySync(instr, CurrentTryIndex()); 733 EmitTrySync(instr, CurrentTryIndex());
734 } 734 }
735 } 735 }
736 736
737 737
738 // TODO(regis): Pass an offset instead of an Address to avoid addressing 738 // TODO(regis): Pass an offset instead of an Address to avoid addressing
739 // mode restrictions and remove Operand::Equals() on IA32/X64 and 739 // mode restrictions and remove Operand::Equals() on IA32/X64 and
740 // Address::Equals() on ARM/MIPS. 740 // Address::Equals() on ARM/MIPS.
regis 2013/07/17 18:46:45 I think you can do what the TODO says and then rem
zra 2013/07/17 20:40:11 Done.
741 void FlowGraphCompiler::EmitTrySyncMove(Address dest, 741 void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
742 Location loc, 742 Location loc,
743 bool* push_emitted) { 743 bool* push_emitted) {
744 if (loc.IsConstant()) { 744 if (loc.IsConstant()) {
745 if (!*push_emitted) { 745 if (!*push_emitted) {
746 __ Push(R0); 746 __ Push(R0);
747 *push_emitted = true; 747 *push_emitted = true;
748 } 748 }
749 __ LoadObject(R0, loc.constant()); 749 __ LoadObject(R0, loc.constant());
750 __ str(R0, dest); 750 __ StoreToOffset(kWord, R0, FP, dest_offset);
751 } else if (loc.IsRegister()) { 751 } else if (loc.IsRegister()) {
752 if (*push_emitted && (loc.reg() == R0)) { 752 if (*push_emitted && (loc.reg() == R0)) {
753 __ ldr(R0, Address(SP, 0)); 753 __ ldr(R0, Address(SP, 0));
754 __ str(R0, dest); 754 __ StoreToOffset(kWord, R0, FP, dest_offset);
755 } else { 755 } else {
756 __ str(loc.reg(), dest); 756 __ StoreToOffset(kWord, loc.reg(), FP, dest_offset);
757 } 757 }
758 } else { 758 } else {
759 Address src = loc.ToStackSlotAddress(); 759 const intptr_t src_offset = loc.ToStackSlotOffset();
760 if (!src.Equals(dest)) { 760 if (src_offset != dest_offset) {
761 if (!*push_emitted) { 761 if (!*push_emitted) {
762 __ Push(R0); 762 __ Push(R0);
763 *push_emitted = true; 763 *push_emitted = true;
764 } 764 }
765 __ ldr(R0, src); 765 __ LoadFromOffset(kWord, R0, FP, src_offset);
766 __ str(R0, dest); 766 __ StoreToOffset(kWord, R0, FP, dest_offset);
767 } 767 }
768 } 768 }
769 } 769 }
770 770
771 771
772 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { 772 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) {
773 ASSERT(is_optimizing()); 773 ASSERT(is_optimizing());
774 Environment* env = instr->env(); 774 Environment* env = instr->env();
775 CatchBlockEntryInstr* catch_block = 775 CatchBlockEntryInstr* catch_block =
776 flow_graph().graph_entry()->GetCatchEntry(try_index); 776 flow_graph().graph_entry()->GetCatchEntry(try_index);
777 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); 777 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions();
778 // Parameters. 778 // Parameters.
779 intptr_t i = 0; 779 intptr_t i = 0;
780 bool push_emitted = false; 780 bool push_emitted = false;
781 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params(); 781 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params();
782 const intptr_t param_base = 782 const intptr_t param_base =
783 kParamEndSlotFromFp + num_non_copied_params; 783 kParamEndSlotFromFp + num_non_copied_params;
784 for (; i < num_non_copied_params; ++i) { 784 for (; i < num_non_copied_params; ++i) {
785 if ((*idefs)[i]->IsConstant()) continue; // Common constants 785 if ((*idefs)[i]->IsConstant()) continue; // Common constants
786 Location loc = env->LocationAt(i); 786 Location loc = env->LocationAt(i);
787 Address dest(FP, (param_base - i) * kWordSize); 787 EmitTrySyncMove((param_base - i) * kWordSize, loc, &push_emitted);
788 EmitTrySyncMove(dest, loc, &push_emitted);
789 } 788 }
790 789
791 // Process locals. Skip exception_var and stacktrace_var. 790 // Process locals. Skip exception_var and stacktrace_var.
792 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); 791 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry();
793 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params; 792 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params;
794 intptr_t ex_idx = local_base - catch_entry->exception_var().index(); 793 intptr_t ex_idx = local_base - catch_entry->exception_var().index();
795 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index(); 794 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index();
796 for (; i < flow_graph().variable_count(); ++i) { 795 for (; i < flow_graph().variable_count(); ++i) {
797 if (i == ex_idx || i == st_idx) continue; 796 if (i == ex_idx || i == st_idx) continue;
798 if ((*idefs)[i]->IsConstant()) continue; 797 if ((*idefs)[i]->IsConstant()) continue;
799 Location loc = env->LocationAt(i); 798 Location loc = env->LocationAt(i);
800 Address dest(FP, (local_base - i) * kWordSize); 799 EmitTrySyncMove((local_base - i) * kWordSize, loc, &push_emitted);
801 EmitTrySyncMove(dest, loc, &push_emitted);
802 // Update safepoint bitmap to indicate that the target location 800 // Update safepoint bitmap to indicate that the target location
803 // now contains a pointer. 801 // now contains a pointer.
804 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true); 802 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true);
805 } 803 }
806 if (push_emitted) { 804 if (push_emitted) {
807 __ Pop(R0); 805 __ Pop(R0);
808 } 806 }
809 } 807 }
810 808
811 809
(...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 void ParallelMoveResolver::EmitMove(int index) { 1694 void ParallelMoveResolver::EmitMove(int index) {
1697 MoveOperands* move = moves_[index]; 1695 MoveOperands* move = moves_[index];
1698 const Location source = move->src(); 1696 const Location source = move->src();
1699 const Location destination = move->dest(); 1697 const Location destination = move->dest();
1700 1698
1701 if (source.IsRegister()) { 1699 if (source.IsRegister()) {
1702 if (destination.IsRegister()) { 1700 if (destination.IsRegister()) {
1703 __ mov(destination.reg(), ShifterOperand(source.reg())); 1701 __ mov(destination.reg(), ShifterOperand(source.reg()));
1704 } else { 1702 } else {
1705 ASSERT(destination.IsStackSlot()); 1703 ASSERT(destination.IsStackSlot());
1706 __ str(source.reg(), destination.ToStackSlotAddress()); 1704 const intptr_t dest_offset = destination.ToStackSlotOffset();
1705 __ StoreToOffset(kWord, source.reg(), FP, dest_offset);
1707 } 1706 }
1708 } else if (source.IsStackSlot()) { 1707 } else if (source.IsStackSlot()) {
1709 if (destination.IsRegister()) { 1708 if (destination.IsRegister()) {
1710 __ ldr(destination.reg(), source.ToStackSlotAddress()); 1709 const intptr_t source_offset = source.ToStackSlotOffset();
1710 __ LoadFromOffset(kWord, destination.reg(), FP, source_offset);
1711 } else { 1711 } else {
1712 ASSERT(destination.IsStackSlot()); 1712 ASSERT(destination.IsStackSlot());
1713 MoveMemoryToMemory(destination.ToStackSlotAddress(), 1713 const intptr_t source_offset = source.ToStackSlotOffset();
1714 source.ToStackSlotAddress()); 1714 const intptr_t dest_offset = destination.ToStackSlotOffset();
1715 __ LoadFromOffset(kWord, TMP, FP, source_offset);
1716 __ StoreToOffset(kWord, TMP, FP, dest_offset);
1715 } 1717 }
1716 } else if (source.IsFpuRegister()) { 1718 } else if (source.IsFpuRegister()) {
1717 if (destination.IsFpuRegister()) { 1719 if (destination.IsFpuRegister()) {
1718 DRegister dst = EvenDRegisterOf(destination.fpu_reg()); 1720 DRegister dst = EvenDRegisterOf(destination.fpu_reg());
1719 DRegister src = EvenDRegisterOf(source.fpu_reg()); 1721 DRegister src = EvenDRegisterOf(source.fpu_reg());
1720 __ vmovd(dst, src); 1722 __ vmovd(dst, src);
1721 } else { 1723 } else {
1722 if (destination.IsDoubleStackSlot()) { 1724 if (destination.IsDoubleStackSlot()) {
1725 const intptr_t dest_offset = destination.ToStackSlotOffset();
1723 DRegister src = EvenDRegisterOf(source.fpu_reg()); 1726 DRegister src = EvenDRegisterOf(source.fpu_reg());
1724 __ vstrd(src, destination.ToStackSlotAddress()); 1727 __ StoreDToOffset(src, FP, dest_offset);
1725 } else { 1728 } else {
1726 ASSERT(destination.IsQuadStackSlot()); 1729 ASSERT(destination.IsQuadStackSlot());
1727 UNIMPLEMENTED(); 1730 UNIMPLEMENTED();
1728 } 1731 }
1729 } 1732 }
1730 } else if (source.IsDoubleStackSlot()) { 1733 } else if (source.IsDoubleStackSlot()) {
1731 if (destination.IsFpuRegister()) { 1734 if (destination.IsFpuRegister()) {
1735 const intptr_t dest_offset = source.ToStackSlotOffset();
1732 DRegister dst = EvenDRegisterOf(destination.fpu_reg()); 1736 DRegister dst = EvenDRegisterOf(destination.fpu_reg());
1733 __ vldrd(dst, source.ToStackSlotAddress()); 1737 __ LoadDFromOffset(dst, FP, dest_offset);
1734 } else { 1738 } else {
1735 ASSERT(destination.IsDoubleStackSlot()); 1739 ASSERT(destination.IsDoubleStackSlot());
1736 __ vldrd(DTMP, source.ToStackSlotAddress()); 1740 const intptr_t source_offset = source.ToStackSlotOffset();
1737 __ vstrd(DTMP, destination.ToStackSlotAddress()); 1741 const intptr_t dest_offset = destination.ToStackSlotOffset();
1742 __ LoadDFromOffset(DTMP, FP, source_offset);
1743 __ StoreDToOffset(DTMP, FP, dest_offset);
1738 } 1744 }
1739 } else if (source.IsQuadStackSlot()) { 1745 } else if (source.IsQuadStackSlot()) {
1740 UNIMPLEMENTED(); 1746 UNIMPLEMENTED();
1741 } else { 1747 } else {
1742 ASSERT(source.IsConstant()); 1748 ASSERT(source.IsConstant());
1743 if (destination.IsRegister()) { 1749 if (destination.IsRegister()) {
1744 const Object& constant = source.constant(); 1750 const Object& constant = source.constant();
1745 __ LoadObject(destination.reg(), constant); 1751 __ LoadObject(destination.reg(), constant);
1746 } else { 1752 } else {
1747 ASSERT(destination.IsStackSlot()); 1753 ASSERT(destination.IsStackSlot());
1748 StoreObject(destination.ToStackSlotAddress(), source.constant()); 1754 const intptr_t dest_offset = destination.ToStackSlotOffset();
1755 __ LoadObject(TMP, source.constant());
1756 __ StoreToOffset(kWord, TMP, FP, dest_offset);
1749 } 1757 }
1750 } 1758 }
1751 1759
1752 move->Eliminate(); 1760 move->Eliminate();
1753 } 1761 }
1754 1762
1755 1763
1756 void ParallelMoveResolver::EmitSwap(int index) { 1764 void ParallelMoveResolver::EmitSwap(int index) {
1757 MoveOperands* move = moves_[index]; 1765 MoveOperands* move = moves_[index];
1758 const Location source = move->src(); 1766 const Location source = move->src();
1759 const Location destination = move->dest(); 1767 const Location destination = move->dest();
1760 1768
1761 if (source.IsRegister() && destination.IsRegister()) { 1769 if (source.IsRegister() && destination.IsRegister()) {
1762 ASSERT(source.reg() != IP); 1770 ASSERT(source.reg() != IP);
1763 ASSERT(destination.reg() != IP); 1771 ASSERT(destination.reg() != IP);
1764 __ mov(IP, ShifterOperand(source.reg())); 1772 __ mov(IP, ShifterOperand(source.reg()));
1765 __ mov(source.reg(), ShifterOperand(destination.reg())); 1773 __ mov(source.reg(), ShifterOperand(destination.reg()));
1766 __ mov(destination.reg(), ShifterOperand(IP)); 1774 __ mov(destination.reg(), ShifterOperand(IP));
1767 } else if (source.IsRegister() && destination.IsStackSlot()) { 1775 } else if (source.IsRegister() && destination.IsStackSlot()) {
1768 Exchange(source.reg(), destination.ToStackSlotAddress()); 1776 const intptr_t dest_offset = destination.ToStackSlotOffset();
1777 __ mov(TMP, ShifterOperand(source.reg()));
1778 __ LoadFromOffset(kWord, source.reg(), FP, dest_offset);
1779 __ StoreToOffset(kWord, TMP, FP, dest_offset);
1769 } else if (source.IsStackSlot() && destination.IsRegister()) { 1780 } else if (source.IsStackSlot() && destination.IsRegister()) {
1770 Exchange(destination.reg(), source.ToStackSlotAddress()); 1781 const intptr_t source_offset = source.ToStackSlotOffset();
1782 __ mov(TMP, ShifterOperand(destination.reg()));
1783 __ LoadFromOffset(kWord, destination.reg(), FP, source_offset);
1784 __ StoreToOffset(kWord, TMP, FP, source_offset);
1771 } else if (source.IsStackSlot() && destination.IsStackSlot()) { 1785 } else if (source.IsStackSlot() && destination.IsStackSlot()) {
1772 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); 1786 ScratchRegisterScope ensure_scratch(this, IP);
1787 const intptr_t source_offset = source.ToStackSlotOffset();
1788 const intptr_t dest_offset = destination.ToStackSlotOffset();
1789 __ LoadFromOffset(kWord, ensure_scratch.reg(), FP, source_offset);
1790 __ LoadFromOffset(kWord, TMP, FP, dest_offset);
1791 __ StoreToOffset(kWord, ensure_scratch.reg(), FP, dest_offset);
1792 __ StoreToOffset(kWord, TMP, FP, source_offset);
regis 2013/07/17 18:46:45 How about implementing a variant of Exchange that
zra 2013/07/17 20:40:11 Done.
1773 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { 1793 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
1774 DRegister dst = EvenDRegisterOf(destination.fpu_reg()); 1794 DRegister dst = EvenDRegisterOf(destination.fpu_reg());
1775 DRegister src = EvenDRegisterOf(source.fpu_reg()); 1795 DRegister src = EvenDRegisterOf(source.fpu_reg());
1776 __ vmovd(DTMP, src); 1796 __ vmovd(DTMP, src);
1777 __ vmovd(src, dst); 1797 __ vmovd(src, dst);
1778 __ vmovd(dst, DTMP); 1798 __ vmovd(dst, DTMP);
1779 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { 1799 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) {
1780 ASSERT(destination.IsDoubleStackSlot() || 1800 ASSERT(destination.IsDoubleStackSlot() ||
1781 destination.IsQuadStackSlot() || 1801 destination.IsQuadStackSlot() ||
1782 source.IsDoubleStackSlot() || 1802 source.IsDoubleStackSlot() ||
1783 source.IsQuadStackSlot()); 1803 source.IsQuadStackSlot());
1784 bool double_width = destination.IsDoubleStackSlot() || 1804 bool double_width = destination.IsDoubleStackSlot() ||
1785 source.IsDoubleStackSlot(); 1805 source.IsDoubleStackSlot();
1786 QRegister qreg = source.IsFpuRegister() ? source.fpu_reg() 1806 QRegister qreg = source.IsFpuRegister() ? source.fpu_reg()
1787 : destination.fpu_reg(); 1807 : destination.fpu_reg();
1788 DRegister reg = EvenDRegisterOf(qreg); 1808 DRegister reg = EvenDRegisterOf(qreg);
1789 const Address& slot_address = source.IsFpuRegister() 1809 const intptr_t slot_offset = source.IsFpuRegister()
1790 ? destination.ToStackSlotAddress() 1810 ? destination.ToStackSlotOffset()
1791 : source.ToStackSlotAddress(); 1811 : source.ToStackSlotOffset();
1792 1812
1793 if (double_width) { 1813 if (double_width) {
1794 __ vldrd(DTMP, slot_address); 1814 __ LoadDFromOffset(DTMP, FP, slot_offset);
1795 __ vstrd(reg, slot_address); 1815 __ StoreDToOffset(reg, FP, slot_offset);
1796 __ vmovd(reg, DTMP); 1816 __ vmovd(reg, DTMP);
1797 } else { 1817 } else {
1798 UNIMPLEMENTED(); 1818 UNIMPLEMENTED();
1799 } 1819 }
1800 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { 1820 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
1801 const Address& source_slot_address = source.ToStackSlotAddress(); 1821 const intptr_t source_offset = source.ToStackSlotOffset();
1802 const Address& destination_slot_address = destination.ToStackSlotAddress(); 1822 const intptr_t dest_offset = destination.ToStackSlotOffset();
1803 1823
1804 ScratchFpuRegisterScope ensure_scratch(this, QTMP); 1824 ScratchFpuRegisterScope ensure_scratch(this, QTMP);
1805 DRegister scratch = EvenDRegisterOf(ensure_scratch.reg()); 1825 DRegister scratch = EvenDRegisterOf(ensure_scratch.reg());
1806 __ vldrd(DTMP, source_slot_address); 1826 __ LoadDFromOffset(DTMP, FP, source_offset);
1807 __ vldrd(scratch, destination_slot_address); 1827 __ LoadDFromOffset(scratch, FP, dest_offset);
1808 __ vstrd(DTMP, destination_slot_address); 1828 __ StoreDToOffset(DTMP, FP, dest_offset);
1809 __ vstrd(scratch, source_slot_address); 1829 __ StoreDToOffset(scratch, FP, source_offset);
1810 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { 1830 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) {
1811 UNIMPLEMENTED(); 1831 UNIMPLEMENTED();
1812 } else { 1832 } else {
1813 UNREACHABLE(); 1833 UNREACHABLE();
1814 } 1834 }
1815 1835
1816 // The swap of source and destination has executed a move from source to 1836 // The swap of source and destination has executed a move from source to
1817 // destination. 1837 // destination.
1818 move->Eliminate(); 1838 move->Eliminate();
1819 1839
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 DRegister dreg = EvenDRegisterOf(reg); 1901 DRegister dreg = EvenDRegisterOf(reg);
1882 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); 1902 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1883 } 1903 }
1884 1904
1885 1905
1886 #undef __ 1906 #undef __
1887 1907
1888 } // namespace dart 1908 } // namespace dart
1889 1909
1890 #endif // defined TARGET_ARCH_ARM 1910 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698