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

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

Issue 817593002: Improve generated MIPS code for conditional expressions and branches by delaying (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 12 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/intermediate_language_mips.cc ('k') | runtime/vm/simulator_arm.h » ('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/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 __ BranchNotEqual(CMPRES1, Immediate(kMintCid), not_smi_or_mint); 678 __ BranchNotEqual(CMPRES1, Immediate(kMintCid), not_smi_or_mint);
679 679
680 // Mint. 680 // Mint.
681 __ lw(res_lo, FieldAddress(reg, Mint::value_offset())); 681 __ lw(res_lo, FieldAddress(reg, Mint::value_offset()));
682 __ lw(res_hi, FieldAddress(reg, Mint::value_offset() + kWordSize)); 682 __ lw(res_hi, FieldAddress(reg, Mint::value_offset() + kWordSize));
683 __ Bind(&done); 683 __ Bind(&done);
684 return; 684 return;
685 } 685 }
686 686
687 687
688 static void CompareIntegers(Assembler* assembler, Condition true_condition) { 688 static void CompareIntegers(Assembler* assembler, RelationOperator rel_op) {
689 Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through; 689 Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
690 TestBothArgumentsSmis(assembler, &try_mint_smi); 690 TestBothArgumentsSmis(assembler, &try_mint_smi);
691 // T0 contains the right argument. T1 contains left argument 691 // T0 contains the right argument. T1 contains left argument
692 692
693 switch (true_condition) { 693 switch (rel_op) {
694 case LT: __ BranchSignedLess(T1, T0, &is_true); break; 694 case LT: __ BranchSignedLess(T1, T0, &is_true); break;
695 case LE: __ BranchSignedLessEqual(T1, T0, &is_true); break; 695 case LE: __ BranchSignedLessEqual(T1, T0, &is_true); break;
696 case GT: __ BranchSignedGreater(T1, T0, &is_true); break; 696 case GT: __ BranchSignedGreater(T1, T0, &is_true); break;
697 case GE: __ BranchSignedGreaterEqual(T1, T0, &is_true); break; 697 case GE: __ BranchSignedGreaterEqual(T1, T0, &is_true); break;
698 default: 698 default:
699 UNREACHABLE(); 699 UNREACHABLE();
700 break; 700 break;
701 } 701 }
702 702
703 __ Bind(&is_false); 703 __ Bind(&is_false);
704 __ LoadObject(V0, Bool::False()); 704 __ LoadObject(V0, Bool::False());
705 __ Ret(); 705 __ Ret();
706 __ Bind(&is_true); 706 __ Bind(&is_true);
707 __ LoadObject(V0, Bool::True()); 707 __ LoadObject(V0, Bool::True());
708 __ Ret(); 708 __ Ret();
709 709
710 __ Bind(&try_mint_smi); 710 __ Bind(&try_mint_smi);
711 // Get left as 64 bit integer. 711 // Get left as 64 bit integer.
712 Get64SmiOrMint(assembler, T3, T2, T1, &fall_through); 712 Get64SmiOrMint(assembler, T3, T2, T1, &fall_through);
713 // Get right as 64 bit integer. 713 // Get right as 64 bit integer.
714 Get64SmiOrMint(assembler, T5, T4, T0, &fall_through); 714 Get64SmiOrMint(assembler, T5, T4, T0, &fall_through);
715 // T3: left high. 715 // T3: left high.
716 // T2: left low. 716 // T2: left low.
717 // T5: right high. 717 // T5: right high.
718 // T4: right low. 718 // T4: right low.
719 719
720 // 64-bit comparison 720 // 64-bit comparison
721 // Condition hi_true_cond, hi_false_cond, lo_false_cond; 721 switch (rel_op) {
722 switch (true_condition) {
723 case LT: 722 case LT:
724 case LE: { 723 case LE: {
725 // Compare left hi, right high. 724 // Compare left hi, right high.
726 __ BranchSignedGreater(T3, T5, &is_false); 725 __ BranchSignedGreater(T3, T5, &is_false);
727 __ BranchSignedLess(T3, T5, &is_true); 726 __ BranchSignedLess(T3, T5, &is_true);
728 // Compare left lo, right lo. 727 // Compare left lo, right lo.
729 if (true_condition == LT) { 728 if (rel_op == LT) {
730 __ BranchUnsignedGreaterEqual(T2, T4, &is_false); 729 __ BranchUnsignedGreaterEqual(T2, T4, &is_false);
731 } else { 730 } else {
732 __ BranchUnsignedGreater(T2, T4, &is_false); 731 __ BranchUnsignedGreater(T2, T4, &is_false);
733 } 732 }
734 break; 733 break;
735 } 734 }
736 case GT: 735 case GT:
737 case GE: { 736 case GE: {
738 // Compare left hi, right high. 737 // Compare left hi, right high.
739 __ BranchSignedLess(T3, T5, &is_false); 738 __ BranchSignedLess(T3, T5, &is_false);
740 __ BranchSignedGreater(T3, T5, &is_true); 739 __ BranchSignedGreater(T3, T5, &is_true);
741 // Compare left lo, right lo. 740 // Compare left lo, right lo.
742 if (true_condition == GT) { 741 if (rel_op == GT) {
743 __ BranchUnsignedLessEqual(T2, T4, &is_false); 742 __ BranchUnsignedLessEqual(T2, T4, &is_false);
744 } else { 743 } else {
745 __ BranchUnsignedLess(T2, T4, &is_false); 744 __ BranchUnsignedLess(T2, T4, &is_false);
746 } 745 }
747 break; 746 break;
748 } 747 }
749 default: 748 default:
750 UNREACHABLE(); 749 UNREACHABLE();
751 break; 750 break;
752 } 751 }
753 // Else is true. 752 // Else is true.
754 __ b(&is_true); 753 __ b(&is_true);
755 754
756 __ Bind(&fall_through); 755 __ Bind(&fall_through);
757 } 756 }
758 757
759 758
760 void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) { 759 void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
761 CompareIntegers(assembler, LT); 760 CompareIntegers(assembler, LT);
762 } 761 }
763 762
764 763
765 void Intrinsifier::Integer_lessThan(Assembler* assembler) { 764 void Intrinsifier::Integer_lessThan(Assembler* assembler) {
766 Integer_greaterThanFromInt(assembler); 765 CompareIntegers(assembler, LT);
767 } 766 }
768 767
769 768
770 void Intrinsifier::Integer_greaterThan(Assembler* assembler) { 769 void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
771 CompareIntegers(assembler, GT); 770 CompareIntegers(assembler, GT);
772 } 771 }
773 772
774 773
775 void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) { 774 void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
776 CompareIntegers(assembler, LE); 775 CompareIntegers(assembler, LE);
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 __ LoadClassId(CMPRES1, T0); 1336 __ LoadClassId(CMPRES1, T0);
1338 __ BranchNotEqual(CMPRES1, Immediate(kDoubleCid), not_double_smi); 1337 __ BranchNotEqual(CMPRES1, Immediate(kDoubleCid), not_double_smi);
1339 // Fall through with Double in T0. 1338 // Fall through with Double in T0.
1340 } 1339 }
1341 1340
1342 1341
1343 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown 1342 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
1344 // type. Return true or false object in the register V0. Any NaN argument 1343 // type. Return true or false object in the register V0. Any NaN argument
1345 // returns false. Any non-double arg1 causes control flow to fall through to the 1344 // returns false. Any non-double arg1 causes control flow to fall through to the
1346 // slow case (compiled method body). 1345 // slow case (compiled method body).
1347 static void CompareDoubles(Assembler* assembler, Condition true_condition) { 1346 static void CompareDoubles(Assembler* assembler, RelationOperator rel_op) {
1348 Label is_smi, double_op, no_NaN, fall_through; 1347 Label is_smi, double_op, no_NaN, fall_through;
1349 __ Comment("CompareDoubles Intrinsic"); 1348 __ Comment("CompareDoubles Intrinsic");
1350 1349
1351 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1350 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1352 // Both arguments are double, right operand is in T0. 1351 // Both arguments are double, right operand is in T0.
1353 __ LoadDFromOffset(D1, T0, Double::value_offset() - kHeapObjectTag); 1352 __ LoadDFromOffset(D1, T0, Double::value_offset() - kHeapObjectTag);
1354 __ Bind(&double_op); 1353 __ Bind(&double_op);
1355 __ lw(T0, Address(SP, 1 * kWordSize)); // Left argument. 1354 __ lw(T0, Address(SP, 1 * kWordSize)); // Left argument.
1356 __ LoadDFromOffset(D0, T0, Double::value_offset() - kHeapObjectTag); 1355 __ LoadDFromOffset(D0, T0, Double::value_offset() - kHeapObjectTag);
1357 // Now, left is in D0, right is in D1. 1356 // Now, left is in D0, right is in D1.
1358 1357
1359 __ cund(D0, D1); // Check for NaN. 1358 __ cund(D0, D1); // Check for NaN.
1360 __ bc1f(&no_NaN); 1359 __ bc1f(&no_NaN);
1361 __ LoadObject(V0, Bool::False()); // Return false if either is NaN. 1360 __ LoadObject(V0, Bool::False()); // Return false if either is NaN.
1362 __ Ret(); 1361 __ Ret();
1363 __ Bind(&no_NaN); 1362 __ Bind(&no_NaN);
1364 1363
1365 switch (true_condition) { 1364 switch (rel_op) {
1366 case EQ: __ ceqd(D0, D1); break; 1365 case EQ: __ ceqd(D0, D1); break;
1367 case LT: __ coltd(D0, D1); break; 1366 case LT: __ coltd(D0, D1); break;
1368 case LE: __ coled(D0, D1); break; 1367 case LE: __ coled(D0, D1); break;
1369 case GT: __ coltd(D1, D0); break; 1368 case GT: __ coltd(D1, D0); break;
1370 case GE: __ coled(D1, D0); break; 1369 case GE: __ coled(D1, D0); break;
1371 default: { 1370 default: {
1372 // Only passing the above conditions to this function. 1371 // Only passing the above conditions to this function.
1373 UNREACHABLE(); 1372 UNREACHABLE();
1374 break; 1373 break;
1375 } 1374 }
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
2140 Isolate* isolate = Isolate::Current(); 2139 Isolate* isolate = Isolate::Current();
2141 __ LoadImmediate(V0, reinterpret_cast<uword>(isolate)); 2140 __ LoadImmediate(V0, reinterpret_cast<uword>(isolate));
2142 // Set return value. 2141 // Set return value.
2143 __ Ret(); 2142 __ Ret();
2144 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset())); 2143 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset()));
2145 } 2144 }
2146 2145
2147 } // namespace dart 2146 } // namespace dart
2148 2147
2149 #endif // defined TARGET_ARCH_MIPS 2148 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/simulator_arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698