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 1766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1777 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1777 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
1778 default: UNREACHABLE(); | 1778 default: UNREACHABLE(); |
1779 } | 1779 } |
1780 | 1780 |
1781 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1781 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
1782 | 1782 |
1783 __ Drop(2); | 1783 __ Drop(2); |
1784 } | 1784 } |
1785 | 1785 |
1786 | 1786 |
1787 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const { | |
1788 if (left()->ResultCid() == kDoubleCid || right()->ResultCid() == kDoubleCid) { | |
1789 const intptr_t kNumInputs = 2; | |
1790 const intptr_t kNumTemps = 0; | |
1791 LocationSummary* summary = | |
1792 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
1793 summary->set_in(0, Location::Any()); | |
1794 summary->set_in(1, Location::Any()); | |
1795 return summary; | |
1796 } else { | |
1797 const intptr_t kNumInputs = 2; | |
1798 const intptr_t kNumTemps = 1; | |
1799 LocationSummary* summary = | |
1800 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
1801 summary->set_in(0, Location::RequiresRegister()); | |
1802 summary->set_in(1, Location::RequiresRegister()); | |
1803 summary->set_temp(0, Location::RequiresRegister()); | |
1804 return summary; | |
1805 } | |
1806 } | |
1807 | |
1808 | |
1809 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
1810 if (left()->ResultCid() == kDoubleCid || right()->ResultCid() == kDoubleCid) { | |
Florian Schneider
2012/08/24 11:09:28
I'd rather eliminate the check by overriding Compu
Vyacheslav Egorov (Google)
2012/08/24 13:23:01
Done.
| |
1811 return; | |
1812 } | |
1813 | |
1814 Label* deopt = compiler->AddDeoptStub(deopt_id(), | |
1815 try_index(), | |
1816 kDeoptBinaryDoubleOp); | |
1817 | |
1818 Register temp = locs()->temp(0).reg(); | |
1819 __ movl(temp, locs()->in(0).reg()); | |
1820 __ orl(temp, locs()->in(1).reg()); | |
1821 __ testl(temp, Immediate(kSmiTagMask)); | |
1822 __ j(ZERO, deopt); | |
1823 } | |
1824 | |
1825 | |
1826 LocationSummary* BoxDoubleComp::MakeLocationSummary() const { | |
1827 const intptr_t kNumInputs = 1; | |
1828 const intptr_t kNumTemps = 0; | |
1829 LocationSummary* summary = | |
1830 new LocationSummary(kNumInputs, | |
1831 kNumTemps, | |
1832 LocationSummary::kCallOnSlowPath); | |
1833 summary->set_in(0, Location::RequiresXmmRegister()); | |
1834 summary->set_out(Location::RequiresRegister()); | |
1835 return summary; | |
1836 } | |
1837 | |
1838 | |
1839 class BoxDoubleSlowPath : public SlowPathCode { | |
1840 public: | |
1841 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) | |
1842 : computation_(computation) { } | |
1843 | |
1844 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
1845 __ Bind(entry_label()); | |
1846 const Class& double_class = compiler->double_class(); | |
1847 const Code& stub = | |
1848 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | |
1849 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | |
1850 | |
1851 // TODO(vegorov): here stack map needs to be set up correctly to skip | |
1852 // double registers. | |
1853 LocationSummary* locs = computation_->locs(); | |
1854 locs->live_registers()->Remove(locs->out()); | |
1855 | |
1856 compiler->SaveLiveRegisters(locs); | |
1857 compiler->GenerateCall(computation_->instance_call()->token_pos(), | |
1858 computation_->instance_call()->try_index(), | |
1859 &label, | |
1860 PcDescriptors::kOther, | |
1861 computation_->locs()->stack_bitmap()); | |
1862 if (EAX != locs->out().reg()) { | |
1863 __ movl(locs->out().reg(), EAX); | |
1864 } | |
1865 compiler->RestoreLiveRegisters(locs); | |
Florian Schneider
2012/08/24 11:09:28
This only works if the output register is not live
Vyacheslav Egorov (Google)
2012/08/24 13:23:01
locs->live_registers()->Remove(locs->out()); <- th
| |
1866 | |
1867 // TODO(vegorov): wrong order of save restore if EAX is live across this | |
Florian Schneider
2012/08/24 11:09:28
How can that happen?
Vyacheslav Egorov (Google)
2012/08/24 13:23:01
This comment is left over from before it was fixed
| |
1868 // code. | |
1869 __ jmp(exit_label()); | |
1870 } | |
1871 | |
1872 private: | |
1873 BoxDoubleComp* computation_; | |
1874 }; | |
1875 | |
1876 | |
1877 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
1878 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | |
1879 compiler->AddSlowPathCode(slow_path); | |
1880 | |
1881 Register out_reg = locs()->out().reg(); | |
1882 XmmRegister value = locs()->in(0).xmm_reg(); | |
1883 | |
1884 AssemblerMacros::TryAllocate(compiler->assembler(), | |
1885 compiler->double_class(), | |
1886 slow_path->entry_label(), | |
1887 Assembler::kFarJump, | |
1888 out_reg); | |
1889 __ Bind(slow_path->exit_label()); | |
1890 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); | |
1891 } | |
1892 | |
1893 | |
1894 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const { | |
1895 const intptr_t v_cid = value()->ResultCid(); | |
1896 | |
1897 const intptr_t kNumInputs = 1; | |
1898 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; | |
1899 LocationSummary* summary = | |
1900 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
1901 summary->set_in(0, Location::RequiresRegister()); | |
1902 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); | |
1903 summary->set_out(Location::RequiresXmmRegister()); | |
1904 return summary; | |
1905 } | |
1906 | |
1907 | |
1908 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
1909 const intptr_t v_cid = value()->ResultCid(); | |
1910 | |
1911 const Register value = locs()->in(0).reg(); | |
1912 const XmmRegister result = locs()->out().xmm_reg(); | |
1913 if (v_cid != kDoubleCid) { | |
1914 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | |
1915 instance_call()->try_index(), | |
1916 kDeoptBinaryDoubleOp); | |
1917 compiler->LoadDoubleOrSmiToXmm(result, | |
1918 value, | |
1919 locs()->temp(0).reg(), | |
1920 deopt); | |
1921 } else { | |
1922 __ movsd(result, FieldAddress(value, Double::value_offset())); | |
1923 } | |
1924 } | |
1925 | |
1926 | |
1927 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const { | |
1928 const intptr_t kNumInputs = 2; | |
1929 const intptr_t kNumTemps = 0; | |
1930 LocationSummary* summary = | |
1931 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
1932 summary->set_in(0, Location::RequiresXmmRegister()); | |
1933 summary->set_in(1, Location::RequiresXmmRegister()); | |
1934 summary->set_out(Location::SameAsFirstInput()); | |
1935 return summary; | |
1936 } | |
1937 | |
1938 | |
1939 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
1940 XmmRegister left = locs()->in(0).xmm_reg(); | |
1941 XmmRegister right = locs()->in(1).xmm_reg(); | |
1942 | |
1943 ASSERT(locs()->out().xmm_reg() == left); | |
1944 | |
1945 switch (op_kind()) { | |
1946 case Token::kADD: __ addsd(left, right); break; | |
1947 case Token::kSUB: __ subsd(left, right); break; | |
1948 case Token::kMUL: __ mulsd(left, right); break; | |
1949 case Token::kDIV: __ divsd(left, right); break; | |
1950 default: UNREACHABLE(); | |
1951 } | |
1952 } | |
1953 | |
1954 | |
1787 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { | 1955 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
1788 const intptr_t kNumInputs = 1; | 1956 const intptr_t kNumInputs = 1; |
1789 const intptr_t kNumTemps = 0; | 1957 const intptr_t kNumTemps = 0; |
1790 LocationSummary* summary = | 1958 LocationSummary* summary = |
1791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1959 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1792 summary->set_in(0, Location::RequiresRegister()); | 1960 summary->set_in(0, Location::RequiresRegister()); |
1793 summary->set_out(Location::SameAsFirstInput()); | 1961 summary->set_out(Location::SameAsFirstInput()); |
1794 return summary; | 1962 return summary; |
1795 } | 1963 } |
1796 | 1964 |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2190 } | 2358 } |
2191 } | 2359 } |
2192 __ Bind(&is_ok); | 2360 __ Bind(&is_ok); |
2193 } | 2361 } |
2194 | 2362 |
2195 } // namespace dart | 2363 } // namespace dart |
2196 | 2364 |
2197 #undef __ | 2365 #undef __ |
2198 | 2366 |
2199 #endif // defined TARGET_ARCH_X64 | 2367 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |