| OLD | NEW |
| 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/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 __ addiu(SP, SP, Immediate(-6 * kWordSize)); | 596 __ addiu(SP, SP, Immediate(-6 * kWordSize)); |
| 597 __ LoadObject(TMP, Object::ZoneHandle()); | 597 __ LoadObject(TMP, Object::ZoneHandle()); |
| 598 __ sw(TMP, Address(SP, 5 * kWordSize)); // Make room for the result. | 598 __ sw(TMP, Address(SP, 5 * kWordSize)); // Make room for the result. |
| 599 __ sw(A0, Address(SP, 4 * kWordSize)); // Push the instance. | 599 __ sw(A0, Address(SP, 4 * kWordSize)); // Push the instance. |
| 600 __ LoadObject(TMP, type); | 600 __ LoadObject(TMP, type); |
| 601 __ sw(TMP, Address(SP, 3 * kWordSize)); // Push the type. | 601 __ sw(TMP, Address(SP, 3 * kWordSize)); // Push the type. |
| 602 __ sw(A2, Address(SP, 2 * kWordSize)); // Push instantiator. | 602 __ sw(A2, Address(SP, 2 * kWordSize)); // Push instantiator. |
| 603 __ sw(A1, Address(SP, 1 * kWordSize)); // Push type arguments. | 603 __ sw(A1, Address(SP, 1 * kWordSize)); // Push type arguments. |
| 604 __ LoadObject(A0, test_cache); | 604 __ LoadObject(A0, test_cache); |
| 605 __ sw(A0, Address(SP, 0 * kWordSize)); | 605 __ sw(A0, Address(SP, 0 * kWordSize)); |
| 606 GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs); | 606 GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs); |
| 607 // Pop the parameters supplied to the runtime entry. The result of the | 607 // Pop the parameters supplied to the runtime entry. The result of the |
| 608 // instanceof runtime call will be left as the result of the operation. | 608 // instanceof runtime call will be left as the result of the operation. |
| 609 __ lw(T0, Address(SP, 5 * kWordSize)); | 609 __ lw(T0, Address(SP, 5 * kWordSize)); |
| 610 __ addiu(SP, SP, Immediate(6 * kWordSize)); | 610 __ addiu(SP, SP, Immediate(6 * kWordSize)); |
| 611 if (negate_result) { | 611 if (negate_result) { |
| 612 __ LoadObject(V0, Bool::True()); | 612 __ LoadObject(V0, Bool::True()); |
| 613 __ bne(T0, V0, &done); | 613 __ bne(T0, V0, &done); |
| 614 __ LoadObject(V0, Bool::False()); | 614 __ LoadObject(V0, Bool::False()); |
| 615 } else { | 615 } else { |
| 616 __ mov(V0, T0); | 616 __ mov(V0, T0); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 | 684 |
| 685 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 685 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
| 686 __ LoadObject(TMP1, Object::ZoneHandle()); | 686 __ LoadObject(TMP1, Object::ZoneHandle()); |
| 687 __ sw(TMP1, Address(SP, 3 * kWordSize)); // Make room for the result. | 687 __ sw(TMP1, Address(SP, 3 * kWordSize)); // Make room for the result. |
| 688 __ sw(A0, Address(SP, 2 * kWordSize)); // Push the source object. | 688 __ sw(A0, Address(SP, 2 * kWordSize)); // Push the source object. |
| 689 __ LoadObject(TMP1, dst_name); | 689 __ LoadObject(TMP1, dst_name); |
| 690 __ sw(TMP1, Address(SP, 1 * kWordSize)); // Push the destination name. | 690 __ sw(TMP1, Address(SP, 1 * kWordSize)); // Push the destination name. |
| 691 __ LoadObject(TMP1, error_message); | 691 __ LoadObject(TMP1, error_message); |
| 692 __ sw(TMP1, Address(SP, 0 * kWordSize)); | 692 __ sw(TMP1, Address(SP, 0 * kWordSize)); |
| 693 | 693 |
| 694 GenerateCallRuntime(token_pos, | 694 GenerateRuntimeCall(token_pos, |
| 695 deopt_id, | 695 deopt_id, |
| 696 kMalformedTypeErrorRuntimeEntry, | 696 kMalformedTypeErrorRuntimeEntry, |
| 697 3, | 697 3, |
| 698 locs); | 698 locs); |
| 699 // We should never return here. | 699 // We should never return here. |
| 700 __ break_(0); | 700 __ break_(0); |
| 701 | 701 |
| 702 __ Bind(&is_assignable); // For a null object. | 702 __ Bind(&is_assignable); // For a null object. |
| 703 // Restore instantiator and its type arguments. | 703 // Restore instantiator and its type arguments. |
| 704 __ lw(A1, Address(SP, 0 * kWordSize)); | 704 __ lw(A1, Address(SP, 0 * kWordSize)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 723 __ sw(A0, Address(SP, 5 * kWordSize)); // Push the source object. | 723 __ sw(A0, Address(SP, 5 * kWordSize)); // Push the source object. |
| 724 __ LoadObject(TMP1, dst_type); | 724 __ LoadObject(TMP1, dst_type); |
| 725 __ sw(TMP1, Address(SP, 4 * kWordSize)); // Push the type of the destination. | 725 __ sw(TMP1, Address(SP, 4 * kWordSize)); // Push the type of the destination. |
| 726 __ sw(A2, Address(SP, 3 * kWordSize)); // Push instantiator. | 726 __ sw(A2, Address(SP, 3 * kWordSize)); // Push instantiator. |
| 727 __ sw(A1, Address(SP, 2 * kWordSize)); // Push type arguments. | 727 __ sw(A1, Address(SP, 2 * kWordSize)); // Push type arguments. |
| 728 __ LoadObject(TMP1, dst_name); | 728 __ LoadObject(TMP1, dst_name); |
| 729 __ sw(TMP1, Address(SP, 1 * kWordSize)); // Push the name of the destination. | 729 __ sw(TMP1, Address(SP, 1 * kWordSize)); // Push the name of the destination. |
| 730 __ LoadObject(T0, test_cache); | 730 __ LoadObject(T0, test_cache); |
| 731 __ sw(T0, Address(SP, 0 * kWordSize)); | 731 __ sw(T0, Address(SP, 0 * kWordSize)); |
| 732 | 732 |
| 733 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); | 733 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); |
| 734 // Pop the parameters supplied to the runtime entry. The result of the | 734 // Pop the parameters supplied to the runtime entry. The result of the |
| 735 // type check runtime call is the checked value. | 735 // type check runtime call is the checked value. |
| 736 __ lw(A0, Address(SP, 6 * kWordSize)); | 736 __ lw(A0, Address(SP, 6 * kWordSize)); |
| 737 __ addiu(SP, SP, Immediate(7 * kWordSize)); | 737 __ addiu(SP, SP, Immediate(7 * kWordSize)); |
| 738 | 738 |
| 739 __ Bind(&is_assignable); | 739 __ Bind(&is_assignable); |
| 740 // Restore instantiator and its type arguments. | 740 // Restore instantiator and its type arguments. |
| 741 __ lw(A1, Address(SP, 0 * kWordSize)); | 741 __ lw(A1, Address(SP, 0 * kWordSize)); |
| 742 __ lw(A2, Address(SP, 1 * kWordSize)); | 742 __ lw(A2, Address(SP, 1 * kWordSize)); |
| 743 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 743 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1265 } else { | 1265 } else { |
| 1266 // Add deoptimization continuation point after the call and before the | 1266 // Add deoptimization continuation point after the call and before the |
| 1267 // arguments are removed. | 1267 // arguments are removed. |
| 1268 AddCurrentDescriptor(PcDescriptors::kDeopt, | 1268 AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 1269 deopt_id_after, | 1269 deopt_id_after, |
| 1270 token_pos); | 1270 token_pos); |
| 1271 } | 1271 } |
| 1272 } | 1272 } |
| 1273 | 1273 |
| 1274 | 1274 |
| 1275 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, | 1275 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos, |
| 1276 intptr_t deopt_id, | 1276 intptr_t deopt_id, |
| 1277 const RuntimeEntry& entry, | 1277 const RuntimeEntry& entry, |
| 1278 intptr_t argument_count, | 1278 intptr_t argument_count, |
| 1279 LocationSummary* locs) { | 1279 LocationSummary* locs) { |
| 1280 __ CallRuntime(entry, argument_count); | 1280 __ CallRuntime(entry, argument_count); |
| 1281 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); | 1281 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); |
| 1282 RecordSafepoint(locs); | 1282 RecordSafepoint(locs); |
| 1283 if (deopt_id != Isolate::kNoDeoptId) { | 1283 if (deopt_id != Isolate::kNoDeoptId) { |
| 1284 // Marks either the continuation point in unoptimized code or the | 1284 // Marks either the continuation point in unoptimized code or the |
| 1285 // deoptimization point in optimized code, after call. | 1285 // deoptimization point in optimized code, after call. |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 __ lw(right, Address(SP, 0 * kWordSize)); | 1545 __ lw(right, Address(SP, 0 * kWordSize)); |
| 1546 __ lw(left, Address(SP, 1 * kWordSize)); | 1546 __ lw(left, Address(SP, 1 * kWordSize)); |
| 1547 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 1547 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 1548 } else { | 1548 } else { |
| 1549 __ slt(CMPRES1, left, right); | 1549 __ slt(CMPRES1, left, right); |
| 1550 __ slt(CMPRES2, right, left); | 1550 __ slt(CMPRES2, right, left); |
| 1551 } | 1551 } |
| 1552 } | 1552 } |
| 1553 | 1553 |
| 1554 | 1554 |
| 1555 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and |
| 1556 // FlowGraphCompiler::SlowPathEnvironmentFor. |
| 1555 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { | 1557 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { |
| 1556 __ TraceSimMsg("SaveLiveRegisters"); | 1558 __ TraceSimMsg("SaveLiveRegisters"); |
| 1557 // TODO(vegorov): consider saving only caller save (volatile) registers. | 1559 // TODO(vegorov): consider saving only caller save (volatile) registers. |
| 1558 const intptr_t fpu_regs_count= locs->live_registers()->fpu_regs_count(); | 1560 const intptr_t fpu_regs_count= locs->live_registers()->FpuRegisterCount(); |
| 1559 if (fpu_regs_count > 0) { | 1561 if (fpu_regs_count > 0) { |
| 1560 __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize)); | 1562 __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize)); |
| 1561 // Store fpu registers with the lowest register number at the lowest | 1563 // Store fpu registers with the lowest register number at the lowest |
| 1562 // address. | 1564 // address. |
| 1563 intptr_t offset = 0; | 1565 intptr_t offset = 0; |
| 1564 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { | 1566 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { |
| 1565 DRegister fpu_reg = static_cast<DRegister>(reg_idx); | 1567 DRegister fpu_reg = static_cast<DRegister>(reg_idx); |
| 1566 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { | 1568 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { |
| 1567 __ StoreDToOffset(fpu_reg, SP, offset); | 1569 __ StoreDToOffset(fpu_reg, SP, offset); |
| 1568 offset += kFpuRegisterSize; | 1570 offset += kFpuRegisterSize; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 | 1602 |
| 1601 for (int i = 0; i < kNumberOfCpuRegisters; i++) { | 1603 for (int i = 0; i < kNumberOfCpuRegisters; i++) { |
| 1602 Register r = static_cast<Register>(i); | 1604 Register r = static_cast<Register>(i); |
| 1603 if (locs->live_registers()->ContainsRegister(r)) { | 1605 if (locs->live_registers()->ContainsRegister(r)) { |
| 1604 __ lw(r, Address(SP, registers_popped * kWordSize)); | 1606 __ lw(r, Address(SP, registers_popped * kWordSize)); |
| 1605 registers_popped++; | 1607 registers_popped++; |
| 1606 } | 1608 } |
| 1607 } | 1609 } |
| 1608 __ addiu(SP, SP, Immediate(register_count * kWordSize)); | 1610 __ addiu(SP, SP, Immediate(register_count * kWordSize)); |
| 1609 | 1611 |
| 1610 const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count(); | 1612 const intptr_t fpu_regs_count = locs->live_registers()->FpuRegisterCount(); |
| 1611 if (fpu_regs_count > 0) { | 1613 if (fpu_regs_count > 0) { |
| 1612 // Fpu registers have the lowest register number at the lowest address. | 1614 // Fpu registers have the lowest register number at the lowest address. |
| 1613 intptr_t offset = 0; | 1615 intptr_t offset = 0; |
| 1614 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { | 1616 for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; ++reg_idx) { |
| 1615 DRegister fpu_reg = static_cast<DRegister>(reg_idx); | 1617 DRegister fpu_reg = static_cast<DRegister>(reg_idx); |
| 1616 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { | 1618 if (locs->live_registers()->ContainsFpuRegister(fpu_reg)) { |
| 1617 __ LoadDFromOffset(fpu_reg, SP, offset); | 1619 __ LoadDFromOffset(fpu_reg, SP, offset); |
| 1618 offset += kFpuRegisterSize; | 1620 offset += kFpuRegisterSize; |
| 1619 } | 1621 } |
| 1620 } | 1622 } |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2006 __ AddImmediate(SP, kDoubleSize); | 2008 __ AddImmediate(SP, kDoubleSize); |
| 2007 } | 2009 } |
| 2008 | 2010 |
| 2009 | 2011 |
| 2010 #undef __ | 2012 #undef __ |
| 2011 | 2013 |
| 2012 | 2014 |
| 2013 } // namespace dart | 2015 } // namespace dart |
| 2014 | 2016 |
| 2015 #endif // defined TARGET_ARCH_MIPS | 2017 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |