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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 1647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 Field::kUnknownLengthOffset); | 1658 Field::kUnknownLengthOffset); |
1659 | 1659 |
1660 __ cmpl(FieldAddress(value_reg, | 1660 __ cmpl(FieldAddress(value_reg, |
1661 field().guarded_list_length_in_object_offset()), | 1661 field().guarded_list_length_in_object_offset()), |
1662 Immediate(Smi::RawValue(field().guarded_list_length()))); | 1662 Immediate(Smi::RawValue(field().guarded_list_length()))); |
1663 __ j(NOT_EQUAL, deopt); | 1663 __ j(NOT_EQUAL, deopt); |
1664 } | 1664 } |
1665 } | 1665 } |
1666 | 1666 |
1667 | 1667 |
1668 class StoreInstanceFieldSlowPath : public SlowPathCode { | 1668 class BoxAllocationSlowPath : public SlowPathCode { |
1669 public: | 1669 public: |
1670 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, | 1670 BoxAllocationSlowPath(Instruction* instruction, |
1671 const Class& cls) | 1671 const Class& cls, |
1672 : instruction_(instruction), cls_(cls) { } | 1672 Register result) |
| 1673 : instruction_(instruction), |
| 1674 cls_(cls), |
| 1675 result_(result) { } |
1673 | 1676 |
1674 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1677 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
1675 __ Comment("StoreInstanceFieldSlowPath"); | 1678 Isolate* isolate = compiler->isolate(); |
| 1679 StubCode* stub_code = isolate->stub_code(); |
| 1680 |
| 1681 if (Assembler::EmittingComments()) { |
| 1682 __ Comment("%s slow path allocation of %s", |
| 1683 instruction_->DebugName(), |
| 1684 String::Handle(cls_.PrettyName()).ToCString()); |
| 1685 } |
1676 __ Bind(entry_label()); | 1686 __ Bind(entry_label()); |
1677 Isolate* isolate = compiler->isolate(); | 1687 |
1678 const Code& stub = | 1688 const Code& stub = |
1679 Code::Handle(isolate, | 1689 Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); |
1680 isolate->stub_code()->GetAllocationStubForClass(cls_)); | |
1681 const ExternalLabel label(stub.EntryPoint()); | 1690 const ExternalLabel label(stub.EntryPoint()); |
1682 | 1691 |
1683 LocationSummary* locs = instruction_->locs(); | 1692 LocationSummary* locs = instruction_->locs(); |
1684 locs->live_registers()->Remove(locs->temp(0)); | 1693 |
| 1694 locs->live_registers()->Remove(Location::RegisterLocation(result_)); |
1685 | 1695 |
1686 compiler->SaveLiveRegisters(locs); | 1696 compiler->SaveLiveRegisters(locs); |
1687 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 1697 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
1688 &label, | 1698 &label, |
1689 RawPcDescriptors::kOther, | 1699 RawPcDescriptors::kOther, |
1690 locs); | 1700 locs); |
1691 __ MoveRegister(locs->temp(0).reg(), EAX); | 1701 __ MoveRegister(result_, EAX); |
1692 compiler->RestoreLiveRegisters(locs); | 1702 compiler->RestoreLiveRegisters(locs); |
1693 __ jmp(exit_label()); | 1703 __ jmp(exit_label()); |
1694 } | 1704 } |
1695 | 1705 |
| 1706 static void Allocate(FlowGraphCompiler* compiler, |
| 1707 Instruction* instruction, |
| 1708 const Class& cls, |
| 1709 Register result, |
| 1710 Register temp) { |
| 1711 BoxAllocationSlowPath* slow_path = |
| 1712 new BoxAllocationSlowPath(instruction, cls, result); |
| 1713 compiler->AddSlowPathCode(slow_path); |
| 1714 |
| 1715 __ TryAllocate(cls, |
| 1716 slow_path->entry_label(), |
| 1717 Assembler::kFarJump, |
| 1718 result, |
| 1719 temp); |
| 1720 __ Bind(slow_path->exit_label()); |
| 1721 } |
| 1722 |
1696 private: | 1723 private: |
1697 StoreInstanceFieldInstr* instruction_; | 1724 Instruction* instruction_; |
1698 const Class& cls_; | 1725 const Class& cls_; |
| 1726 Register result_; |
1699 }; | 1727 }; |
1700 | 1728 |
1701 | 1729 |
1702 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, | 1730 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, |
1703 bool opt) const { | 1731 bool opt) const { |
1704 const intptr_t kNumInputs = 2; | 1732 const intptr_t kNumInputs = 2; |
1705 const intptr_t kNumTemps = | 1733 const intptr_t kNumTemps = |
1706 (IsUnboxedStore() && opt) ? 2 : | 1734 (IsUnboxedStore() && opt) ? 2 : |
1707 ((IsPotentialUnboxedStore()) ? 3 : 0); | 1735 ((IsPotentialUnboxedStore()) ? 3 : 0); |
1708 LocationSummary* summary = new(isolate) LocationSummary( | 1736 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 18 matching lines...) Expand all Loading... |
1727 : Location::FpuRegisterLocation(XMM1)); | 1755 : Location::FpuRegisterLocation(XMM1)); |
1728 } else { | 1756 } else { |
1729 summary->set_in(1, ShouldEmitStoreBarrier() | 1757 summary->set_in(1, ShouldEmitStoreBarrier() |
1730 ? Location::WritableRegister() | 1758 ? Location::WritableRegister() |
1731 : Location::RegisterOrConstant(value())); | 1759 : Location::RegisterOrConstant(value())); |
1732 } | 1760 } |
1733 return summary; | 1761 return summary; |
1734 } | 1762 } |
1735 | 1763 |
1736 | 1764 |
| 1765 static void EnsureMutableBox(FlowGraphCompiler* compiler, |
| 1766 StoreInstanceFieldInstr* instruction, |
| 1767 Register box_reg, |
| 1768 const Class& cls, |
| 1769 Register instance_reg, |
| 1770 intptr_t offset, |
| 1771 Register temp) { |
| 1772 Label done; |
| 1773 const Immediate& raw_null = |
| 1774 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1775 __ movl(box_reg, FieldAddress(instance_reg, offset)); |
| 1776 __ cmpl(box_reg, raw_null); |
| 1777 __ j(NOT_EQUAL, &done); |
| 1778 BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp); |
| 1779 __ movl(temp, box_reg); |
| 1780 __ StoreIntoObject(instance_reg, |
| 1781 FieldAddress(instance_reg, offset), |
| 1782 temp); |
| 1783 |
| 1784 __ Bind(&done); |
| 1785 } |
| 1786 |
| 1787 |
1737 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1788 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1738 Label skip_store; | 1789 Label skip_store; |
1739 | 1790 |
1740 Register instance_reg = locs()->in(0).reg(); | 1791 Register instance_reg = locs()->in(0).reg(); |
1741 | 1792 |
1742 if (IsUnboxedStore() && compiler->is_optimizing()) { | 1793 if (IsUnboxedStore() && compiler->is_optimizing()) { |
1743 XmmRegister value = locs()->in(1).fpu_reg(); | 1794 XmmRegister value = locs()->in(1).fpu_reg(); |
1744 Register temp = locs()->temp(0).reg(); | 1795 Register temp = locs()->temp(0).reg(); |
1745 Register temp2 = locs()->temp(1).reg(); | 1796 Register temp2 = locs()->temp(1).reg(); |
1746 const intptr_t cid = field().UnboxedFieldCid(); | 1797 const intptr_t cid = field().UnboxedFieldCid(); |
1747 | 1798 |
1748 if (is_initialization_) { | 1799 if (is_initialization_) { |
1749 const Class* cls = NULL; | 1800 const Class* cls = NULL; |
1750 switch (cid) { | 1801 switch (cid) { |
1751 case kDoubleCid: | 1802 case kDoubleCid: |
1752 cls = &compiler->double_class(); | 1803 cls = &compiler->double_class(); |
1753 break; | 1804 break; |
1754 case kFloat32x4Cid: | 1805 case kFloat32x4Cid: |
1755 cls = &compiler->float32x4_class(); | 1806 cls = &compiler->float32x4_class(); |
1756 break; | 1807 break; |
1757 case kFloat64x2Cid: | 1808 case kFloat64x2Cid: |
1758 cls = &compiler->float64x2_class(); | 1809 cls = &compiler->float64x2_class(); |
1759 break; | 1810 break; |
1760 default: | 1811 default: |
1761 UNREACHABLE(); | 1812 UNREACHABLE(); |
1762 } | 1813 } |
1763 | 1814 |
1764 StoreInstanceFieldSlowPath* slow_path = | 1815 BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2); |
1765 new StoreInstanceFieldSlowPath(this, *cls); | |
1766 compiler->AddSlowPathCode(slow_path); | |
1767 | |
1768 __ TryAllocate(*cls, | |
1769 slow_path->entry_label(), | |
1770 Assembler::kFarJump, | |
1771 temp, | |
1772 temp2); | |
1773 __ Bind(slow_path->exit_label()); | |
1774 __ movl(temp2, temp); | 1816 __ movl(temp2, temp); |
1775 __ StoreIntoObject(instance_reg, | 1817 __ StoreIntoObject(instance_reg, |
1776 FieldAddress(instance_reg, offset_in_bytes_), | 1818 FieldAddress(instance_reg, offset_in_bytes_), |
1777 temp2); | 1819 temp2); |
1778 } else { | 1820 } else { |
1779 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1821 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
1780 } | 1822 } |
1781 switch (cid) { | 1823 switch (cid) { |
1782 case kDoubleCid: | 1824 case kDoubleCid: |
1783 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); | 1825 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1835 __ jmp(&store_pointer); | 1877 __ jmp(&store_pointer); |
1836 | 1878 |
1837 | 1879 |
1838 if (!compiler->is_optimizing()) { | 1880 if (!compiler->is_optimizing()) { |
1839 locs()->live_registers()->Add(locs()->in(0)); | 1881 locs()->live_registers()->Add(locs()->in(0)); |
1840 locs()->live_registers()->Add(locs()->in(1)); | 1882 locs()->live_registers()->Add(locs()->in(1)); |
1841 } | 1883 } |
1842 | 1884 |
1843 { | 1885 { |
1844 __ Bind(&store_double); | 1886 __ Bind(&store_double); |
1845 Label copy_double; | 1887 EnsureMutableBox(compiler, |
1846 | 1888 this, |
1847 StoreInstanceFieldSlowPath* slow_path = | 1889 temp, |
1848 new StoreInstanceFieldSlowPath(this, compiler->double_class()); | 1890 compiler->double_class(), |
1849 compiler->AddSlowPathCode(slow_path); | 1891 instance_reg, |
1850 | 1892 offset_in_bytes_, |
1851 const Immediate& raw_null = | 1893 temp2); |
1852 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
1853 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); | |
1854 __ cmpl(temp, raw_null); | |
1855 __ j(NOT_EQUAL, ©_double); | |
1856 | |
1857 __ TryAllocate(compiler->double_class(), | |
1858 slow_path->entry_label(), | |
1859 Assembler::kFarJump, | |
1860 temp, | |
1861 temp2); | |
1862 __ Bind(slow_path->exit_label()); | |
1863 __ movl(temp2, temp); | |
1864 __ StoreIntoObject(instance_reg, | |
1865 FieldAddress(instance_reg, offset_in_bytes_), | |
1866 temp2); | |
1867 | |
1868 __ Bind(©_double); | |
1869 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset())); | 1894 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset())); |
1870 __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp); | 1895 __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp); |
1871 __ jmp(&skip_store); | 1896 __ jmp(&skip_store); |
1872 } | 1897 } |
1873 | 1898 |
1874 { | 1899 { |
1875 __ Bind(&store_float32x4); | 1900 __ Bind(&store_float32x4); |
1876 Label copy_float32x4; | 1901 EnsureMutableBox(compiler, |
1877 | 1902 this, |
1878 StoreInstanceFieldSlowPath* slow_path = | 1903 temp, |
1879 new StoreInstanceFieldSlowPath(this, compiler->float32x4_class()); | 1904 compiler->float32x4_class(), |
1880 compiler->AddSlowPathCode(slow_path); | 1905 instance_reg, |
1881 | 1906 offset_in_bytes_, |
1882 const Immediate& raw_null = | 1907 temp2); |
1883 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
1884 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); | |
1885 __ cmpl(temp, raw_null); | |
1886 __ j(NOT_EQUAL, ©_float32x4); | |
1887 | |
1888 __ TryAllocate(compiler->float32x4_class(), | |
1889 slow_path->entry_label(), | |
1890 Assembler::kFarJump, | |
1891 temp, | |
1892 temp2); | |
1893 __ Bind(slow_path->exit_label()); | |
1894 __ movl(temp2, temp); | |
1895 __ StoreIntoObject(instance_reg, | |
1896 FieldAddress(instance_reg, offset_in_bytes_), | |
1897 temp2); | |
1898 | |
1899 __ Bind(©_float32x4); | |
1900 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); | 1908 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); |
1901 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); | 1909 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); |
1902 __ jmp(&skip_store); | 1910 __ jmp(&skip_store); |
1903 } | 1911 } |
1904 | 1912 |
1905 { | 1913 { |
1906 __ Bind(&store_float64x2); | 1914 __ Bind(&store_float64x2); |
1907 Label copy_float64x2; | 1915 EnsureMutableBox(compiler, |
1908 | 1916 this, |
1909 StoreInstanceFieldSlowPath* slow_path = | 1917 temp, |
1910 new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); | 1918 compiler->float64x2_class(), |
1911 compiler->AddSlowPathCode(slow_path); | 1919 instance_reg, |
1912 | 1920 offset_in_bytes_, |
1913 const Immediate& raw_null = | 1921 temp2); |
1914 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
1915 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); | |
1916 __ cmpl(temp, raw_null); | |
1917 __ j(NOT_EQUAL, ©_float64x2); | |
1918 | |
1919 __ TryAllocate(compiler->float64x2_class(), | |
1920 slow_path->entry_label(), | |
1921 Assembler::kFarJump, | |
1922 temp, | |
1923 temp2); | |
1924 __ Bind(slow_path->exit_label()); | |
1925 __ movl(temp2, temp); | |
1926 __ StoreIntoObject(instance_reg, | |
1927 FieldAddress(instance_reg, offset_in_bytes_), | |
1928 temp2); | |
1929 | |
1930 __ Bind(©_float64x2); | |
1931 __ movups(fpu_temp, FieldAddress(value_reg, Float64x2::value_offset())); | 1922 __ movups(fpu_temp, FieldAddress(value_reg, Float64x2::value_offset())); |
1932 __ movups(FieldAddress(temp, Float64x2::value_offset()), fpu_temp); | 1923 __ movups(FieldAddress(temp, Float64x2::value_offset()), fpu_temp); |
1933 __ jmp(&skip_store); | 1924 __ jmp(&skip_store); |
1934 } | 1925 } |
1935 | 1926 |
1936 __ Bind(&store_pointer); | 1927 __ Bind(&store_pointer); |
1937 } | 1928 } |
1938 | 1929 |
1939 if (ShouldEmitStoreBarrier()) { | 1930 if (ShouldEmitStoreBarrier()) { |
1940 Register value_reg = locs()->in(1).reg(); | 1931 Register value_reg = locs()->in(1).reg(); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2154 StubCode* stub_code = compiler->isolate()->stub_code(); | 2145 StubCode* stub_code = compiler->isolate()->stub_code(); |
2155 compiler->GenerateCall(token_pos(), | 2146 compiler->GenerateCall(token_pos(), |
2156 &stub_code->AllocateArrayLabel(), | 2147 &stub_code->AllocateArrayLabel(), |
2157 RawPcDescriptors::kOther, | 2148 RawPcDescriptors::kOther, |
2158 locs()); | 2149 locs()); |
2159 __ Bind(&done); | 2150 __ Bind(&done); |
2160 ASSERT(locs()->out(0).reg() == kResultReg); | 2151 ASSERT(locs()->out(0).reg() == kResultReg); |
2161 } | 2152 } |
2162 | 2153 |
2163 | 2154 |
2164 class BoxDoubleSlowPath : public SlowPathCode { | |
2165 public: | |
2166 explicit BoxDoubleSlowPath(Instruction* instruction) | |
2167 : instruction_(instruction) { } | |
2168 | |
2169 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2170 __ Comment("BoxDoubleSlowPath"); | |
2171 __ Bind(entry_label()); | |
2172 Isolate* isolate = compiler->isolate(); | |
2173 StubCode* stub_code = isolate->stub_code(); | |
2174 const Class& double_class = compiler->double_class(); | |
2175 const Code& stub = | |
2176 Code::Handle(isolate, | |
2177 stub_code->GetAllocationStubForClass(double_class)); | |
2178 const ExternalLabel label(stub.EntryPoint()); | |
2179 | |
2180 LocationSummary* locs = instruction_->locs(); | |
2181 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
2182 compiler->SaveLiveRegisters(locs); | |
2183 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
2184 &label, | |
2185 RawPcDescriptors::kOther, | |
2186 locs); | |
2187 __ MoveRegister(locs->out(0).reg(), EAX); | |
2188 compiler->RestoreLiveRegisters(locs); | |
2189 | |
2190 __ jmp(exit_label()); | |
2191 } | |
2192 | |
2193 private: | |
2194 Instruction* instruction_; | |
2195 }; | |
2196 | |
2197 | |
2198 class BoxFloat32x4SlowPath : public SlowPathCode { | |
2199 public: | |
2200 explicit BoxFloat32x4SlowPath(Instruction* instruction) | |
2201 : instruction_(instruction) { } | |
2202 | |
2203 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2204 __ Comment("BoxFloat32x4SlowPath"); | |
2205 __ Bind(entry_label()); | |
2206 Isolate* isolate = compiler->isolate(); | |
2207 StubCode* stub_code = isolate->stub_code(); | |
2208 const Class& float32x4_class = compiler->float32x4_class(); | |
2209 const Code& stub = | |
2210 Code::Handle(isolate, | |
2211 stub_code->GetAllocationStubForClass(float32x4_class)); | |
2212 const ExternalLabel label(stub.EntryPoint()); | |
2213 | |
2214 LocationSummary* locs = instruction_->locs(); | |
2215 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
2216 | |
2217 compiler->SaveLiveRegisters(locs); | |
2218 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
2219 &label, | |
2220 RawPcDescriptors::kOther, | |
2221 locs); | |
2222 __ MoveRegister(locs->out(0).reg(), EAX); | |
2223 compiler->RestoreLiveRegisters(locs); | |
2224 | |
2225 __ jmp(exit_label()); | |
2226 } | |
2227 | |
2228 private: | |
2229 Instruction* instruction_; | |
2230 }; | |
2231 | |
2232 | |
2233 class BoxFloat64x2SlowPath : public SlowPathCode { | |
2234 public: | |
2235 explicit BoxFloat64x2SlowPath(Instruction* instruction) | |
2236 : instruction_(instruction) { } | |
2237 | |
2238 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2239 __ Comment("BoxFloat64x2SlowPath"); | |
2240 __ Bind(entry_label()); | |
2241 Isolate* isolate = compiler->isolate(); | |
2242 StubCode* stub_code = isolate->stub_code(); | |
2243 const Class& float64x2_class = compiler->float64x2_class(); | |
2244 const Code& stub = | |
2245 Code::Handle(isolate, | |
2246 stub_code->GetAllocationStubForClass(float64x2_class)); | |
2247 const ExternalLabel label(stub.EntryPoint()); | |
2248 | |
2249 LocationSummary* locs = instruction_->locs(); | |
2250 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
2251 | |
2252 compiler->SaveLiveRegisters(locs); | |
2253 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
2254 &label, | |
2255 RawPcDescriptors::kOther, | |
2256 locs); | |
2257 __ MoveRegister(locs->out(0).reg(), EAX); | |
2258 compiler->RestoreLiveRegisters(locs); | |
2259 | |
2260 __ jmp(exit_label()); | |
2261 } | |
2262 | |
2263 private: | |
2264 Instruction* instruction_; | |
2265 }; | |
2266 | |
2267 | |
2268 LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, | 2155 LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, |
2269 bool opt) const { | 2156 bool opt) const { |
2270 const intptr_t kNumInputs = 1; | 2157 const intptr_t kNumInputs = 1; |
2271 const intptr_t kNumTemps = | 2158 const intptr_t kNumTemps = |
2272 (IsUnboxedLoad() && opt) ? 1 : | 2159 (IsUnboxedLoad() && opt) ? 1 : |
2273 ((IsPotentialUnboxedLoad()) ? 2 : 0); | 2160 ((IsPotentialUnboxedLoad()) ? 2 : 0); |
2274 | 2161 |
2275 LocationSummary* locs = new(isolate) LocationSummary( | 2162 LocationSummary* locs = new(isolate) LocationSummary( |
2276 isolate, kNumInputs, kNumTemps, | 2163 isolate, kNumInputs, kNumTemps, |
2277 (opt && !IsPotentialUnboxedLoad()) | 2164 (opt && !IsPotentialUnboxedLoad()) |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2349 | 2236 |
2350 // Fall through. | 2237 // Fall through. |
2351 __ jmp(&load_pointer); | 2238 __ jmp(&load_pointer); |
2352 | 2239 |
2353 if (!compiler->is_optimizing()) { | 2240 if (!compiler->is_optimizing()) { |
2354 locs()->live_registers()->Add(locs()->in(0)); | 2241 locs()->live_registers()->Add(locs()->in(0)); |
2355 } | 2242 } |
2356 | 2243 |
2357 { | 2244 { |
2358 __ Bind(&load_double); | 2245 __ Bind(&load_double); |
2359 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2246 BoxAllocationSlowPath::Allocate( |
2360 compiler->AddSlowPathCode(slow_path); | 2247 compiler, this, compiler->double_class(), result, temp); |
2361 | |
2362 __ TryAllocate(compiler->double_class(), | |
2363 slow_path->entry_label(), | |
2364 Assembler::kFarJump, | |
2365 result, | |
2366 temp); | |
2367 __ Bind(slow_path->exit_label()); | |
2368 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2248 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); |
2369 __ movsd(value, FieldAddress(temp, Double::value_offset())); | 2249 __ movsd(value, FieldAddress(temp, Double::value_offset())); |
2370 __ movsd(FieldAddress(result, Double::value_offset()), value); | 2250 __ movsd(FieldAddress(result, Double::value_offset()), value); |
2371 __ jmp(&done); | 2251 __ jmp(&done); |
2372 } | 2252 } |
2373 | 2253 |
2374 { | 2254 { |
2375 __ Bind(&load_float32x4); | 2255 __ Bind(&load_float32x4); |
2376 | 2256 BoxAllocationSlowPath::Allocate( |
2377 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | 2257 compiler, this, compiler->float32x4_class(), result, temp); |
2378 compiler->AddSlowPathCode(slow_path); | |
2379 | |
2380 __ TryAllocate(compiler->float32x4_class(), | |
2381 slow_path->entry_label(), | |
2382 Assembler::kFarJump, | |
2383 result, | |
2384 temp); | |
2385 __ Bind(slow_path->exit_label()); | |
2386 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2258 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); |
2387 __ movups(value, FieldAddress(temp, Float32x4::value_offset())); | 2259 __ movups(value, FieldAddress(temp, Float32x4::value_offset())); |
2388 __ movups(FieldAddress(result, Float32x4::value_offset()), value); | 2260 __ movups(FieldAddress(result, Float32x4::value_offset()), value); |
2389 __ jmp(&done); | 2261 __ jmp(&done); |
2390 } | 2262 } |
2391 | 2263 |
2392 { | 2264 { |
2393 __ Bind(&load_float64x2); | 2265 __ Bind(&load_float64x2); |
2394 | 2266 BoxAllocationSlowPath::Allocate( |
2395 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); | 2267 compiler, this, compiler->float64x2_class(), result, temp); |
2396 compiler->AddSlowPathCode(slow_path); | |
2397 | |
2398 __ TryAllocate(compiler->float64x2_class(), | |
2399 slow_path->entry_label(), | |
2400 Assembler::kFarJump, | |
2401 result, | |
2402 temp); | |
2403 __ Bind(slow_path->exit_label()); | |
2404 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2268 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); |
2405 __ movups(value, FieldAddress(temp, Float64x2::value_offset())); | 2269 __ movups(value, FieldAddress(temp, Float64x2::value_offset())); |
2406 __ movups(FieldAddress(result, Float64x2::value_offset()), value); | 2270 __ movups(FieldAddress(result, Float64x2::value_offset()), value); |
2407 __ jmp(&done); | 2271 __ jmp(&done); |
2408 } | 2272 } |
2409 | 2273 |
2410 __ Bind(&load_pointer); | 2274 __ Bind(&load_pointer); |
2411 } | 2275 } |
2412 __ movl(result, FieldAddress(instance_reg, offset_in_bytes())); | 2276 __ movl(result, FieldAddress(instance_reg, offset_in_bytes())); |
2413 __ Bind(&done); | 2277 __ Bind(&done); |
(...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3352 const intptr_t kNumTemps = 0; | 3216 const intptr_t kNumTemps = 0; |
3353 LocationSummary* summary = new(isolate) LocationSummary( | 3217 LocationSummary* summary = new(isolate) LocationSummary( |
3354 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | 3218 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
3355 summary->set_in(0, Location::RequiresFpuRegister()); | 3219 summary->set_in(0, Location::RequiresFpuRegister()); |
3356 summary->set_out(0, Location::RequiresRegister()); | 3220 summary->set_out(0, Location::RequiresRegister()); |
3357 return summary; | 3221 return summary; |
3358 } | 3222 } |
3359 | 3223 |
3360 | 3224 |
3361 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3225 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3362 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | |
3363 compiler->AddSlowPathCode(slow_path); | |
3364 | |
3365 Register out_reg = locs()->out(0).reg(); | 3226 Register out_reg = locs()->out(0).reg(); |
3366 XmmRegister value = locs()->in(0).fpu_reg(); | 3227 XmmRegister value = locs()->in(0).fpu_reg(); |
3367 | 3228 BoxAllocationSlowPath::Allocate( |
3368 __ TryAllocate(compiler->double_class(), | 3229 compiler, this, compiler->double_class(), out_reg, kNoRegister); |
3369 slow_path->entry_label(), | |
3370 Assembler::kFarJump, | |
3371 out_reg, | |
3372 kNoRegister); | |
3373 __ Bind(slow_path->exit_label()); | |
3374 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); | 3230 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
3375 } | 3231 } |
3376 | 3232 |
3377 | 3233 |
3378 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3234 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, |
3379 bool opt) const { | 3235 bool opt) const { |
3380 const intptr_t kNumInputs = 1; | 3236 const intptr_t kNumInputs = 1; |
3381 const intptr_t value_cid = value()->Type()->ToCid(); | 3237 const intptr_t value_cid = value()->Type()->ToCid(); |
3382 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); | 3238 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); |
3383 const bool needs_writable_input = (value_cid == kSmiCid); | 3239 const bool needs_writable_input = (value_cid == kSmiCid); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3442 isolate, kNumInputs, | 3298 isolate, kNumInputs, |
3443 kNumTemps, | 3299 kNumTemps, |
3444 LocationSummary::kCallOnSlowPath); | 3300 LocationSummary::kCallOnSlowPath); |
3445 summary->set_in(0, Location::RequiresFpuRegister()); | 3301 summary->set_in(0, Location::RequiresFpuRegister()); |
3446 summary->set_out(0, Location::RequiresRegister()); | 3302 summary->set_out(0, Location::RequiresRegister()); |
3447 return summary; | 3303 return summary; |
3448 } | 3304 } |
3449 | 3305 |
3450 | 3306 |
3451 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3307 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3452 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | |
3453 compiler->AddSlowPathCode(slow_path); | |
3454 | |
3455 Register out_reg = locs()->out(0).reg(); | 3308 Register out_reg = locs()->out(0).reg(); |
3456 XmmRegister value = locs()->in(0).fpu_reg(); | 3309 XmmRegister value = locs()->in(0).fpu_reg(); |
3457 | 3310 |
3458 __ TryAllocate(compiler->float32x4_class(), | 3311 BoxAllocationSlowPath::Allocate( |
3459 slow_path->entry_label(), | 3312 compiler, this, compiler->float32x4_class(), out_reg, kNoRegister); |
3460 Assembler::kFarJump, | |
3461 out_reg, | |
3462 kNoRegister); | |
3463 __ Bind(slow_path->exit_label()); | |
3464 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); | 3313 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); |
3465 } | 3314 } |
3466 | 3315 |
3467 | 3316 |
3468 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3317 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, |
3469 bool opt) const { | 3318 bool opt) const { |
3470 const intptr_t value_cid = value()->Type()->ToCid(); | 3319 const intptr_t value_cid = value()->Type()->ToCid(); |
3471 const intptr_t kNumInputs = 1; | 3320 const intptr_t kNumInputs = 1; |
3472 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; | 3321 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; |
3473 LocationSummary* summary = new(isolate) LocationSummary( | 3322 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3507 isolate, kNumInputs, | 3356 isolate, kNumInputs, |
3508 kNumTemps, | 3357 kNumTemps, |
3509 LocationSummary::kCallOnSlowPath); | 3358 LocationSummary::kCallOnSlowPath); |
3510 summary->set_in(0, Location::RequiresFpuRegister()); | 3359 summary->set_in(0, Location::RequiresFpuRegister()); |
3511 summary->set_out(0, Location::RequiresRegister()); | 3360 summary->set_out(0, Location::RequiresRegister()); |
3512 return summary; | 3361 return summary; |
3513 } | 3362 } |
3514 | 3363 |
3515 | 3364 |
3516 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3365 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3517 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); | |
3518 compiler->AddSlowPathCode(slow_path); | |
3519 | |
3520 Register out_reg = locs()->out(0).reg(); | 3366 Register out_reg = locs()->out(0).reg(); |
3521 XmmRegister value = locs()->in(0).fpu_reg(); | 3367 XmmRegister value = locs()->in(0).fpu_reg(); |
3522 | 3368 |
3523 __ TryAllocate(compiler->float64x2_class(), | 3369 BoxAllocationSlowPath::Allocate( |
3524 slow_path->entry_label(), | 3370 compiler, this, compiler->float64x2_class(), out_reg, kNoRegister); |
3525 Assembler::kFarJump, | |
3526 out_reg, | |
3527 kNoRegister); | |
3528 __ Bind(slow_path->exit_label()); | |
3529 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); | 3371 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); |
3530 } | 3372 } |
3531 | 3373 |
3532 | 3374 |
3533 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, | 3375 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, |
3534 bool opt) const { | 3376 bool opt) const { |
3535 const intptr_t value_cid = value()->Type()->ToCid(); | 3377 const intptr_t value_cid = value()->Type()->ToCid(); |
3536 const intptr_t kNumInputs = 1; | 3378 const intptr_t kNumInputs = 1; |
3537 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; | 3379 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; |
3538 LocationSummary* summary = new(isolate) LocationSummary( | 3380 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3571 LocationSummary* summary = new(isolate) LocationSummary( | 3413 LocationSummary* summary = new(isolate) LocationSummary( |
3572 isolate, kNumInputs, | 3414 isolate, kNumInputs, |
3573 kNumTemps, | 3415 kNumTemps, |
3574 LocationSummary::kCallOnSlowPath); | 3416 LocationSummary::kCallOnSlowPath); |
3575 summary->set_in(0, Location::RequiresFpuRegister()); | 3417 summary->set_in(0, Location::RequiresFpuRegister()); |
3576 summary->set_out(0, Location::RequiresRegister()); | 3418 summary->set_out(0, Location::RequiresRegister()); |
3577 return summary; | 3419 return summary; |
3578 } | 3420 } |
3579 | 3421 |
3580 | 3422 |
3581 class BoxInt32x4SlowPath : public SlowPathCode { | |
3582 public: | |
3583 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) | |
3584 : instruction_(instruction) { } | |
3585 | |
3586 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
3587 __ Comment("BoxInt32x4SlowPath"); | |
3588 __ Bind(entry_label()); | |
3589 Isolate* isolate = compiler->isolate(); | |
3590 StubCode* stub_code = isolate->stub_code(); | |
3591 const Class& int32x4_class = compiler->int32x4_class(); | |
3592 const Code& stub = | |
3593 Code::Handle(isolate, | |
3594 stub_code->GetAllocationStubForClass(int32x4_class)); | |
3595 const ExternalLabel label(stub.EntryPoint()); | |
3596 | |
3597 LocationSummary* locs = instruction_->locs(); | |
3598 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
3599 | |
3600 compiler->SaveLiveRegisters(locs); | |
3601 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
3602 &label, | |
3603 RawPcDescriptors::kOther, | |
3604 locs); | |
3605 __ MoveRegister(locs->out(0).reg(), EAX); | |
3606 compiler->RestoreLiveRegisters(locs); | |
3607 | |
3608 __ jmp(exit_label()); | |
3609 } | |
3610 | |
3611 private: | |
3612 BoxInt32x4Instr* instruction_; | |
3613 }; | |
3614 | |
3615 | |
3616 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3423 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3617 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); | |
3618 compiler->AddSlowPathCode(slow_path); | |
3619 | |
3620 Register out_reg = locs()->out(0).reg(); | 3424 Register out_reg = locs()->out(0).reg(); |
3621 XmmRegister value = locs()->in(0).fpu_reg(); | 3425 XmmRegister value = locs()->in(0).fpu_reg(); |
3622 | 3426 |
3623 __ TryAllocate(compiler->int32x4_class(), | 3427 BoxAllocationSlowPath::Allocate( |
3624 slow_path->entry_label(), | 3428 compiler, this, compiler->int32x4_class(), out_reg, kNoRegister); |
3625 Assembler::kFarJump, | |
3626 out_reg, | |
3627 kNoRegister); | |
3628 __ Bind(slow_path->exit_label()); | |
3629 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); | 3429 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); |
3630 } | 3430 } |
3631 | 3431 |
3632 | 3432 |
3633 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate, | 3433 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate, |
3634 bool opt) const { | 3434 bool opt) const { |
3635 const intptr_t value_cid = value()->Type()->ToCid(); | 3435 const intptr_t value_cid = value()->Type()->ToCid(); |
3636 const intptr_t kNumInputs = 1; | 3436 const intptr_t kNumInputs = 1; |
3637 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; | 3437 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
3638 LocationSummary* summary = new(isolate) LocationSummary( | 3438 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 2057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5696 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 5496 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
5697 Location::RequiresRegister())); | 5497 Location::RequiresRegister())); |
5698 if (!is_smi()) { | 5498 if (!is_smi()) { |
5699 summary->set_temp(0, Location::RequiresRegister()); | 5499 summary->set_temp(0, Location::RequiresRegister()); |
5700 } | 5500 } |
5701 summary->set_out(0, Location::RequiresRegister()); | 5501 summary->set_out(0, Location::RequiresRegister()); |
5702 return summary; | 5502 return summary; |
5703 } | 5503 } |
5704 | 5504 |
5705 | 5505 |
5706 class BoxIntegerSlowPath : public SlowPathCode { | |
5707 public: | |
5708 explicit BoxIntegerSlowPath(Definition* instruction) | |
5709 : instruction_(instruction) { } | |
5710 | |
5711 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
5712 __ Comment("BoxIntegerSlowPath"); | |
5713 __ Bind(entry_label()); | |
5714 Isolate* isolate = compiler->isolate(); | |
5715 StubCode* stub_code = isolate->stub_code(); | |
5716 const Class& mint_class = | |
5717 Class::ZoneHandle(isolate, isolate->object_store()->mint_class()); | |
5718 const Code& stub = | |
5719 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); | |
5720 const ExternalLabel label(stub.EntryPoint()); | |
5721 | |
5722 LocationSummary* locs = instruction_->locs(); | |
5723 ASSERT(!locs->live_registers()->Contains(locs->out(0))); | |
5724 | |
5725 compiler->SaveLiveRegisters(locs); | |
5726 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | |
5727 &label, | |
5728 RawPcDescriptors::kOther, | |
5729 locs); | |
5730 __ MoveRegister(locs->out(0).reg(), EAX); | |
5731 compiler->RestoreLiveRegisters(locs); | |
5732 | |
5733 __ jmp(exit_label()); | |
5734 } | |
5735 | |
5736 private: | |
5737 Definition* instruction_; | |
5738 }; | |
5739 | |
5740 | |
5741 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5506 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5742 if (is_smi()) { | 5507 if (is_smi()) { |
5743 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | 5508 PairLocation* value_pair = locs()->in(0).AsPairLocation(); |
5744 Register value_lo = value_pair->At(0).reg(); | 5509 Register value_lo = value_pair->At(0).reg(); |
5745 Register out_reg = locs()->out(0).reg(); | 5510 Register out_reg = locs()->out(0).reg(); |
5746 __ movl(out_reg, value_lo); | 5511 __ movl(out_reg, value_lo); |
5747 __ SmiTag(out_reg); | 5512 __ SmiTag(out_reg); |
5748 return; | 5513 return; |
5749 } | 5514 } |
5750 | 5515 |
5751 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); | |
5752 compiler->AddSlowPathCode(slow_path); | |
5753 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | 5516 PairLocation* value_pair = locs()->in(0).AsPairLocation(); |
5754 Register value_lo = value_pair->At(0).reg(); | 5517 Register value_lo = value_pair->At(0).reg(); |
5755 Register value_hi = value_pair->At(1).reg(); | 5518 Register value_hi = value_pair->At(1).reg(); |
5756 Register out_reg = locs()->out(0).reg(); | 5519 Register out_reg = locs()->out(0).reg(); |
5757 | 5520 |
5758 // Copy value_hi into out_reg as a temporary. | 5521 // Copy value_hi into out_reg as a temporary. |
5759 // We modify value_lo but restore it before using it. | 5522 // We modify value_lo but restore it before using it. |
5760 __ movl(out_reg, value_hi); | 5523 __ movl(out_reg, value_hi); |
5761 | 5524 |
5762 // Unboxed operations produce smis or mint-sized values. | 5525 // Unboxed operations produce smis or mint-sized values. |
5763 // Check if value fits into a smi. | 5526 // Check if value fits into a smi. |
5764 Label not_smi, done; | 5527 Label not_smi, done; |
5765 | 5528 |
5766 // 1. Compute (x + -kMinSmi) which has to be in the range | 5529 // 1. Compute (x + -kMinSmi) which has to be in the range |
5767 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi. | 5530 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi. |
5768 __ addl(value_lo, Immediate(0x40000000)); | 5531 __ addl(value_lo, Immediate(0x40000000)); |
5769 __ adcl(out_reg, Immediate(0)); | 5532 __ adcl(out_reg, Immediate(0)); |
5770 // 2. Unsigned compare to -kMinSmi+kMaxSmi. | 5533 // 2. Unsigned compare to -kMinSmi+kMaxSmi. |
5771 __ cmpl(value_lo, Immediate(0x80000000)); | 5534 __ cmpl(value_lo, Immediate(0x80000000)); |
5772 __ sbbl(out_reg, Immediate(0)); | 5535 __ sbbl(out_reg, Immediate(0)); |
5773 __ j(ABOVE_EQUAL, ¬_smi); | 5536 __ j(ABOVE_EQUAL, ¬_smi); |
5774 // 3. Restore lower half if result is a smi. | 5537 // 3. Restore lower half if result is a smi. |
5775 __ subl(value_lo, Immediate(0x40000000)); | 5538 __ subl(value_lo, Immediate(0x40000000)); |
5776 __ movl(out_reg, value_lo); | 5539 __ movl(out_reg, value_lo); |
5777 __ SmiTag(out_reg); | 5540 __ SmiTag(out_reg); |
5778 __ jmp(&done); | 5541 __ jmp(&done); |
5779 __ Bind(¬_smi); | 5542 __ Bind(¬_smi); |
5780 __ TryAllocate( | |
5781 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), | |
5782 slow_path->entry_label(), | |
5783 Assembler::kFarJump, | |
5784 out_reg, | |
5785 kNoRegister); | |
5786 __ Bind(slow_path->exit_label()); | |
5787 // 3. Restore lower half of input before using it. | 5543 // 3. Restore lower half of input before using it. |
5788 __ subl(value_lo, Immediate(0x40000000)); | 5544 __ subl(value_lo, Immediate(0x40000000)); |
| 5545 |
| 5546 BoxAllocationSlowPath::Allocate( |
| 5547 compiler, this, compiler->mint_class(), out_reg, kNoRegister); |
5789 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); | 5548 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); |
5790 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); | 5549 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); |
5791 __ Bind(&done); | 5550 __ Bind(&done); |
5792 } | 5551 } |
5793 | 5552 |
5794 | 5553 |
5795 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | 5554 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
5796 bool opt) const { | 5555 bool opt) const { |
5797 const intptr_t kNumInputs = 2; | 5556 const intptr_t kNumInputs = 2; |
5798 switch (op_kind()) { | 5557 switch (op_kind()) { |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6331 const intptr_t kNumTemps = 0; | 6090 const intptr_t kNumTemps = 0; |
6332 LocationSummary* summary = new(isolate) LocationSummary( | 6091 LocationSummary* summary = new(isolate) LocationSummary( |
6333 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | 6092 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
6334 summary->set_in(0, Location::RequiresRegister()); | 6093 summary->set_in(0, Location::RequiresRegister()); |
6335 summary->set_out(0, Location::RequiresRegister()); | 6094 summary->set_out(0, Location::RequiresRegister()); |
6336 return summary; | 6095 return summary; |
6337 } | 6096 } |
6338 | 6097 |
6339 | 6098 |
6340 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6099 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6341 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); | |
6342 compiler->AddSlowPathCode(slow_path); | |
6343 Register value = locs()->in(0).reg(); | 6100 Register value = locs()->in(0).reg(); |
6344 Register out = locs()->out(0).reg(); | 6101 Register out = locs()->out(0).reg(); |
6345 ASSERT(value != out); | 6102 ASSERT(value != out); |
6346 | 6103 |
6347 Label not_smi, done; | 6104 Label not_smi, done; |
6348 | 6105 |
6349 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing. | 6106 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing. |
6350 // Test if this value is <= kSmiMax. | 6107 // Test if this value is <= kSmiMax. |
6351 __ cmpl(value, Immediate(kSmiMax)); | 6108 __ cmpl(value, Immediate(kSmiMax)); |
6352 __ j(ABOVE, ¬_smi); | 6109 __ j(ABOVE, ¬_smi); |
6353 // Smi. | 6110 // Smi. |
6354 __ movl(out, value); | 6111 __ movl(out, value); |
6355 __ SmiTag(out); | 6112 __ SmiTag(out); |
6356 __ jmp(&done); | 6113 __ jmp(&done); |
6357 __ Bind(¬_smi); | 6114 __ Bind(¬_smi); |
6358 // Allocate a mint. | 6115 // Allocate a mint. |
6359 __ TryAllocate( | 6116 BoxAllocationSlowPath::Allocate( |
6360 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), | 6117 compiler, this, compiler->mint_class(), out, kNoRegister); |
6361 slow_path->entry_label(), | |
6362 Assembler::kFarJump, | |
6363 out, | |
6364 kNoRegister); | |
6365 __ Bind(slow_path->exit_label()); | |
6366 // Copy low word into mint. | 6118 // Copy low word into mint. |
6367 __ movl(FieldAddress(out, Mint::value_offset()), value); | 6119 __ movl(FieldAddress(out, Mint::value_offset()), value); |
6368 // Zero high word. | 6120 // Zero high word. |
6369 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); | 6121 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); |
6370 __ Bind(&done); | 6122 __ Bind(&done); |
6371 } | 6123 } |
6372 | 6124 |
6373 | 6125 |
6374 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | 6126 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, |
6375 bool opt) const { | 6127 bool opt) const { |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6809 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6561 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6810 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6562 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6811 #endif | 6563 #endif |
6812 } | 6564 } |
6813 | 6565 |
6814 } // namespace dart | 6566 } // namespace dart |
6815 | 6567 |
6816 #undef __ | 6568 #undef __ |
6817 | 6569 |
6818 #endif // defined TARGET_ARCH_IA32 | 6570 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |