Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 10875030: Add support for XMM registers in SSA code generation pipeline. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698