| OLD | NEW |
| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 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 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { | 755 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { |
| 756 // Optimized try-block: Sync locals to fixed stack locations. | 756 // Optimized try-block: Sync locals to fixed stack locations. |
| 757 EmitTrySync(instr, CurrentTryIndex()); | 757 EmitTrySync(instr, CurrentTryIndex()); |
| 758 } | 758 } |
| 759 } | 759 } |
| 760 | 760 |
| 761 | 761 |
| 762 // TODO(regis): Pass an offset instead of an Address to avoid addressing | 762 // TODO(regis): Pass an offset instead of an Address to avoid addressing |
| 763 // mode restrictions and remove Operand::Equals() on IA32/X64 and | 763 // mode restrictions and remove Operand::Equals() on IA32/X64 and |
| 764 // Address::Equals() on ARM/MIPS. | 764 // Address::Equals() on ARM/MIPS. |
| 765 void FlowGraphCompiler::EmitTrySyncMove(Address dest, | 765 void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset, |
| 766 Location loc, | 766 Location loc, |
| 767 bool* push_emitted) { | 767 bool* push_emitted) { |
| 768 if (loc.IsConstant()) { | 768 if (loc.IsConstant()) { |
| 769 if (!*push_emitted) { | 769 if (!*push_emitted) { |
| 770 __ Push(T0); | 770 __ Push(T0); |
| 771 *push_emitted = true; | 771 *push_emitted = true; |
| 772 } | 772 } |
| 773 __ LoadObject(T0, loc.constant()); | 773 __ LoadObject(T0, loc.constant()); |
| 774 __ sw(T0, dest); | 774 __ StoreToOffset(T0, FP, dest_offset); |
| 775 } else if (loc.IsRegister()) { | 775 } else if (loc.IsRegister()) { |
| 776 if (*push_emitted && loc.reg() == T0) { | 776 if (*push_emitted && loc.reg() == T0) { |
| 777 __ lw(T0, Address(SP, 0)); | 777 __ lw(T0, Address(SP, 0)); |
| 778 __ sw(T0, dest); | 778 __ StoreToOffset(T0, FP, dest_offset); |
| 779 } else { | 779 } else { |
| 780 __ sw(loc.reg(), dest); | 780 __ StoreToOffset(loc.reg(), FP, dest_offset); |
| 781 } | 781 } |
| 782 } else { | 782 } else { |
| 783 Address src = loc.ToStackSlotAddress(); | 783 const intptr_t src_offset = loc.ToStackSlotOffset(); |
| 784 if (!src.Equals(dest)) { | 784 if (src_offset != dest_offset) { |
| 785 if (!*push_emitted) { | 785 if (!*push_emitted) { |
| 786 __ Push(T0); | 786 __ Push(T0); |
| 787 *push_emitted = true; | 787 *push_emitted = true; |
| 788 } | 788 } |
| 789 __ lw(T0, src); | 789 __ LoadFromOffset(T0, FP, src_offset); |
| 790 __ sw(T0, dest); | 790 __ StoreToOffset(T0, FP, dest_offset); |
| 791 } | 791 } |
| 792 } | 792 } |
| 793 } | 793 } |
| 794 | 794 |
| 795 | 795 |
| 796 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { | 796 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { |
| 797 ASSERT(is_optimizing()); | 797 ASSERT(is_optimizing()); |
| 798 Environment* env = instr->env(); | 798 Environment* env = instr->env(); |
| 799 CatchBlockEntryInstr* catch_block = | 799 CatchBlockEntryInstr* catch_block = |
| 800 flow_graph().graph_entry()->GetCatchEntry(try_index); | 800 flow_graph().graph_entry()->GetCatchEntry(try_index); |
| 801 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); | 801 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); |
| 802 // Parameters. | 802 // Parameters. |
| 803 intptr_t i = 0; | 803 intptr_t i = 0; |
| 804 bool push_emitted = false; | 804 bool push_emitted = false; |
| 805 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params(); | 805 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params(); |
| 806 const intptr_t param_base = | 806 const intptr_t param_base = |
| 807 kParamEndSlotFromFp + num_non_copied_params; | 807 kParamEndSlotFromFp + num_non_copied_params; |
| 808 for (; i < num_non_copied_params; ++i) { | 808 for (; i < num_non_copied_params; ++i) { |
| 809 if ((*idefs)[i]->IsConstant()) continue; // Common constants | 809 if ((*idefs)[i]->IsConstant()) continue; // Common constants |
| 810 Location loc = env->LocationAt(i); | 810 Location loc = env->LocationAt(i); |
| 811 Address dest(FP, (param_base - i) * kWordSize); | 811 EmitTrySyncMove((param_base - i) * kWordSize, loc, &push_emitted); |
| 812 EmitTrySyncMove(dest, loc, &push_emitted); | |
| 813 } | 812 } |
| 814 | 813 |
| 815 // Process locals. Skip exception_var and stacktrace_var. | 814 // Process locals. Skip exception_var and stacktrace_var. |
| 816 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); | 815 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); |
| 817 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params; | 816 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params; |
| 818 intptr_t ex_idx = local_base - catch_entry->exception_var().index(); | 817 intptr_t ex_idx = local_base - catch_entry->exception_var().index(); |
| 819 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index(); | 818 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index(); |
| 820 for (; i < flow_graph().variable_count(); ++i) { | 819 for (; i < flow_graph().variable_count(); ++i) { |
| 821 if (i == ex_idx || i == st_idx) continue; | 820 if (i == ex_idx || i == st_idx) continue; |
| 822 if ((*idefs)[i]->IsConstant()) continue; | 821 if ((*idefs)[i]->IsConstant()) continue; |
| 823 Location loc = env->LocationAt(i); | 822 Location loc = env->LocationAt(i); |
| 824 Address dest(FP, (local_base - i) * kWordSize); | 823 EmitTrySyncMove((local_base - i) * kWordSize, loc, &push_emitted); |
| 825 EmitTrySyncMove(dest, loc, &push_emitted); | |
| 826 // Update safepoint bitmap to indicate that the target location | 824 // Update safepoint bitmap to indicate that the target location |
| 827 // now contains a pointer. | 825 // now contains a pointer. |
| 828 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true); | 826 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true); |
| 829 } | 827 } |
| 830 if (push_emitted) { | 828 if (push_emitted) { |
| 831 __ Pop(T0); | 829 __ Pop(T0); |
| 832 } | 830 } |
| 833 } | 831 } |
| 834 | 832 |
| 835 | 833 |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1800 UNREACHABLE(); | 1798 UNREACHABLE(); |
| 1801 return FieldAddress(array, index); | 1799 return FieldAddress(array, index); |
| 1802 } | 1800 } |
| 1803 | 1801 |
| 1804 | 1802 |
| 1805 #undef __ | 1803 #undef __ |
| 1806 #define __ compiler_->assembler()-> | 1804 #define __ compiler_->assembler()-> |
| 1807 | 1805 |
| 1808 | 1806 |
| 1809 void ParallelMoveResolver::EmitMove(int index) { | 1807 void ParallelMoveResolver::EmitMove(int index) { |
| 1810 __ TraceSimMsg("ParallelMoveResolver::EmitMove"); | |
| 1811 MoveOperands* move = moves_[index]; | 1808 MoveOperands* move = moves_[index]; |
| 1812 const Location source = move->src(); | 1809 const Location source = move->src(); |
| 1813 const Location destination = move->dest(); | 1810 const Location destination = move->dest(); |
| 1811 __ TraceSimMsg("ParallelMoveResolver::EmitMove"); |
| 1814 | 1812 |
| 1815 if (source.IsRegister()) { | 1813 if (source.IsRegister()) { |
| 1816 if (destination.IsRegister()) { | 1814 if (destination.IsRegister()) { |
| 1817 __ mov(destination.reg(), source.reg()); | 1815 __ mov(destination.reg(), source.reg()); |
| 1818 } else { | 1816 } else { |
| 1819 ASSERT(destination.IsStackSlot()); | 1817 ASSERT(destination.IsStackSlot()); |
| 1820 __ sw(source.reg(), destination.ToStackSlotAddress()); | 1818 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1819 __ StoreToOffset(source.reg(), FP, dest_offset); |
| 1821 } | 1820 } |
| 1822 } else if (source.IsStackSlot()) { | 1821 } else if (source.IsStackSlot()) { |
| 1823 if (destination.IsRegister()) { | 1822 if (destination.IsRegister()) { |
| 1824 __ lw(destination.reg(), source.ToStackSlotAddress()); | 1823 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1824 __ LoadFromOffset(destination.reg(), FP, source_offset); |
| 1825 } else { | 1825 } else { |
| 1826 ASSERT(destination.IsStackSlot()); | 1826 ASSERT(destination.IsStackSlot()); |
| 1827 MoveMemoryToMemory(destination.ToStackSlotAddress(), | 1827 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1828 source.ToStackSlotAddress()); | 1828 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1829 __ LoadFromOffset(TMP, FP, source_offset); |
| 1830 __ StoreToOffset(TMP, FP, dest_offset); |
| 1829 } | 1831 } |
| 1830 } else if (source.IsFpuRegister()) { | 1832 } else if (source.IsFpuRegister()) { |
| 1831 if (destination.IsFpuRegister()) { | 1833 if (destination.IsFpuRegister()) { |
| 1832 __ movd(destination.fpu_reg(), source.fpu_reg()); | 1834 DRegister dst = destination.fpu_reg(); |
| 1835 DRegister src = source.fpu_reg(); |
| 1836 __ movd(dst, src); |
| 1833 } else { | 1837 } else { |
| 1834 if (destination.IsDoubleStackSlot()) { | 1838 if (destination.IsDoubleStackSlot()) { |
| 1835 const Address& addr = destination.ToStackSlotAddress(); | 1839 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1836 int32_t offset = addr.offset(); | 1840 DRegister src = source.fpu_reg(); |
| 1837 __ StoreDToOffset(source.fpu_reg(), FP, offset); | 1841 __ StoreDToOffset(src, FP, dest_offset); |
| 1838 } else { | 1842 } else { |
| 1839 ASSERT(destination.IsQuadStackSlot()); | 1843 ASSERT(destination.IsQuadStackSlot()); |
| 1840 UNIMPLEMENTED(); | 1844 UNIMPLEMENTED(); |
| 1841 } | 1845 } |
| 1842 } | 1846 } |
| 1843 } else if (source.IsDoubleStackSlot()) { | 1847 } else if (source.IsDoubleStackSlot()) { |
| 1844 if (destination.IsFpuRegister()) { | 1848 if (destination.IsFpuRegister()) { |
| 1845 const Address &addr = source.ToStackSlotAddress(); | 1849 const intptr_t dest_offset = source.ToStackSlotOffset(); |
| 1846 const Register base = addr.base(); | 1850 DRegister dst = destination.fpu_reg(); |
| 1847 const int32_t offset = addr.offset(); | 1851 __ LoadDFromOffset(dst, FP, dest_offset); |
| 1848 __ LoadDFromOffset(destination.fpu_reg(), base, offset); | |
| 1849 } else { | 1852 } else { |
| 1850 ASSERT(destination.IsDoubleStackSlot()); | 1853 ASSERT(destination.IsDoubleStackSlot()); |
| 1851 const Address& saddr = source.ToStackSlotAddress(); | 1854 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1852 const Address& daddr = destination.ToStackSlotAddress(); | 1855 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1853 int32_t soffset = saddr.offset(); | 1856 __ LoadDFromOffset(DTMP, FP, source_offset); |
| 1854 int32_t doffset = daddr.offset(); | 1857 __ StoreDToOffset(DTMP, FP, dest_offset); |
| 1855 __ LoadDFromOffset(FpuTMP, FP, soffset); | |
| 1856 __ StoreDToOffset(FpuTMP, FP, doffset); | |
| 1857 } | 1858 } |
| 1858 } else if (source.IsQuadStackSlot()) { | 1859 } else if (source.IsQuadStackSlot()) { |
| 1859 UNIMPLEMENTED(); | 1860 UNIMPLEMENTED(); |
| 1860 } else { | 1861 } else { |
| 1861 ASSERT(source.IsConstant()); | 1862 ASSERT(source.IsConstant()); |
| 1862 if (destination.IsRegister()) { | 1863 if (destination.IsRegister()) { |
| 1863 const Object& constant = source.constant(); | 1864 const Object& constant = source.constant(); |
| 1864 __ LoadObject(destination.reg(), constant); | 1865 __ LoadObject(destination.reg(), constant); |
| 1865 } else { | 1866 } else { |
| 1866 ASSERT(destination.IsStackSlot()); | 1867 ASSERT(destination.IsStackSlot()); |
| 1867 StoreObject(destination.ToStackSlotAddress(), source.constant()); | 1868 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1869 __ LoadObject(TMP, source.constant()); |
| 1870 __ StoreToOffset(TMP, FP, dest_offset); |
| 1868 } | 1871 } |
| 1869 } | 1872 } |
| 1870 | 1873 |
| 1871 move->Eliminate(); | 1874 move->Eliminate(); |
| 1872 } | 1875 } |
| 1873 | 1876 |
| 1874 | 1877 |
| 1875 void ParallelMoveResolver::EmitSwap(int index) { | 1878 void ParallelMoveResolver::EmitSwap(int index) { |
| 1876 __ TraceSimMsg("ParallelMoveResolver::EmitSwap"); | |
| 1877 MoveOperands* move = moves_[index]; | 1879 MoveOperands* move = moves_[index]; |
| 1878 const Location source = move->src(); | 1880 const Location source = move->src(); |
| 1879 const Location destination = move->dest(); | 1881 const Location destination = move->dest(); |
| 1880 | 1882 |
| 1881 if (source.IsRegister() && destination.IsRegister()) { | 1883 if (source.IsRegister() && destination.IsRegister()) { |
| 1882 ASSERT(source.reg() != TMP1); | 1884 ASSERT(source.reg() != TMP); |
| 1883 ASSERT(destination.reg() != TMP1); | 1885 ASSERT(destination.reg() != TMP); |
| 1884 __ mov(TMP1, source.reg()); | 1886 __ mov(TMP, source.reg()); |
| 1885 __ mov(source.reg(), destination.reg()); | 1887 __ mov(source.reg(), destination.reg()); |
| 1886 __ mov(destination.reg(), TMP1); | 1888 __ mov(destination.reg(), TMP); |
| 1887 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1889 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1888 Exchange(source.reg(), destination.ToStackSlotAddress()); | 1890 Exchange(source.reg(), destination.ToStackSlotOffset()); |
| 1889 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1891 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1890 Exchange(destination.reg(), source.ToStackSlotAddress()); | 1892 Exchange(destination.reg(), source.ToStackSlotOffset()); |
| 1891 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1893 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1892 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); | 1894 Exchange(source.ToStackSlotOffset(), destination.ToStackSlotOffset()); |
| 1893 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1895 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1894 __ movd(FpuTMP, source.fpu_reg()); | 1896 DRegister dst = destination.fpu_reg(); |
| 1895 __ movd(source.fpu_reg(), destination.fpu_reg()); | 1897 DRegister src = source.fpu_reg(); |
| 1896 __ movd(destination.fpu_reg(), FpuTMP); | 1898 __ movd(DTMP, src); |
| 1899 __ movd(src, dst); |
| 1900 __ movd(dst, DTMP); |
| 1897 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1901 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1898 ASSERT(destination.IsDoubleStackSlot() || | 1902 ASSERT(destination.IsDoubleStackSlot() || |
| 1899 destination.IsQuadStackSlot() || | 1903 destination.IsQuadStackSlot() || |
| 1900 source.IsDoubleStackSlot() || | 1904 source.IsDoubleStackSlot() || |
| 1901 source.IsQuadStackSlot()); | 1905 source.IsQuadStackSlot()); |
| 1902 bool double_width = destination.IsDoubleStackSlot() || | 1906 bool double_width = destination.IsDoubleStackSlot() || |
| 1903 source.IsDoubleStackSlot(); | 1907 source.IsDoubleStackSlot(); |
| 1904 DRegister reg = source.IsFpuRegister() ? source.fpu_reg() | 1908 DRegister reg = source.IsFpuRegister() ? source.fpu_reg() |
| 1905 : destination.fpu_reg(); | 1909 : destination.fpu_reg(); |
| 1906 const Address& slot_address = source.IsFpuRegister() | 1910 const intptr_t slot_offset = source.IsFpuRegister() |
| 1907 ? destination.ToStackSlotAddress() | 1911 ? destination.ToStackSlotOffset() |
| 1908 : source.ToStackSlotAddress(); | 1912 : source.ToStackSlotOffset(); |
| 1909 | 1913 |
| 1910 if (double_width) { | 1914 if (double_width) { |
| 1911 const Register base = slot_address.base(); | 1915 __ LoadDFromOffset(DTMP, FP, slot_offset); |
| 1912 const int32_t offset = slot_address.offset(); | 1916 __ StoreDToOffset(reg, FP, slot_offset); |
| 1913 __ LoadDFromOffset(FpuTMP, base, offset); | 1917 __ movd(reg, DTMP); |
| 1914 __ StoreDToOffset(reg, base, offset); | |
| 1915 __ movd(reg, FpuTMP); | |
| 1916 } else { | 1918 } else { |
| 1917 UNIMPLEMENTED(); | 1919 UNIMPLEMENTED(); |
| 1918 } | 1920 } |
| 1919 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { | 1921 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { |
| 1920 const Address& source_slot_address = source.ToStackSlotAddress(); | 1922 const intptr_t source_offset = source.ToStackSlotOffset(); |
| 1921 const Address& destination_slot_address = destination.ToStackSlotAddress(); | 1923 const intptr_t dest_offset = destination.ToStackSlotOffset(); |
| 1922 const Register sbase = source_slot_address.base(); | |
| 1923 const int32_t soffset = source_slot_address.offset(); | |
| 1924 const Register dbase = destination_slot_address.base(); | |
| 1925 const int32_t doffset = destination_slot_address.offset(); | |
| 1926 | 1924 |
| 1927 ScratchFpuRegisterScope ensure_scratch(this, FpuTMP); | 1925 ScratchFpuRegisterScope ensure_scratch(this, DTMP); |
| 1928 __ LoadDFromOffset(FpuTMP, sbase, soffset); | 1926 DRegister scratch = ensure_scratch.reg(); |
| 1929 __ LoadDFromOffset(ensure_scratch.reg(), dbase, doffset); | 1927 __ LoadDFromOffset(DTMP, FP, source_offset); |
| 1930 __ StoreDToOffset(FpuTMP, dbase, doffset); | 1928 __ LoadDFromOffset(scratch, FP, dest_offset); |
| 1931 __ StoreDToOffset(ensure_scratch.reg(), sbase, soffset); | 1929 __ StoreDToOffset(DTMP, FP, dest_offset); |
| 1930 __ StoreDToOffset(scratch, FP, source_offset); |
| 1932 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { | 1931 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { |
| 1933 UNIMPLEMENTED(); | 1932 UNIMPLEMENTED(); |
| 1934 } else { | 1933 } else { |
| 1935 UNREACHABLE(); | 1934 UNREACHABLE(); |
| 1936 } | 1935 } |
| 1937 | 1936 |
| 1938 // The swap of source and destination has executed a move from source to | 1937 // The swap of source and destination has executed a move from source to |
| 1939 // destination. | 1938 // destination. |
| 1940 move->Eliminate(); | 1939 move->Eliminate(); |
| 1941 | 1940 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1961 } | 1960 } |
| 1962 | 1961 |
| 1963 | 1962 |
| 1964 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { | 1963 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { |
| 1965 __ TraceSimMsg("ParallelMoveResolver::StoreObject"); | 1964 __ TraceSimMsg("ParallelMoveResolver::StoreObject"); |
| 1966 __ LoadObject(TMP1, obj); | 1965 __ LoadObject(TMP1, obj); |
| 1967 __ sw(TMP1, dst); | 1966 __ sw(TMP1, dst); |
| 1968 } | 1967 } |
| 1969 | 1968 |
| 1970 | 1969 |
| 1970 // Do not call or implement this function. Instead, use the form below that |
| 1971 // uses an offset from the frame pointer instead of an Address. |
| 1971 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { | 1972 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { |
| 1972 __ TraceSimMsg("ParallelMoveResolver::Exchange ra"); | 1973 UNREACHABLE(); |
| 1973 ASSERT(reg != TMP1); | |
| 1974 __ mov(TMP1, reg); | |
| 1975 __ lw(reg, mem); | |
| 1976 __ sw(TMP1, mem); | |
| 1977 } | 1974 } |
| 1978 | 1975 |
| 1979 | 1976 |
| 1977 // Do not call or implement this function. Instead, use the form below that |
| 1978 // uses offsets from the frame pointer instead of Addresses. |
| 1980 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1979 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1981 __ TraceSimMsg("ParallelMoveResolver::Exchange aa"); | 1980 UNREACHABLE(); |
| 1982 ScratchRegisterScope ensure_scratch(this, TMP1); | 1981 } |
| 1983 __ lw(ensure_scratch.reg(), mem1); | 1982 |
| 1984 __ lw(TMP1, mem2); | 1983 |
| 1985 __ sw(ensure_scratch.reg(), mem2); | 1984 void ParallelMoveResolver::Exchange(Register reg, intptr_t stack_offset) { |
| 1986 __ sw(TMP1, mem1); | 1985 __ mov(TMP, reg); |
| 1986 __ LoadFromOffset(reg, FP, stack_offset); |
| 1987 __ StoreToOffset(TMP, FP, stack_offset); |
| 1988 } |
| 1989 |
| 1990 |
| 1991 void ParallelMoveResolver::Exchange(intptr_t stack_offset1, |
| 1992 intptr_t stack_offset2) { |
| 1993 ScratchRegisterScope ensure_scratch(this, TMP); |
| 1994 __ LoadFromOffset(ensure_scratch.reg(), FP, stack_offset1); |
| 1995 __ LoadFromOffset(TMP, FP, stack_offset2); |
| 1996 __ StoreToOffset(ensure_scratch.reg(), FP, stack_offset2); |
| 1997 __ StoreToOffset(TMP, FP, stack_offset1); |
| 1987 } | 1998 } |
| 1988 | 1999 |
| 1989 | 2000 |
| 1990 void ParallelMoveResolver::SpillScratch(Register reg) { | 2001 void ParallelMoveResolver::SpillScratch(Register reg) { |
| 1991 __ TraceSimMsg("ParallelMoveResolver::SpillScratch"); | 2002 __ TraceSimMsg("ParallelMoveResolver::SpillScratch"); |
| 1992 __ Push(reg); | 2003 __ Push(reg); |
| 1993 } | 2004 } |
| 1994 | 2005 |
| 1995 | 2006 |
| 1996 void ParallelMoveResolver::RestoreScratch(Register reg) { | 2007 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2012 __ AddImmediate(SP, kDoubleSize); | 2023 __ AddImmediate(SP, kDoubleSize); |
| 2013 } | 2024 } |
| 2014 | 2025 |
| 2015 | 2026 |
| 2016 #undef __ | 2027 #undef __ |
| 2017 | 2028 |
| 2018 | 2029 |
| 2019 } // namespace dart | 2030 } // namespace dart |
| 2020 | 2031 |
| 2021 #endif // defined TARGET_ARCH_MIPS | 2032 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |