| 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 |