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/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 (kFirstLocalSlotIndex + 1 - compiler->StackSize()) * kWordSize; | 92 (kFirstLocalSlotIndex + 1 - compiler->StackSize()) * kWordSize; |
93 ASSERT(fp_sp_dist <= 0); | 93 ASSERT(fp_sp_dist <= 0); |
94 __ subu(T2, SP, FP); | 94 __ subu(T2, SP, FP); |
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 |
| 103 // extra NOP instructions here because the sequence patched in for a |
| 104 // breakpoint is shorter than the sequence here. |
102 __ LeaveDartFrame(); | 105 __ LeaveDartFrame(); |
103 __ Ret(); | 106 __ Ret(); |
104 | |
105 // Generate 2 NOP instructions so that the debugger can patch the return | |
106 // pattern (1 instruction) with a call to the debug stub (3 instructions). | |
107 __ nop(); | |
108 __ nop(); | |
109 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, | 107 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
110 Isolate::kNoDeoptId, | 108 Isolate::kNoDeoptId, |
111 token_pos()); | 109 token_pos()); |
112 } | 110 } |
113 | 111 |
114 | 112 |
115 bool IfThenElseInstr::IsSupported() { | 113 bool IfThenElseInstr::IsSupported() { |
116 return false; | 114 return false; |
117 } | 115 } |
118 | 116 |
(...skipping 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1675 __ AddImmediate(result, left, imm); | 1673 __ AddImmediate(result, left, imm); |
1676 } else { | 1674 } else { |
1677 __ AddImmediateDetectOverflow(result, left, imm, CMPRES); | 1675 __ AddImmediateDetectOverflow(result, left, imm, CMPRES); |
1678 __ bltz(CMPRES, deopt); | 1676 __ bltz(CMPRES, deopt); |
1679 } | 1677 } |
1680 break; | 1678 break; |
1681 } | 1679 } |
1682 case Token::kMUL: { | 1680 case Token::kMUL: { |
1683 // Keep left value tagged and untag right value. | 1681 // Keep left value tagged and untag right value. |
1684 const intptr_t value = Smi::Cast(constant).Value(); | 1682 const intptr_t value = Smi::Cast(constant).Value(); |
1685 if (value == 2) { | 1683 if (deopt == NULL) { |
1686 __ sll(result, left, 1); | 1684 if (value == 2) { |
| 1685 __ sll(result, left, 1); |
| 1686 } else { |
| 1687 __ LoadImmediate(TMP1, value); |
| 1688 __ mult(left, TMP1); |
| 1689 __ mflo(result); |
| 1690 } |
1687 } else { | 1691 } else { |
1688 __ LoadImmediate(TMP1, value); | 1692 if (value == 2) { |
1689 __ mult(left, TMP1); | 1693 __ sra(TMP1, left, 31); // TMP1 = sign of left. |
1690 __ mflo(result); | 1694 __ sll(result, left, 1); |
1691 } | 1695 } else { |
1692 if (deopt != NULL) { | 1696 __ LoadImmediate(TMP1, value); |
1693 UNIMPLEMENTED(); | 1697 __ mult(left, TMP1); |
| 1698 __ mflo(result); |
| 1699 __ mfhi(TMP1); |
| 1700 } |
| 1701 __ sra(TMP2, result, 31); |
| 1702 __ bne(TMP1, TMP2, deopt); |
1694 } | 1703 } |
1695 break; | 1704 break; |
1696 } | 1705 } |
1697 case Token::kTRUNCDIV: { | 1706 case Token::kTRUNCDIV: { |
1698 UNIMPLEMENTED(); | 1707 UNIMPLEMENTED(); |
1699 break; | 1708 break; |
1700 } | 1709 } |
1701 case Token::kBIT_AND: { | 1710 case Token::kBIT_AND: { |
1702 // No overflow check. | 1711 // No overflow check. |
1703 if (Utils::IsUint(kImmBits, imm)) { | 1712 if (Utils::IsUint(kImmBits, imm)) { |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 Register result = locs()->out().reg(); | 2381 Register result = locs()->out().reg(); |
2373 | 2382 |
2374 __ LoadObject(result, Bool::True()); | 2383 __ LoadObject(result, Bool::True()); |
2375 __ LoadObject(TMP1, Bool::False()); | 2384 __ LoadObject(TMP1, Bool::False()); |
2376 __ subu(CMPRES, value, result); | 2385 __ subu(CMPRES, value, result); |
2377 __ movz(result, TMP1, CMPRES); // If value is True, move False into result. | 2386 __ movz(result, TMP1, CMPRES); // If value is True, move False into result. |
2378 } | 2387 } |
2379 | 2388 |
2380 | 2389 |
2381 LocationSummary* ChainContextInstr::MakeLocationSummary() const { | 2390 LocationSummary* ChainContextInstr::MakeLocationSummary() const { |
2382 UNIMPLEMENTED(); | 2391 return LocationSummary::Make(1, |
2383 return NULL; | 2392 Location::NoLocation(), |
| 2393 LocationSummary::kNoCall); |
2384 } | 2394 } |
2385 | 2395 |
2386 | 2396 |
2387 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2397 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2388 UNIMPLEMENTED(); | 2398 Register context_value = locs()->in(0).reg(); |
| 2399 |
| 2400 // Chain the new context in context_value to its parent in CTX. |
| 2401 __ StoreIntoObject(context_value, |
| 2402 FieldAddress(context_value, Context::parent_offset()), |
| 2403 CTX); |
| 2404 // Set new context as current context. |
| 2405 __ mov(CTX, context_value); |
2389 } | 2406 } |
2390 | 2407 |
2391 | 2408 |
2392 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { | 2409 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { |
2393 UNIMPLEMENTED(); | 2410 const intptr_t kNumInputs = 2; |
2394 return NULL; | 2411 const intptr_t kNumTemps = 0; |
| 2412 LocationSummary* locs = |
| 2413 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2414 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
| 2415 : Location::RequiresRegister()); |
| 2416 locs->set_in(1, Location::RequiresRegister()); |
| 2417 return locs; |
2395 } | 2418 } |
2396 | 2419 |
2397 | 2420 |
2398 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2421 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2399 UNIMPLEMENTED(); | 2422 Register value_reg = locs()->in(0).reg(); |
| 2423 Register dest_reg = locs()->in(1).reg(); |
| 2424 |
| 2425 if (value()->NeedsStoreBuffer()) { |
| 2426 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), |
| 2427 value_reg); |
| 2428 } else { |
| 2429 __ StoreIntoObjectNoBarrier( |
| 2430 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
| 2431 } |
2400 } | 2432 } |
2401 | 2433 |
2402 | 2434 |
2403 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { | 2435 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { |
2404 return MakeCallSummary(); | 2436 return MakeCallSummary(); |
2405 } | 2437 } |
2406 | 2438 |
2407 | 2439 |
2408 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2440 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2409 __ TraceSimMsg("AllocateObjectInstr"); | 2441 __ TraceSimMsg("AllocateObjectInstr"); |
(...skipping 23 matching lines...) Expand all Loading... |
2433 &label, | 2465 &label, |
2434 PcDescriptors::kOther, | 2466 PcDescriptors::kOther, |
2435 locs()); | 2467 locs()); |
2436 __ Drop(2); // Discard type arguments and receiver. | 2468 __ Drop(2); // Discard type arguments and receiver. |
2437 } | 2469 } |
2438 | 2470 |
2439 } // namespace dart | 2471 } // namespace dart |
2440 | 2472 |
2441 #endif // defined TARGET_ARCH_MIPS | 2473 #endif // defined TARGET_ARCH_MIPS |
2442 | 2474 |
OLD | NEW |