OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 1748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1759 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1759 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
1760 default: UNREACHABLE(); | 1760 default: UNREACHABLE(); |
1761 } | 1761 } |
1762 | 1762 |
1763 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1763 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
1764 | 1764 |
1765 __ Drop(2); | 1765 __ Drop(2); |
1766 } | 1766 } |
1767 | 1767 |
1768 | 1768 |
| 1769 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const { |
| 1770 ASSERT((left()->ResultCid() != kDoubleCid) && |
| 1771 (right()->ResultCid() != kDoubleCid)); |
| 1772 const intptr_t kNumInputs = 2; |
| 1773 const intptr_t kNumTemps = 1; |
| 1774 LocationSummary* summary = |
| 1775 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1776 summary->set_in(0, Location::RequiresRegister()); |
| 1777 summary->set_in(1, Location::RequiresRegister()); |
| 1778 summary->set_temp(0, Location::RequiresRegister()); |
| 1779 return summary; |
| 1780 } |
| 1781 |
| 1782 |
| 1783 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1784 Label* deopt = compiler->AddDeoptStub(instance_call_->deopt_id(), |
| 1785 instance_call_->try_index(), |
| 1786 kDeoptBinaryDoubleOp); |
| 1787 |
| 1788 Register temp = locs()->temp(0).reg(); |
| 1789 __ movl(temp, locs()->in(0).reg()); |
| 1790 __ orl(temp, locs()->in(1).reg()); |
| 1791 __ testl(temp, Immediate(kSmiTagMask)); |
| 1792 __ j(ZERO, deopt); |
| 1793 } |
| 1794 |
| 1795 |
| 1796 LocationSummary* BoxDoubleComp::MakeLocationSummary() const { |
| 1797 const intptr_t kNumInputs = 1; |
| 1798 const intptr_t kNumTemps = 0; |
| 1799 LocationSummary* summary = |
| 1800 new LocationSummary(kNumInputs, |
| 1801 kNumTemps, |
| 1802 LocationSummary::kCallOnSlowPath); |
| 1803 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1804 summary->set_out(Location::RequiresRegister()); |
| 1805 return summary; |
| 1806 } |
| 1807 |
| 1808 |
| 1809 class BoxDoubleSlowPath : public SlowPathCode { |
| 1810 public: |
| 1811 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) |
| 1812 : computation_(computation) { } |
| 1813 |
| 1814 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1815 __ Bind(entry_label()); |
| 1816 const Class& double_class = compiler->double_class(); |
| 1817 const Code& stub = |
| 1818 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1819 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1820 |
| 1821 // TODO(vegorov): here stack map needs to be set up correctly to skip |
| 1822 // double registers. |
| 1823 LocationSummary* locs = computation_->locs(); |
| 1824 locs->live_registers()->Remove(locs->out()); |
| 1825 |
| 1826 compiler->SaveLiveRegisters(locs); |
| 1827 compiler->GenerateCall(computation_->instance_call()->token_pos(), |
| 1828 computation_->instance_call()->try_index(), |
| 1829 &label, |
| 1830 PcDescriptors::kOther, |
| 1831 locs); |
| 1832 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); |
| 1833 compiler->RestoreLiveRegisters(locs); |
| 1834 |
| 1835 __ jmp(exit_label()); |
| 1836 } |
| 1837 |
| 1838 private: |
| 1839 BoxDoubleComp* computation_; |
| 1840 }; |
| 1841 |
| 1842 |
| 1843 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1844 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 1845 compiler->AddSlowPathCode(slow_path); |
| 1846 |
| 1847 Register out_reg = locs()->out().reg(); |
| 1848 XmmRegister value = locs()->in(0).xmm_reg(); |
| 1849 |
| 1850 AssemblerMacros::TryAllocate(compiler->assembler(), |
| 1851 compiler->double_class(), |
| 1852 slow_path->entry_label(), |
| 1853 Assembler::kFarJump, |
| 1854 out_reg); |
| 1855 __ Bind(slow_path->exit_label()); |
| 1856 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
| 1857 } |
| 1858 |
| 1859 |
| 1860 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const { |
| 1861 const intptr_t v_cid = value()->ResultCid(); |
| 1862 |
| 1863 const intptr_t kNumInputs = 1; |
| 1864 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; |
| 1865 LocationSummary* summary = |
| 1866 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1867 summary->set_in(0, Location::RequiresRegister()); |
| 1868 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); |
| 1869 summary->set_out(Location::RequiresXmmRegister()); |
| 1870 return summary; |
| 1871 } |
| 1872 |
| 1873 |
| 1874 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1875 const intptr_t v_cid = value()->ResultCid(); |
| 1876 |
| 1877 const Register value = locs()->in(0).reg(); |
| 1878 const XmmRegister result = locs()->out().xmm_reg(); |
| 1879 if (v_cid != kDoubleCid) { |
| 1880 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1881 instance_call()->try_index(), |
| 1882 kDeoptBinaryDoubleOp); |
| 1883 compiler->LoadDoubleOrSmiToXmm(result, |
| 1884 value, |
| 1885 locs()->temp(0).reg(), |
| 1886 deopt); |
| 1887 } else { |
| 1888 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 1889 } |
| 1890 } |
| 1891 |
| 1892 |
| 1893 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const { |
| 1894 const intptr_t kNumInputs = 2; |
| 1895 const intptr_t kNumTemps = 0; |
| 1896 LocationSummary* summary = |
| 1897 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1898 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1899 summary->set_in(1, Location::RequiresXmmRegister()); |
| 1900 summary->set_out(Location::SameAsFirstInput()); |
| 1901 return summary; |
| 1902 } |
| 1903 |
| 1904 |
| 1905 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1906 XmmRegister left = locs()->in(0).xmm_reg(); |
| 1907 XmmRegister right = locs()->in(1).xmm_reg(); |
| 1908 |
| 1909 ASSERT(locs()->out().xmm_reg() == left); |
| 1910 |
| 1911 switch (op_kind()) { |
| 1912 case Token::kADD: __ addsd(left, right); break; |
| 1913 case Token::kSUB: __ subsd(left, right); break; |
| 1914 case Token::kMUL: __ mulsd(left, right); break; |
| 1915 case Token::kDIV: __ divsd(left, right); break; |
| 1916 default: UNREACHABLE(); |
| 1917 } |
| 1918 } |
| 1919 |
| 1920 |
1769 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { | 1921 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
1770 const intptr_t kNumInputs = 1; | 1922 const intptr_t kNumInputs = 1; |
1771 const intptr_t kNumTemps = 0; | 1923 const intptr_t kNumTemps = 0; |
1772 LocationSummary* summary = | 1924 LocationSummary* summary = |
1773 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1925 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1774 summary->set_in(0, Location::RequiresRegister()); | 1926 summary->set_in(0, Location::RequiresRegister()); |
1775 summary->set_out(Location::SameAsFirstInput()); | 1927 summary->set_out(Location::SameAsFirstInput()); |
1776 return summary; | 1928 return summary; |
1777 } | 1929 } |
1778 | 1930 |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2202 __ testl(value, Immediate(kSmiTagMask)); | 2354 __ testl(value, Immediate(kSmiTagMask)); |
2203 __ j(NOT_ZERO, deopt); | 2355 __ j(NOT_ZERO, deopt); |
2204 } | 2356 } |
2205 | 2357 |
2206 | 2358 |
2207 } // namespace dart | 2359 } // namespace dart |
2208 | 2360 |
2209 #undef __ | 2361 #undef __ |
2210 | 2362 |
2211 #endif // defined TARGET_ARCH_X64 | 2363 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |