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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
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 1761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1772 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
1773 default: UNREACHABLE(); | 1773 default: UNREACHABLE(); |
1774 } | 1774 } |
1775 | 1775 |
1776 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1776 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
1777 | 1777 |
1778 __ Drop(2); | 1778 __ Drop(2); |
1779 } | 1779 } |
1780 | 1780 |
1781 | 1781 |
| 1782 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const { |
| 1783 ASSERT((left()->ResultCid() != kDoubleCid) && |
| 1784 (right()->ResultCid() != kDoubleCid)); |
| 1785 const intptr_t kNumInputs = 2; |
| 1786 const intptr_t kNumTemps = 1; |
| 1787 LocationSummary* summary = |
| 1788 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1789 summary->set_in(0, Location::RequiresRegister()); |
| 1790 summary->set_in(1, Location::RequiresRegister()); |
| 1791 summary->set_temp(0, Location::RequiresRegister()); |
| 1792 return summary; |
| 1793 } |
| 1794 |
| 1795 |
| 1796 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1797 Label* deopt = compiler->AddDeoptStub(instance_call_->deopt_id(), |
| 1798 instance_call_->try_index(), |
| 1799 kDeoptBinaryDoubleOp); |
| 1800 |
| 1801 Register temp = locs()->temp(0).reg(); |
| 1802 __ movq(temp, locs()->in(0).reg()); |
| 1803 __ orq(temp, locs()->in(1).reg()); |
| 1804 __ testl(temp, Immediate(kSmiTagMask)); |
| 1805 __ j(ZERO, deopt); |
| 1806 } |
| 1807 |
| 1808 |
| 1809 LocationSummary* BoxDoubleComp::MakeLocationSummary() const { |
| 1810 const intptr_t kNumInputs = 1; |
| 1811 const intptr_t kNumTemps = 0; |
| 1812 LocationSummary* summary = |
| 1813 new LocationSummary(kNumInputs, |
| 1814 kNumTemps, |
| 1815 LocationSummary::kCallOnSlowPath); |
| 1816 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1817 summary->set_out(Location::RequiresRegister()); |
| 1818 return summary; |
| 1819 } |
| 1820 |
| 1821 |
| 1822 class BoxDoubleSlowPath : public SlowPathCode { |
| 1823 public: |
| 1824 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) |
| 1825 : computation_(computation) { } |
| 1826 |
| 1827 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1828 __ Bind(entry_label()); |
| 1829 const Class& double_class = compiler->double_class(); |
| 1830 const Code& stub = |
| 1831 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1832 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1833 |
| 1834 // TODO(vegorov): here stack map needs to be set up correctly to skip |
| 1835 // double registers. |
| 1836 LocationSummary* locs = computation_->locs(); |
| 1837 locs->live_registers()->Remove(locs->out()); |
| 1838 |
| 1839 compiler->SaveLiveRegisters(locs); |
| 1840 compiler->GenerateCall(computation_->instance_call()->token_pos(), |
| 1841 computation_->instance_call()->try_index(), |
| 1842 &label, |
| 1843 PcDescriptors::kOther, |
| 1844 locs); |
| 1845 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); |
| 1846 compiler->RestoreLiveRegisters(locs); |
| 1847 |
| 1848 __ jmp(exit_label()); |
| 1849 } |
| 1850 |
| 1851 private: |
| 1852 BoxDoubleComp* computation_; |
| 1853 }; |
| 1854 |
| 1855 |
| 1856 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1857 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 1858 compiler->AddSlowPathCode(slow_path); |
| 1859 |
| 1860 Register out_reg = locs()->out().reg(); |
| 1861 XmmRegister value = locs()->in(0).xmm_reg(); |
| 1862 |
| 1863 AssemblerMacros::TryAllocate(compiler->assembler(), |
| 1864 compiler->double_class(), |
| 1865 slow_path->entry_label(), |
| 1866 Assembler::kFarJump, |
| 1867 out_reg); |
| 1868 __ Bind(slow_path->exit_label()); |
| 1869 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
| 1870 } |
| 1871 |
| 1872 |
| 1873 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const { |
| 1874 const intptr_t v_cid = value()->ResultCid(); |
| 1875 |
| 1876 const intptr_t kNumInputs = 1; |
| 1877 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; |
| 1878 LocationSummary* summary = |
| 1879 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1880 summary->set_in(0, Location::RequiresRegister()); |
| 1881 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); |
| 1882 summary->set_out(Location::RequiresXmmRegister()); |
| 1883 return summary; |
| 1884 } |
| 1885 |
| 1886 |
| 1887 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1888 const intptr_t v_cid = value()->ResultCid(); |
| 1889 |
| 1890 const Register value = locs()->in(0).reg(); |
| 1891 const XmmRegister result = locs()->out().xmm_reg(); |
| 1892 if (v_cid != kDoubleCid) { |
| 1893 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1894 instance_call()->try_index(), |
| 1895 kDeoptBinaryDoubleOp); |
| 1896 compiler->LoadDoubleOrSmiToXmm(result, |
| 1897 value, |
| 1898 locs()->temp(0).reg(), |
| 1899 deopt); |
| 1900 } else { |
| 1901 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 1902 } |
| 1903 } |
| 1904 |
| 1905 |
| 1906 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const { |
| 1907 const intptr_t kNumInputs = 2; |
| 1908 const intptr_t kNumTemps = 0; |
| 1909 LocationSummary* summary = |
| 1910 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1911 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1912 summary->set_in(1, Location::RequiresXmmRegister()); |
| 1913 summary->set_out(Location::SameAsFirstInput()); |
| 1914 return summary; |
| 1915 } |
| 1916 |
| 1917 |
| 1918 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1919 XmmRegister left = locs()->in(0).xmm_reg(); |
| 1920 XmmRegister right = locs()->in(1).xmm_reg(); |
| 1921 |
| 1922 ASSERT(locs()->out().xmm_reg() == left); |
| 1923 |
| 1924 switch (op_kind()) { |
| 1925 case Token::kADD: __ addsd(left, right); break; |
| 1926 case Token::kSUB: __ subsd(left, right); break; |
| 1927 case Token::kMUL: __ mulsd(left, right); break; |
| 1928 case Token::kDIV: __ divsd(left, right); break; |
| 1929 default: UNREACHABLE(); |
| 1930 } |
| 1931 } |
| 1932 |
| 1933 |
1782 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { | 1934 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
1783 const intptr_t kNumInputs = 1; | 1935 const intptr_t kNumInputs = 1; |
1784 const intptr_t kNumTemps = 0; | 1936 const intptr_t kNumTemps = 0; |
1785 LocationSummary* summary = | 1937 LocationSummary* summary = |
1786 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1938 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1787 summary->set_in(0, Location::RequiresRegister()); | 1939 summary->set_in(0, Location::RequiresRegister()); |
1788 summary->set_out(Location::SameAsFirstInput()); | 1940 summary->set_out(Location::SameAsFirstInput()); |
1789 return summary; | 1941 return summary; |
1790 } | 1942 } |
1791 | 1943 |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2214 __ testq(value, Immediate(kSmiTagMask)); | 2366 __ testq(value, Immediate(kSmiTagMask)); |
2215 __ j(NOT_ZERO, deopt); | 2367 __ j(NOT_ZERO, deopt); |
2216 } | 2368 } |
2217 | 2369 |
2218 | 2370 |
2219 } // namespace dart | 2371 } // namespace dart |
2220 | 2372 |
2221 #undef __ | 2373 #undef __ |
2222 | 2374 |
2223 #endif // defined TARGET_ARCH_X64 | 2375 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |