| 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/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1685 StoreInstanceFieldInstr* instruction_; | 1685 StoreInstanceFieldInstr* instruction_; |
| 1686 const Class& cls_; | 1686 const Class& cls_; |
| 1687 }; | 1687 }; |
| 1688 | 1688 |
| 1689 | 1689 |
| 1690 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { | 1690 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { |
| 1691 const intptr_t kNumInputs = 2; | 1691 const intptr_t kNumInputs = 2; |
| 1692 const intptr_t kNumTemps = 0; | 1692 const intptr_t kNumTemps = 0; |
| 1693 LocationSummary* summary = | 1693 LocationSummary* summary = |
| 1694 new LocationSummary(kNumInputs, kNumTemps, | 1694 new LocationSummary(kNumInputs, kNumTemps, |
| 1695 (field().guarded_cid() == kIllegalCid) || (is_initialization_) | 1695 !field().IsNull() && |
| 1696 ((field().guarded_cid() == kIllegalCid) || is_initialization_) |
| 1696 ? LocationSummary::kCallOnSlowPath | 1697 ? LocationSummary::kCallOnSlowPath |
| 1697 : LocationSummary::kNoCall); | 1698 : LocationSummary::kNoCall); |
| 1698 | 1699 |
| 1699 summary->set_in(0, Location::RequiresRegister()); | 1700 summary->set_in(0, Location::RequiresRegister()); |
| 1700 if (IsUnboxedStore() && opt) { | 1701 if (IsUnboxedStore() && opt) { |
| 1701 summary->set_in(1, Location::RequiresFpuRegister()); | 1702 summary->set_in(1, Location::RequiresFpuRegister()); |
| 1702 summary->AddTemp(Location::RequiresRegister()); | 1703 summary->AddTemp(Location::RequiresRegister()); |
| 1703 summary->AddTemp(Location::RequiresRegister()); | 1704 summary->AddTemp(Location::RequiresRegister()); |
| 1704 } else if (IsPotentialUnboxedStore()) { | 1705 } else if (IsPotentialUnboxedStore()) { |
| 1705 summary->set_in(1, ShouldEmitStoreBarrier() | 1706 summary->set_in(1, ShouldEmitStoreBarrier() |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1743 new StoreInstanceFieldSlowPath(this, *cls); | 1744 new StoreInstanceFieldSlowPath(this, *cls); |
| 1744 compiler->AddSlowPathCode(slow_path); | 1745 compiler->AddSlowPathCode(slow_path); |
| 1745 | 1746 |
| 1746 __ TryAllocate(*cls, | 1747 __ TryAllocate(*cls, |
| 1747 slow_path->entry_label(), | 1748 slow_path->entry_label(), |
| 1748 temp, | 1749 temp, |
| 1749 temp2); | 1750 temp2); |
| 1750 __ Bind(slow_path->exit_label()); | 1751 __ Bind(slow_path->exit_label()); |
| 1751 __ mov(temp2, temp); | 1752 __ mov(temp2, temp); |
| 1752 __ StoreIntoObject(instance_reg, | 1753 __ StoreIntoObject(instance_reg, |
| 1753 FieldAddress(instance_reg, field().Offset()), | 1754 FieldAddress(instance_reg, offset_in_bytes_), |
| 1754 temp2); | 1755 temp2); |
| 1755 } else { | 1756 } else { |
| 1756 __ lw(temp, FieldAddress(instance_reg, field().Offset())); | 1757 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
| 1757 } | 1758 } |
| 1758 switch (cid) { | 1759 switch (cid) { |
| 1759 case kDoubleCid: | 1760 case kDoubleCid: |
| 1760 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); | 1761 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1761 break; | 1762 break; |
| 1762 default: | 1763 default: |
| 1763 UNREACHABLE(); | 1764 UNREACHABLE(); |
| 1764 } | 1765 } |
| 1765 return; | 1766 return; |
| 1766 } | 1767 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1791 | 1792 |
| 1792 if (!compiler->is_optimizing()) { | 1793 if (!compiler->is_optimizing()) { |
| 1793 locs()->live_registers()->Add(locs()->in(0)); | 1794 locs()->live_registers()->Add(locs()->in(0)); |
| 1794 locs()->live_registers()->Add(locs()->in(1)); | 1795 locs()->live_registers()->Add(locs()->in(1)); |
| 1795 } | 1796 } |
| 1796 | 1797 |
| 1797 { | 1798 { |
| 1798 __ Bind(&store_double); | 1799 __ Bind(&store_double); |
| 1799 Label copy_double; | 1800 Label copy_double; |
| 1800 | 1801 |
| 1801 __ lw(temp, FieldAddress(instance_reg, field().Offset())); | 1802 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
| 1802 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()), | 1803 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()), |
| 1803 ©_double); | 1804 ©_double); |
| 1804 | 1805 |
| 1805 StoreInstanceFieldSlowPath* slow_path = | 1806 StoreInstanceFieldSlowPath* slow_path = |
| 1806 new StoreInstanceFieldSlowPath(this, compiler->double_class()); | 1807 new StoreInstanceFieldSlowPath(this, compiler->double_class()); |
| 1807 compiler->AddSlowPathCode(slow_path); | 1808 compiler->AddSlowPathCode(slow_path); |
| 1808 | 1809 |
| 1809 __ TryAllocate(compiler->double_class(), | 1810 __ TryAllocate(compiler->double_class(), |
| 1810 slow_path->entry_label(), | 1811 slow_path->entry_label(), |
| 1811 temp, | 1812 temp, |
| 1812 temp2); | 1813 temp2); |
| 1813 __ Bind(slow_path->exit_label()); | 1814 __ Bind(slow_path->exit_label()); |
| 1814 __ mov(temp2, temp); | 1815 __ mov(temp2, temp); |
| 1815 __ StoreIntoObject(instance_reg, | 1816 __ StoreIntoObject(instance_reg, |
| 1816 FieldAddress(instance_reg, field().Offset()), | 1817 FieldAddress(instance_reg, offset_in_bytes_), |
| 1817 temp2); | 1818 temp2); |
| 1818 | 1819 |
| 1819 __ Bind(©_double); | 1820 __ Bind(©_double); |
| 1820 __ LoadDFromOffset(fpu_temp, | 1821 __ LoadDFromOffset(fpu_temp, |
| 1821 value_reg, | 1822 value_reg, |
| 1822 Double::value_offset() - kHeapObjectTag); | 1823 Double::value_offset() - kHeapObjectTag); |
| 1823 __ StoreDToOffset(fpu_temp, temp, | 1824 __ StoreDToOffset(fpu_temp, temp, |
| 1824 Double::value_offset() - kHeapObjectTag); | 1825 Double::value_offset() - kHeapObjectTag); |
| 1825 __ b(&skip_store); | 1826 __ b(&skip_store); |
| 1826 } | 1827 } |
| 1827 | 1828 |
| 1828 __ Bind(&store_pointer); | 1829 __ Bind(&store_pointer); |
| 1829 } | 1830 } |
| 1830 | 1831 |
| 1831 if (ShouldEmitStoreBarrier()) { | 1832 if (ShouldEmitStoreBarrier()) { |
| 1832 Register value_reg = locs()->in(1).reg(); | 1833 Register value_reg = locs()->in(1).reg(); |
| 1833 __ StoreIntoObject(instance_reg, | 1834 __ StoreIntoObject(instance_reg, |
| 1834 FieldAddress(instance_reg, field().Offset()), | 1835 FieldAddress(instance_reg, offset_in_bytes_), |
| 1835 value_reg, | 1836 value_reg, |
| 1836 CanValueBeSmi()); | 1837 CanValueBeSmi()); |
| 1837 } else { | 1838 } else { |
| 1838 if (locs()->in(1).IsConstant()) { | 1839 if (locs()->in(1).IsConstant()) { |
| 1839 __ StoreIntoObjectNoBarrier( | 1840 __ StoreIntoObjectNoBarrier( |
| 1840 instance_reg, | 1841 instance_reg, |
| 1841 FieldAddress(instance_reg, field().Offset()), | 1842 FieldAddress(instance_reg, offset_in_bytes_), |
| 1842 locs()->in(1).constant()); | 1843 locs()->in(1).constant()); |
| 1843 } else { | 1844 } else { |
| 1844 Register value_reg = locs()->in(1).reg(); | 1845 Register value_reg = locs()->in(1).reg(); |
| 1845 __ StoreIntoObjectNoBarrier(instance_reg, | 1846 __ StoreIntoObjectNoBarrier(instance_reg, |
| 1846 FieldAddress(instance_reg, field().Offset()), value_reg); | 1847 FieldAddress(instance_reg, offset_in_bytes_), value_reg); |
| 1847 } | 1848 } |
| 1848 } | 1849 } |
| 1849 __ Bind(&skip_store); | 1850 __ Bind(&skip_store); |
| 1850 } | 1851 } |
| 1851 | 1852 |
| 1852 | 1853 |
| 1853 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { | 1854 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { |
| 1854 const intptr_t kNumInputs = 1; | 1855 const intptr_t kNumInputs = 1; |
| 1855 const intptr_t kNumTemps = 0; | 1856 const intptr_t kNumTemps = 0; |
| 1856 LocationSummary* summary = | 1857 LocationSummary* summary = |
| (...skipping 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4160 Register value = locs()->in(0).reg(); | 4161 Register value = locs()->in(0).reg(); |
| 4161 Register result = locs()->out().reg(); | 4162 Register result = locs()->out().reg(); |
| 4162 | 4163 |
| 4163 __ LoadObject(result, Bool::True()); | 4164 __ LoadObject(result, Bool::True()); |
| 4164 __ LoadObject(TMP, Bool::False()); | 4165 __ LoadObject(TMP, Bool::False()); |
| 4165 __ subu(CMPRES1, value, result); | 4166 __ subu(CMPRES1, value, result); |
| 4166 __ movz(result, TMP, CMPRES1); // If value is True, move False into result. | 4167 __ movz(result, TMP, CMPRES1); // If value is True, move False into result. |
| 4167 } | 4168 } |
| 4168 | 4169 |
| 4169 | 4170 |
| 4170 LocationSummary* StoreVMFieldInstr::MakeLocationSummary(bool opt) const { | |
| 4171 const intptr_t kNumInputs = 2; | |
| 4172 const intptr_t kNumTemps = 0; | |
| 4173 LocationSummary* locs = | |
| 4174 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 4175 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | |
| 4176 : Location::RequiresRegister()); | |
| 4177 locs->set_in(1, Location::RequiresRegister()); | |
| 4178 return locs; | |
| 4179 } | |
| 4180 | |
| 4181 | |
| 4182 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4183 Register value_reg = locs()->in(0).reg(); | |
| 4184 Register dest_reg = locs()->in(1).reg(); | |
| 4185 | |
| 4186 if (value()->NeedsStoreBuffer()) { | |
| 4187 __ StoreIntoObject(dest_reg, | |
| 4188 FieldAddress(dest_reg, offset_in_bytes()), value_reg); | |
| 4189 } else { | |
| 4190 __ StoreIntoObjectNoBarrier(dest_reg, | |
| 4191 FieldAddress(dest_reg, offset_in_bytes()), value_reg); | |
| 4192 } | |
| 4193 } | |
| 4194 | |
| 4195 | |
| 4196 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { | 4171 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { |
| 4197 return MakeCallSummary(); | 4172 return MakeCallSummary(); |
| 4198 } | 4173 } |
| 4199 | 4174 |
| 4200 | 4175 |
| 4201 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4176 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4202 __ TraceSimMsg("AllocateObjectInstr"); | 4177 __ TraceSimMsg("AllocateObjectInstr"); |
| 4203 __ Comment("AllocateObjectInstr"); | 4178 __ Comment("AllocateObjectInstr"); |
| 4204 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); | 4179 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); |
| 4205 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); | 4180 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4226 compiler->GenerateCall(token_pos(), | 4201 compiler->GenerateCall(token_pos(), |
| 4227 &label, | 4202 &label, |
| 4228 PcDescriptors::kOther, | 4203 PcDescriptors::kOther, |
| 4229 locs()); | 4204 locs()); |
| 4230 __ Drop(2); // Discard type arguments and receiver. | 4205 __ Drop(2); // Discard type arguments and receiver. |
| 4231 } | 4206 } |
| 4232 | 4207 |
| 4233 } // namespace dart | 4208 } // namespace dart |
| 4234 | 4209 |
| 4235 #endif // defined TARGET_ARCH_MIPS | 4210 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |