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 1780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1791 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1791 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
1792 default: UNREACHABLE(); | 1792 default: UNREACHABLE(); |
1793 } | 1793 } |
1794 | 1794 |
1795 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1795 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
1796 | 1796 |
1797 __ Drop(2); | 1797 __ Drop(2); |
1798 } | 1798 } |
1799 | 1799 |
1800 | 1800 |
| 1801 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const { |
| 1802 if (left()->ResultCid() == kDoubleCid || right()->ResultCid() == kDoubleCid) { |
| 1803 const intptr_t kNumInputs = 2; |
| 1804 const intptr_t kNumTemps = 0; |
| 1805 LocationSummary* summary = |
| 1806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1807 summary->set_in(0, Location::Any()); |
| 1808 summary->set_in(1, Location::Any()); |
| 1809 return summary; |
| 1810 } else { |
| 1811 const intptr_t kNumInputs = 2; |
| 1812 const intptr_t kNumTemps = 1; |
| 1813 LocationSummary* summary = |
| 1814 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1815 summary->set_in(0, Location::RequiresRegister()); |
| 1816 summary->set_in(1, Location::RequiresRegister()); |
| 1817 summary->set_temp(0, Location::RequiresRegister()); |
| 1818 return summary; |
| 1819 } |
| 1820 } |
| 1821 |
| 1822 |
| 1823 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1824 if (left()->ResultCid() == kDoubleCid || right()->ResultCid() == kDoubleCid) { |
| 1825 return; |
| 1826 } |
| 1827 |
| 1828 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 1829 try_index(), |
| 1830 kDeoptBinaryDoubleOp); |
| 1831 |
| 1832 Register temp = locs()->temp(0).reg(); |
| 1833 __ movq(temp, locs()->in(0).reg()); |
| 1834 __ orq(temp, locs()->in(1).reg()); |
| 1835 __ testl(temp, Immediate(kSmiTagMask)); |
| 1836 __ j(ZERO, deopt); |
| 1837 } |
| 1838 |
| 1839 |
| 1840 LocationSummary* BoxDoubleComp::MakeLocationSummary() const { |
| 1841 const intptr_t kNumInputs = 1; |
| 1842 const intptr_t kNumTemps = 0; |
| 1843 LocationSummary* summary = |
| 1844 new LocationSummary(kNumInputs, |
| 1845 kNumTemps, |
| 1846 LocationSummary::kCallOnSlowPath); |
| 1847 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1848 summary->set_out(Location::RequiresRegister()); |
| 1849 return summary; |
| 1850 } |
| 1851 |
| 1852 |
| 1853 class BoxDoubleSlowPath : public SlowPathCode { |
| 1854 public: |
| 1855 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) |
| 1856 : computation_(computation) { } |
| 1857 |
| 1858 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1859 __ Bind(entry_label()); |
| 1860 const Class& double_class = compiler->double_class(); |
| 1861 const Code& stub = |
| 1862 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1863 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1864 |
| 1865 // TODO(vegorov): here stack map needs to be set up correctly to skip |
| 1866 // double registers. |
| 1867 compiler->SaveLiveRegisters(computation_->locs()); |
| 1868 compiler->GenerateCall(computation_->instance_call()->token_pos(), |
| 1869 computation_->instance_call()->try_index(), |
| 1870 &label, |
| 1871 PcDescriptors::kOther, |
| 1872 computation_->locs()->stack_bitmap()); |
| 1873 compiler->RestoreLiveRegisters(computation_->locs()); |
| 1874 |
| 1875 // TODO(vegorov): wrong order of save restore here is RAX is live |
| 1876 // across the code |
| 1877 if (RAX != computation_->locs()->out().reg()) { |
| 1878 __ movq(computation_->locs()->out().reg(), RAX); |
| 1879 } |
| 1880 __ jmp(exit_label()); |
| 1881 } |
| 1882 |
| 1883 private: |
| 1884 BoxDoubleComp* computation_; |
| 1885 }; |
| 1886 |
| 1887 |
| 1888 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1889 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 1890 compiler->AddSlowPathCode(slow_path); |
| 1891 |
| 1892 Register out_reg = locs()->out().reg(); |
| 1893 XmmRegister value = locs()->in(0).xmm_reg(); |
| 1894 |
| 1895 AssemblerMacros::TryAllocate(compiler->assembler(), |
| 1896 compiler->double_class(), |
| 1897 slow_path->entry_label(), |
| 1898 Assembler::kFarJump, |
| 1899 out_reg); |
| 1900 __ Bind(slow_path->exit_label()); |
| 1901 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
| 1902 } |
| 1903 |
| 1904 |
| 1905 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const { |
| 1906 const intptr_t v_cid = value()->ResultCid(); |
| 1907 |
| 1908 const intptr_t kNumInputs = 1; |
| 1909 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; |
| 1910 LocationSummary* summary = |
| 1911 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1912 summary->set_in(0, Location::RequiresRegister()); |
| 1913 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); |
| 1914 summary->set_out(Location::RequiresXmmRegister()); |
| 1915 return summary; |
| 1916 } |
| 1917 |
| 1918 |
| 1919 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1920 const intptr_t v_cid = value()->ResultCid(); |
| 1921 |
| 1922 const Register value = locs()->in(0).reg(); |
| 1923 const XmmRegister result = locs()->out().xmm_reg(); |
| 1924 if (v_cid != kDoubleCid) { |
| 1925 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1926 instance_call()->try_index(), |
| 1927 kDeoptBinaryDoubleOp); |
| 1928 compiler->LoadDoubleOrSmiToXmm(result, |
| 1929 value, |
| 1930 locs()->temp(0).reg(), |
| 1931 deopt); |
| 1932 } else { |
| 1933 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 1934 } |
| 1935 } |
| 1936 |
| 1937 |
| 1938 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const { |
| 1939 const intptr_t kNumInputs = 2; |
| 1940 const intptr_t kNumTemps = 0; |
| 1941 LocationSummary* summary = |
| 1942 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1943 summary->set_in(0, Location::RequiresXmmRegister()); |
| 1944 summary->set_in(1, Location::RequiresXmmRegister()); |
| 1945 summary->set_out(Location::SameAsFirstInput()); |
| 1946 return summary; |
| 1947 } |
| 1948 |
| 1949 |
| 1950 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1951 XmmRegister left = locs()->in(0).xmm_reg(); |
| 1952 XmmRegister right = locs()->in(1).xmm_reg(); |
| 1953 |
| 1954 ASSERT(locs()->out().xmm_reg() == left); |
| 1955 |
| 1956 switch (op_kind()) { |
| 1957 case Token::kADD: __ addsd(left, right); break; |
| 1958 case Token::kSUB: __ subsd(left, right); break; |
| 1959 case Token::kMUL: __ mulsd(left, right); break; |
| 1960 case Token::kDIV: __ divsd(left, right); break; |
| 1961 default: UNREACHABLE(); |
| 1962 } |
| 1963 } |
| 1964 |
| 1965 |
1801 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { | 1966 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
1802 const intptr_t kNumInputs = 1; | 1967 const intptr_t kNumInputs = 1; |
1803 const intptr_t kNumTemps = 0; | 1968 const intptr_t kNumTemps = 0; |
1804 LocationSummary* summary = | 1969 LocationSummary* summary = |
1805 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1970 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1806 summary->set_in(0, Location::RequiresRegister()); | 1971 summary->set_in(0, Location::RequiresRegister()); |
1807 summary->set_out(Location::SameAsFirstInput()); | 1972 summary->set_out(Location::SameAsFirstInput()); |
1808 return summary; | 1973 return summary; |
1809 } | 1974 } |
1810 | 1975 |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2203 } | 2368 } |
2204 } | 2369 } |
2205 __ Bind(&is_ok); | 2370 __ Bind(&is_ok); |
2206 } | 2371 } |
2207 | 2372 |
2208 } // namespace dart | 2373 } // namespace dart |
2209 | 2374 |
2210 #undef __ | 2375 #undef __ |
2211 | 2376 |
2212 #endif // defined TARGET_ARCH_X64 | 2377 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |