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

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

Issue 68663003: Merge TRUNCDIV and MOD into TRUNCDIV_MOD single operation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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) 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 2375 matching lines...) Expand 10 before | Expand all | Expand 10 after
2386 summary->set_out(Location::RequiresRegister()); 2386 summary->set_out(Location::RequiresRegister());
2387 return summary; 2387 return summary;
2388 } 2388 }
2389 if (op_kind() == Token::kMOD) { 2389 if (op_kind() == Token::kMOD) {
2390 summary->set_in(0, Location::RequiresRegister()); 2390 summary->set_in(0, Location::RequiresRegister());
2391 summary->set_in(1, Location::RequiresRegister()); 2391 summary->set_in(1, Location::RequiresRegister());
2392 summary->AddTemp(Location::RequiresRegister()); 2392 summary->AddTemp(Location::RequiresRegister());
2393 summary->set_out(Location::RequiresRegister()); 2393 summary->set_out(Location::RequiresRegister());
2394 return summary; 2394 return summary;
2395 } 2395 }
2396 if (op_kind() == Token::kTRUNCDIVMOD) {
2397 summary->set_in(0, Location::RequiresRegister());
2398 summary->set_in(1, Location::RequiresRegister());
2399 summary->AddTemp(Location::RequiresRegister());
2400 summary->AddTemp(Location::RequiresRegister()); // result_div.
2401 summary->AddTemp(Location::RequiresRegister()); // result_mod.
2402 summary->set_out(Location::RequiresRegister());
2403 return summary;
2404 }
2396 summary->set_in(0, Location::RequiresRegister()); 2405 summary->set_in(0, Location::RequiresRegister());
2397 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 2406 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
2398 if (((op_kind() == Token::kSHL) && !is_truncating()) || 2407 if (((op_kind() == Token::kSHL) && !is_truncating()) ||
2399 (op_kind() == Token::kSHR)) { 2408 (op_kind() == Token::kSHR)) {
2400 summary->AddTemp(Location::RequiresRegister()); 2409 summary->AddTemp(Location::RequiresRegister());
2401 } else if (op_kind() == Token::kADD) { 2410 } else if (op_kind() == Token::kADD) {
2402 // Need an extra temp for the overflow detection code. 2411 // Need an extra temp for the overflow detection code.
2403 summary->set_temp(0, Location::RequiresRegister()); 2412 summary->set_temp(0, Location::RequiresRegister());
2404 } 2413 }
2405 // We make use of 3-operand instructions by not requiring result register 2414 // We make use of 3-operand instructions by not requiring result register
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2653 __ bgez(result, &done); 2662 __ bgez(result, &done);
2654 __ bltz(right, &subtract); 2663 __ bltz(right, &subtract);
2655 __ addu(result, result, TMP); 2664 __ addu(result, result, TMP);
2656 __ b(&done); 2665 __ b(&done);
2657 __ Bind(&subtract); 2666 __ Bind(&subtract);
2658 __ subu(result, result, TMP); 2667 __ subu(result, result, TMP);
2659 __ Bind(&done); 2668 __ Bind(&done);
2660 __ SmiTag(result); 2669 __ SmiTag(result);
2661 break; 2670 break;
2662 } 2671 }
2672 case Token::kTRUNCDIVMOD: {
2673 Register temp = locs()->temp(0).reg();
2674 Register result_div = locs()->temp(1).reg();
2675 Register result_mod = locs()->temp(2).reg();
2676 // Handle divide by zero in runtime.
2677 __ beq(right, ZR, deopt);
2678 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp.
2679 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP.
2680 __ div(temp, TMP);
2681 __ mflo(result_div);
2682 __ mfhi(result_mod);
2683 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
2684 // case we cannot tag the result.
2685 __ BranchEqual(result_div, 0x40000000, deopt);
2686 // res = left % right;
2687 // if (res < 0) {
2688 // if (right < 0) {
2689 // res = res - right;
2690 // } else {
2691 // res = res + right;
2692 // }
2693 // }
2694 Label done, subtract;
2695 __ bgez(result_mod, &done);
2696 __ bltz(right, &subtract);
2697 __ addu(result_mod, result_mod, TMP);
2698 __ b(&done);
2699 __ Bind(&subtract);
2700 __ subu(result_mod, result_mod, TMP);
2701 __ Bind(&done);
2702
2703 __ SmiTag(result_div);
2704 __ SmiTag(result_mod);
2705 __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld)));
2706 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays.
2707 // [0]: divide resut, [1]: mod result.
2708 __ LoadImmediate(temp,
2709 FlowGraphCompiler::DataOffsetFor(kArrayCid) - kHeapObjectTag);
2710 __ addu(temp, result, temp);
2711 Address div_result_address(temp, 0);
2712 Address mod_result_address(temp, kWordSize);
2713 __ StoreIntoObjectNoBarrier(result, div_result_address, result_div);
2714 __ StoreIntoObjectNoBarrier(result, mod_result_address, result_mod);
2715 break;
2716 }
2663 case Token::kSHR: { 2717 case Token::kSHR: {
2664 Register temp = locs()->temp(0).reg(); 2718 Register temp = locs()->temp(0).reg();
2665 if (CanDeoptimize()) { 2719 if (CanDeoptimize()) {
2666 __ bltz(right, deopt); 2720 __ bltz(right, deopt);
2667 } 2721 }
2668 __ sra(temp, right, kSmiTagSize); // SmiUntag right into temp. 2722 __ sra(temp, right, kSmiTagSize); // SmiUntag right into temp.
2669 // sra operation masks the count to 5 bits. 2723 // sra operation masks the count to 5 bits.
2670 const intptr_t kCountLimit = 0x1F; 2724 const intptr_t kCountLimit = 0x1F;
2671 Range* right_range = this->right()->definition()->range(); 2725 Range* right_range = this->right()->definition()->range();
2672 if ((right_range == NULL) || 2726 if ((right_range == NULL) ||
(...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after
3997 compiler->GenerateCall(token_pos(), 4051 compiler->GenerateCall(token_pos(),
3998 &label, 4052 &label,
3999 PcDescriptors::kOther, 4053 PcDescriptors::kOther,
4000 locs()); 4054 locs());
4001 __ Drop(2); // Discard type arguments and receiver. 4055 __ Drop(2); // Discard type arguments and receiver.
4002 } 4056 }
4003 4057
4004 } // namespace dart 4058 } // namespace dart
4005 4059
4006 #endif // defined TARGET_ARCH_MIPS 4060 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698