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

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

Issue 14854010: On MIPS, keeps Object::null() in a register. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/object_mips_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 95
96 __ BranchEqual(T2, fp_sp_dist, &stack_ok); 96 __ BranchEqual(T2, fp_sp_dist, &stack_ok);
97 __ break_(0); 97 __ break_(0);
98 98
99 __ Bind(&stack_ok); 99 __ Bind(&stack_ok);
100 } 100 }
101 #endif 101 #endif
102 // This sequence is patched by a debugger breakpoint. There is no need for 102 // This sequence is patched by a debugger breakpoint. There is no need for
103 // extra NOP instructions here because the sequence patched in for a 103 // extra NOP instructions here because the sequence patched in for a
104 // breakpoint is shorter than the sequence here. 104 // breakpoint is shorter than the sequence here.
105 __ LeaveDartFrame(); 105 __ LeaveDartFrameAndReturn();
106 __ Ret();
107 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 106 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
108 Isolate::kNoDeoptId, 107 Isolate::kNoDeoptId,
109 token_pos()); 108 token_pos());
110 } 109 }
111 110
112 111
113 bool IfThenElseInstr::IsSupported() { 112 bool IfThenElseInstr::IsSupported() {
114 return false; 113 return false;
115 } 114 }
116 115
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 1239
1241 LoadValueCid(compiler, value_cid_reg, value_reg); 1240 LoadValueCid(compiler, value_cid_reg, value_reg);
1242 1241
1243 __ lw(TMP1, field_cid_operand); 1242 __ lw(TMP1, field_cid_operand);
1244 __ beq(value_cid_reg, TMP1, &ok); 1243 __ beq(value_cid_reg, TMP1, &ok);
1245 __ lw(TMP1, field_nullability_operand); 1244 __ lw(TMP1, field_nullability_operand);
1246 __ subu(CMPRES, value_cid_reg, TMP1); 1245 __ subu(CMPRES, value_cid_reg, TMP1);
1247 } else if (value_cid == kNullCid) { 1246 } else if (value_cid == kNullCid) {
1248 // TODO(regis): TMP1 may conflict. Revisit. 1247 // TODO(regis): TMP1 may conflict. Revisit.
1249 __ lw(TMP1, field_nullability_operand); 1248 __ lw(TMP1, field_nullability_operand);
1250 __ LoadImmediate(TMP2, value_cid); 1249 __ LoadImmediate(CMPRES, value_cid);
1251 __ subu(CMPRES, TMP1, TMP2); 1250 __ subu(CMPRES, TMP1, CMPRES);
1252 } else { 1251 } else {
1253 // TODO(regis): TMP1 may conflict. Revisit. 1252 // TODO(regis): TMP1 may conflict. Revisit.
1254 __ lw(TMP1, field_cid_operand); 1253 __ lw(TMP1, field_cid_operand);
1255 __ LoadImmediate(TMP2, value_cid); 1254 __ LoadImmediate(CMPRES, value_cid);
1256 __ subu(CMPRES, TMP1, TMP2); 1255 __ subu(CMPRES, TMP1, CMPRES);
1257 } 1256 }
1258 __ beq(CMPRES, ZR, &ok); 1257 __ beq(CMPRES, ZR, &ok);
1259 1258
1260 __ lw(TMP1, field_cid_operand); 1259 __ lw(TMP1, field_cid_operand);
1261 __ BranchNotEqual(TMP1, kIllegalCid, fail); 1260 __ BranchNotEqual(TMP1, kIllegalCid, fail);
1262 1261
1263 if (value_cid == kDynamicCid) { 1262 if (value_cid == kDynamicCid) {
1264 __ sw(value_cid_reg, field_cid_operand); 1263 __ sw(value_cid_reg, field_cid_operand);
1265 __ sw(value_cid_reg, field_nullability_operand); 1264 __ sw(value_cid_reg, field_nullability_operand);
1266 } else { 1265 } else {
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 const intptr_t len = type_arguments().Length(); 1494 const intptr_t len = type_arguments().Length();
1496 if (type_arguments().IsRawInstantiatedRaw(len)) { 1495 if (type_arguments().IsRawInstantiatedRaw(len)) {
1497 __ BranchEqual(instantiator_reg, 1496 __ BranchEqual(instantiator_reg,
1498 reinterpret_cast<intptr_t>(Object::null()), 1497 reinterpret_cast<intptr_t>(Object::null()),
1499 &type_arguments_instantiated); 1498 &type_arguments_instantiated);
1500 } 1499 }
1501 // Instantiate non-null type arguments. 1500 // Instantiate non-null type arguments.
1502 // A runtime call to instantiate the type arguments is required. 1501 // A runtime call to instantiate the type arguments is required.
1503 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1502 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1504 __ LoadObject(TMP1, Object::ZoneHandle()); 1503 __ LoadObject(TMP1, Object::ZoneHandle());
1505 __ LoadObject(TMP2, type_arguments());
1506 __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result. 1504 __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result.
1507 __ sw(TMP2, Address(SP, 1 * kWordSize)); 1505 __ LoadObject(TMP1, type_arguments());
1506 __ sw(TMP1, Address(SP, 1 * kWordSize));
1508 // Push instantiator type arguments. 1507 // Push instantiator type arguments.
1509 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); 1508 __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
1510 1509
1511 compiler->GenerateCallRuntime(token_pos(), 1510 compiler->GenerateCallRuntime(token_pos(),
1512 deopt_id(), 1511 deopt_id(),
1513 kInstantiateTypeArgumentsRuntimeEntry, 1512 kInstantiateTypeArgumentsRuntimeEntry,
1514 locs()); 1513 locs());
1515 // Pop instantiated type arguments. 1514 // Pop instantiated type arguments.
1516 __ lw(result_reg, Address(SP, 2 * kWordSize)); 1515 __ lw(result_reg, Address(SP, 2 * kWordSize));
1517 // Drop instantiator and uninstantiated type arguments. 1516 // Drop instantiator and uninstantiated type arguments.
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 1670
1672 ASSERT(!exception_var().is_captured()); 1671 ASSERT(!exception_var().is_captured());
1673 ASSERT(!stacktrace_var().is_captured()); 1672 ASSERT(!stacktrace_var().is_captured());
1674 1673
1675 __ sw(kExceptionObjectReg, 1674 __ sw(kExceptionObjectReg,
1676 Address(FP, exception_var().index() * kWordSize)); 1675 Address(FP, exception_var().index() * kWordSize));
1677 __ sw(kStackTraceObjectReg, 1676 __ sw(kStackTraceObjectReg,
1678 Address(FP, stacktrace_var().index() * kWordSize)); 1677 Address(FP, stacktrace_var().index() * kWordSize));
1679 1678
1680 Label next; 1679 Label next;
1681 __ mov(TMP1, RA); // Save return adress. 1680 __ mov(T0, RA); // Save return adress.
1682 // Restore the pool pointer. 1681 // Restore the pool pointer.
1683 __ bal(&next); // Branch and link to next instruction to get PC in RA. 1682 __ bal(&next); // Branch and link to next instruction to get PC in RA.
1684 __ delay_slot()->mov(TMP2, RA); // Save PC of the following mov. 1683 __ delay_slot()->mov(T1, RA); // Save PC of the following mov.
1685 1684
1686 // Calculate offset of pool pointer from the PC. 1685 // Calculate offset of pool pointer from the PC.
1687 const intptr_t object_pool_pc_dist = 1686 const intptr_t object_pool_pc_dist =
1688 Instructions::HeaderSize() - Instructions::object_pool_offset() + 1687 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1689 compiler->assembler()->CodeSize(); 1688 compiler->assembler()->CodeSize();
1690 1689
1691 __ Bind(&next); 1690 __ Bind(&next);
1692 __ mov(RA, TMP1); // Restore return address. 1691 __ mov(RA, T0); // Restore return address.
1693 __ lw(PP, Address(TMP2, -object_pool_pc_dist)); 1692 __ lw(PP, Address(T1, -object_pool_pc_dist));
1694 } 1693 }
1695 1694
1696 1695
1697 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { 1696 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const {
1698 const intptr_t kNumInputs = 0; 1697 const intptr_t kNumInputs = 0;
1699 const intptr_t kNumTemps = 0; 1698 const intptr_t kNumTemps = 0;
1700 LocationSummary* summary = 1699 LocationSummary* summary =
1701 new LocationSummary(kNumInputs, 1700 new LocationSummary(kNumInputs,
1702 kNumTemps, 1701 kNumTemps,
1703 LocationSummary::kCallOnSlowPath); 1702 LocationSummary::kCallOnSlowPath);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 const intptr_t kNumInputs = 2; 1750 const intptr_t kNumInputs = 2;
1752 if (op_kind() == Token::kTRUNCDIV) { 1751 if (op_kind() == Token::kTRUNCDIV) {
1753 UNIMPLEMENTED(); 1752 UNIMPLEMENTED();
1754 return NULL; 1753 return NULL;
1755 } else { 1754 } else {
1756 const intptr_t kNumTemps = 0; 1755 const intptr_t kNumTemps = 0;
1757 LocationSummary* summary = 1756 LocationSummary* summary =
1758 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1757 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1759 summary->set_in(0, Location::RequiresRegister()); 1758 summary->set_in(0, Location::RequiresRegister());
1760 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 1759 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
1760 if (op_kind() == Token::kADD) {
1761 // Need an extra temp for the overflow detection code.
1762 summary->set_temp(0, Location::RequiresRegister());
1763 }
1761 // We make use of 3-operand instructions by not requiring result register 1764 // We make use of 3-operand instructions by not requiring result register
1762 // to be identical to first input register as on Intel. 1765 // to be identical to first input register as on Intel.
1763 summary->set_out(Location::RequiresRegister()); 1766 summary->set_out(Location::RequiresRegister());
1764 return summary; 1767 return summary;
1765 } 1768 }
1766 } 1769 }
1767 1770
1768 1771
1769 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1772 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1770 __ TraceSimMsg("BinarySmiOpInstr"); 1773 __ TraceSimMsg("BinarySmiOpInstr");
(...skipping 21 matching lines...) Expand all
1792 } else { 1795 } else {
1793 __ SubImmediateDetectOverflow(result, left, imm, CMPRES); 1796 __ SubImmediateDetectOverflow(result, left, imm, CMPRES);
1794 __ bltz(CMPRES, deopt); 1797 __ bltz(CMPRES, deopt);
1795 } 1798 }
1796 break; 1799 break;
1797 } 1800 }
1798 case Token::kADD: { 1801 case Token::kADD: {
1799 if (deopt == NULL) { 1802 if (deopt == NULL) {
1800 __ AddImmediate(result, left, imm); 1803 __ AddImmediate(result, left, imm);
1801 } else { 1804 } else {
1802 __ AddImmediateDetectOverflow(result, left, imm, CMPRES); 1805 Register temp = locs()->temp(0).reg();
1806 __ AddImmediateDetectOverflow(result, left, imm, CMPRES, temp);
1803 __ bltz(CMPRES, deopt); 1807 __ bltz(CMPRES, deopt);
1804 } 1808 }
1805 break; 1809 break;
1806 } 1810 }
1807 case Token::kMUL: { 1811 case Token::kMUL: {
1808 // Keep left value tagged and untag right value. 1812 // Keep left value tagged and untag right value.
1809 const intptr_t value = Smi::Cast(constant).Value(); 1813 const intptr_t value = Smi::Cast(constant).Value();
1810 if (deopt == NULL) { 1814 if (deopt == NULL) {
1811 if (value == 2) { 1815 if (value == 2) {
1812 __ sll(result, left, 1); 1816 __ sll(result, left, 1);
1813 } else { 1817 } else {
1814 __ LoadImmediate(TMP1, value); 1818 __ LoadImmediate(TMP1, value);
1815 __ mult(left, TMP1); 1819 __ mult(left, TMP1);
1816 __ mflo(result); 1820 __ mflo(result);
1817 } 1821 }
1818 } else { 1822 } else {
1819 if (value == 2) { 1823 if (value == 2) {
1820 __ sra(TMP1, left, 31); // TMP1 = sign of left. 1824 __ sra(TMP1, left, 31); // TMP1 = sign of left.
1821 __ sll(result, left, 1); 1825 __ sll(result, left, 1);
1822 } else { 1826 } else {
1823 __ LoadImmediate(TMP1, value); 1827 __ LoadImmediate(TMP1, value);
1824 __ mult(left, TMP1); 1828 __ mult(left, TMP1);
1825 __ mflo(result); 1829 __ mflo(result);
1826 __ mfhi(TMP1); 1830 __ mfhi(TMP1);
1827 } 1831 }
1828 __ sra(TMP2, result, 31); 1832 __ sra(CMPRES, result, 31);
1829 __ bne(TMP1, TMP2, deopt); 1833 __ bne(TMP1, CMPRES, deopt);
1830 } 1834 }
1831 break; 1835 break;
1832 } 1836 }
1833 case Token::kTRUNCDIV: { 1837 case Token::kTRUNCDIV: {
1834 UNIMPLEMENTED(); 1838 UNIMPLEMENTED();
1835 break; 1839 break;
1836 } 1840 }
1837 case Token::kBIT_AND: { 1841 case Token::kBIT_AND: {
1838 // No overflow check. 1842 // No overflow check.
1839 if (Utils::IsUint(kImmBits, imm)) { 1843 if (Utils::IsUint(kImmBits, imm)) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 } 1879 }
1876 return; 1880 return;
1877 } 1881 }
1878 1882
1879 Register right = locs()->in(1).reg(); 1883 Register right = locs()->in(1).reg();
1880 switch (op_kind()) { 1884 switch (op_kind()) {
1881 case Token::kADD: { 1885 case Token::kADD: {
1882 if (deopt == NULL) { 1886 if (deopt == NULL) {
1883 __ addu(result, left, right); 1887 __ addu(result, left, right);
1884 } else { 1888 } else {
1885 __ AdduDetectOverflow(result, left, right, CMPRES); 1889 Register temp = locs()->temp(0).reg();
1890 __ AdduDetectOverflow(result, left, right, CMPRES, temp);
1886 __ bltz(CMPRES, deopt); 1891 __ bltz(CMPRES, deopt);
1887 } 1892 }
1888 break; 1893 break;
1889 } 1894 }
1890 case Token::kSUB: { 1895 case Token::kSUB: {
1891 if (deopt == NULL) { 1896 if (deopt == NULL) {
1892 __ subu(result, left, right); 1897 __ subu(result, left, right);
1893 } else { 1898 } else {
1894 __ SubuDetectOverflow(result, left, right, CMPRES); 1899 __ SubuDetectOverflow(result, left, right, CMPRES);
1895 __ bltz(CMPRES, deopt); 1900 __ bltz(CMPRES, deopt);
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after
2808 &label, 2813 &label,
2809 PcDescriptors::kOther, 2814 PcDescriptors::kOther,
2810 locs()); 2815 locs());
2811 __ Drop(2); // Discard type arguments and receiver. 2816 __ Drop(2); // Discard type arguments and receiver.
2812 } 2817 }
2813 2818
2814 } // namespace dart 2819 } // namespace dart
2815 2820
2816 #endif // defined TARGET_ARCH_MIPS 2821 #endif // defined TARGET_ARCH_MIPS
2817 2822
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/object_mips_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698