| 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 "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 2382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2393 if (RightIsPowerOfTwoConstant()) { | 2393 if (RightIsPowerOfTwoConstant()) { |
| 2394 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2394 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
| 2395 summary->set_in(1, Location::Constant(right_constant->value())); | 2395 summary->set_in(1, Location::Constant(right_constant->value())); |
| 2396 } else { | 2396 } else { |
| 2397 summary->set_in(1, Location::RequiresRegister()); | 2397 summary->set_in(1, Location::RequiresRegister()); |
| 2398 } | 2398 } |
| 2399 summary->AddTemp(Location::RequiresRegister()); | 2399 summary->AddTemp(Location::RequiresRegister()); |
| 2400 summary->set_out(Location::RequiresRegister()); | 2400 summary->set_out(Location::RequiresRegister()); |
| 2401 return summary; | 2401 return summary; |
| 2402 } | 2402 } |
| 2403 if (op_kind() == Token::kMOD) { |
| 2404 summary->set_in(0, Location::RequiresRegister()); |
| 2405 summary->set_in(1, Location::RequiresRegister()); |
| 2406 summary->AddTemp(Location::RequiresRegister()); |
| 2407 summary->set_out(Location::RequiresRegister()); |
| 2408 return summary; |
| 2409 } |
| 2403 summary->set_in(0, Location::RequiresRegister()); | 2410 summary->set_in(0, Location::RequiresRegister()); |
| 2404 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | 2411 summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| 2405 if (((op_kind() == Token::kSHL) && !is_truncating()) || | 2412 if (((op_kind() == Token::kSHL) && !is_truncating()) || |
| 2406 (op_kind() == Token::kSHR)) { | 2413 (op_kind() == Token::kSHR)) { |
| 2407 summary->AddTemp(Location::RequiresRegister()); | 2414 summary->AddTemp(Location::RequiresRegister()); |
| 2408 } else if (op_kind() == Token::kADD) { | 2415 } else if (op_kind() == Token::kADD) { |
| 2409 // Need an extra temp for the overflow detection code. | 2416 // Need an extra temp for the overflow detection code. |
| 2410 summary->set_temp(0, Location::RequiresRegister()); | 2417 summary->set_temp(0, Location::RequiresRegister()); |
| 2411 } | 2418 } |
| 2412 // We make use of 3-operand instructions by not requiring result register | 2419 // We make use of 3-operand instructions by not requiring result register |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2633 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. | 2640 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2634 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. | 2641 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. |
| 2635 __ div(temp, TMP); | 2642 __ div(temp, TMP); |
| 2636 __ mflo(result); | 2643 __ mflo(result); |
| 2637 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 2644 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 2638 // case we cannot tag the result. | 2645 // case we cannot tag the result. |
| 2639 __ BranchEqual(result, 0x40000000, deopt); | 2646 __ BranchEqual(result, 0x40000000, deopt); |
| 2640 __ SmiTag(result); | 2647 __ SmiTag(result); |
| 2641 break; | 2648 break; |
| 2642 } | 2649 } |
| 2650 case Token::kMOD: { |
| 2651 // Handle divide by zero in runtime. |
| 2652 __ beq(right, ZR, deopt); |
| 2653 Register temp = locs()->temp(0).reg(); |
| 2654 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2655 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. |
| 2656 __ div(temp, TMP); |
| 2657 __ mfhi(result); |
| 2658 // res = left % right; |
| 2659 // if (res < 0) { |
| 2660 // if (right < 0) { |
| 2661 // res = res - right; |
| 2662 // } else { |
| 2663 // res = res + right; |
| 2664 // } |
| 2665 // } |
| 2666 Label done, subtract; |
| 2667 __ bgez(result, &done); |
| 2668 __ bltz(right, &subtract); |
| 2669 __ addu(result, result, TMP); |
| 2670 __ b(&done); |
| 2671 __ Bind(&subtract); |
| 2672 __ subu(result, result, TMP); |
| 2673 __ Bind(&done); |
| 2674 __ SmiTag(result); |
| 2675 break; |
| 2676 } |
| 2643 case Token::kSHR: { | 2677 case Token::kSHR: { |
| 2644 Register temp = locs()->temp(0).reg(); | 2678 Register temp = locs()->temp(0).reg(); |
| 2645 if (CanDeoptimize()) { | 2679 if (CanDeoptimize()) { |
| 2646 __ bltz(right, deopt); | 2680 __ bltz(right, deopt); |
| 2647 } | 2681 } |
| 2648 __ sra(temp, right, kSmiTagSize); // SmiUntag right into temp. | 2682 __ sra(temp, right, kSmiTagSize); // SmiUntag right into temp. |
| 2649 // sra operation masks the count to 5 bits. | 2683 // sra operation masks the count to 5 bits. |
| 2650 const intptr_t kCountLimit = 0x1F; | 2684 const intptr_t kCountLimit = 0x1F; |
| 2651 Range* right_range = this->right()->definition()->range(); | 2685 Range* right_range = this->right()->definition()->range(); |
| 2652 if ((right_range == NULL) || | 2686 if ((right_range == NULL) || |
| 2653 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { | 2687 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { |
| 2654 Label ok; | 2688 Label ok; |
| 2655 __ BranchSignedLessEqual(temp, kCountLimit, &ok); | 2689 __ BranchSignedLessEqual(temp, kCountLimit, &ok); |
| 2656 __ LoadImmediate(temp, kCountLimit); | 2690 __ LoadImmediate(temp, kCountLimit); |
| 2657 __ Bind(&ok); | 2691 __ Bind(&ok); |
| 2658 } | 2692 } |
| 2659 | 2693 |
| 2660 __ sra(CMPRES1, left, kSmiTagSize); // SmiUntag left into CMPRES1. | 2694 __ sra(CMPRES1, left, kSmiTagSize); // SmiUntag left into CMPRES1. |
| 2661 __ srav(result, CMPRES1, temp); | 2695 __ srav(result, CMPRES1, temp); |
| 2662 __ SmiTag(result); | 2696 __ SmiTag(result); |
| 2663 break; | 2697 break; |
| 2664 } | 2698 } |
| 2665 case Token::kDIV: { | 2699 case Token::kDIV: { |
| 2666 // Dispatches to 'Double./'. | 2700 // Dispatches to 'Double./'. |
| 2667 // TODO(srdjan): Implement as conversion to double and double division. | 2701 // TODO(srdjan): Implement as conversion to double and double division. |
| 2668 UNREACHABLE(); | 2702 UNREACHABLE(); |
| 2669 break; | 2703 break; |
| 2670 } | 2704 } |
| 2671 case Token::kMOD: { | |
| 2672 // TODO(srdjan): Implement. | |
| 2673 UNREACHABLE(); | |
| 2674 break; | |
| 2675 } | |
| 2676 case Token::kOR: | 2705 case Token::kOR: |
| 2677 case Token::kAND: { | 2706 case Token::kAND: { |
| 2678 // Flow graph builder has dissected this operation to guarantee correct | 2707 // Flow graph builder has dissected this operation to guarantee correct |
| 2679 // behavior (short-circuit evaluation). | 2708 // behavior (short-circuit evaluation). |
| 2680 UNREACHABLE(); | 2709 UNREACHABLE(); |
| 2681 break; | 2710 break; |
| 2682 } | 2711 } |
| 2683 default: | 2712 default: |
| 2684 UNREACHABLE(); | 2713 UNREACHABLE(); |
| 2685 break; | 2714 break; |
| (...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3995 compiler->GenerateCall(token_pos(), | 4024 compiler->GenerateCall(token_pos(), |
| 3996 &label, | 4025 &label, |
| 3997 PcDescriptors::kOther, | 4026 PcDescriptors::kOther, |
| 3998 locs()); | 4027 locs()); |
| 3999 __ Drop(2); // Discard type arguments and receiver. | 4028 __ Drop(2); // Discard type arguments and receiver. |
| 4000 } | 4029 } |
| 4001 | 4030 |
| 4002 } // namespace dart | 4031 } // namespace dart |
| 4003 | 4032 |
| 4004 #endif // defined TARGET_ARCH_MIPS | 4033 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |