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

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

Issue 766313002: Simplify mint comparison code on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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 | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 // Compare lower. 563 // Compare lower.
564 __ cmp(left_lo, Operand(right_lo)); 564 __ cmp(left_lo, Operand(right_lo));
565 // Compare upper if lower is equal. 565 // Compare upper if lower is equal.
566 __ cmp(left_hi, Operand(right_hi), EQ); 566 __ cmp(left_hi, Operand(right_hi), EQ);
567 return TokenKindToMintCondition(kind); 567 return TokenKindToMintCondition(kind);
568 } 568 }
569 569
570 570
571 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, 571 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
572 LocationSummary* locs, 572 LocationSummary* locs,
573 Token::Kind kind) { 573 Token::Kind kind,
574 BranchLabels labels) {
574 PairLocation* left_pair = locs->in(0).AsPairLocation(); 575 PairLocation* left_pair = locs->in(0).AsPairLocation();
575 Register left_lo = left_pair->At(0).reg(); 576 Register left_lo = left_pair->At(0).reg();
576 Register left_hi = left_pair->At(1).reg(); 577 Register left_hi = left_pair->At(1).reg();
577 PairLocation* right_pair = locs->in(1).AsPairLocation(); 578 PairLocation* right_pair = locs->in(1).AsPairLocation();
578 Register right_lo = right_pair->At(0).reg(); 579 Register right_lo = right_pair->At(0).reg();
579 Register right_hi = right_pair->At(1).reg(); 580 Register right_hi = right_pair->At(1).reg();
580 581
581 Register out = locs->temp(0).reg(); 582 // 64-bit comparison.
582 583 Condition hi_cond, lo_cond;
583 // 64-bit comparison
584 Condition hi_true_cond, hi_false_cond, lo_false_cond;
585 switch (kind) { 584 switch (kind) {
586 case Token::kLT: 585 case Token::kLT:
587 case Token::kLTE: 586 hi_cond = LT;
588 hi_true_cond = LT; 587 lo_cond = CC;
589 hi_false_cond = GT;
590 lo_false_cond = (kind == Token::kLT) ? CS : HI;
591 break; 588 break;
592 case Token::kGT: 589 case Token::kGT:
590 hi_cond = GT;
591 lo_cond = HI;
592 break;
593 case Token::kLTE:
594 hi_cond = LT;
595 lo_cond = LS;
596 break;
593 case Token::kGTE: 597 case Token::kGTE:
594 hi_true_cond = GT; 598 hi_cond = GT;
595 hi_false_cond = LT; 599 lo_cond = CS;
596 lo_false_cond = (kind == Token::kGT) ? LS : CC;
597 break; 600 break;
598 default: 601 default:
599 UNREACHABLE(); 602 UNREACHABLE();
600 hi_true_cond = hi_false_cond = lo_false_cond = VS; 603 hi_cond = lo_cond = VS;
601 } 604 }
602
603 Label done;
604 // Compare upper halves first. 605 // Compare upper halves first.
605 __ cmp(left_hi, Operand(right_hi)); 606 __ cmp(left_hi, Operand(right_hi));
606 __ LoadImmediate(out, 0, hi_false_cond); 607 __ b(labels.true_label, hi_cond);
607 __ LoadImmediate(out, 1, hi_true_cond); 608 __ b(labels.false_label, FlipCondition(hi_cond));
608 // If higher words aren't equal, skip comparing lower words.
609 __ b(&done, NE);
610 609
610 // If higher words are equal, compare lower words.
611 __ cmp(left_lo, Operand(right_lo)); 611 __ cmp(left_lo, Operand(right_lo));
zra 2014/12/01 21:18:18 Do you need to branch to a label here? Maybe we ne
regis 2014/12/01 22:19:51 No, we only return the condition. The branch itsel
zra 2014/12/01 22:34:47 Ah, I see =) Didn't notice the call to EmitBranchO
regis 2014/12/01 22:44:00 I prefer to leave the code in sync with other plat
612 __ LoadImmediate(out, 1); 612 return lo_cond;
613 __ LoadImmediate(out, 0, lo_false_cond);
614 __ Bind(&done);
615
616 return NegateCondition(lo_false_cond);
617 } 613 }
618 614
619 615
620 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 616 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
621 switch (kind) { 617 switch (kind) {
622 case Token::kEQ: return EQ; 618 case Token::kEQ: return EQ;
623 case Token::kNE: return NE; 619 case Token::kNE: return NE;
624 case Token::kLT: return LT; 620 case Token::kLT: return LT;
625 case Token::kGT: return GT; 621 case Token::kGT: return GT;
626 case Token::kLTE: return LE; 622 case Token::kLTE: return LE;
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 __ LoadObject(result_reg, Bool::True()); 811 __ LoadObject(result_reg, Bool::True());
816 __ Bind(&done); 812 __ Bind(&done);
817 } 813 }
818 814
819 815
820 LocationSummary* RelationalOpInstr::MakeLocationSummary(Isolate* isolate, 816 LocationSummary* RelationalOpInstr::MakeLocationSummary(Isolate* isolate,
821 bool opt) const { 817 bool opt) const {
822 const intptr_t kNumInputs = 2; 818 const intptr_t kNumInputs = 2;
823 const intptr_t kNumTemps = 0; 819 const intptr_t kNumTemps = 0;
824 if (operation_cid() == kMintCid) { 820 if (operation_cid() == kMintCid) {
825 const intptr_t kNumTemps = 1; 821 const intptr_t kNumTemps = 0;
826 LocationSummary* locs = new(isolate) LocationSummary( 822 LocationSummary* locs = new(isolate) LocationSummary(
827 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 823 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
828 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 824 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
829 Location::RequiresRegister())); 825 Location::RequiresRegister()));
830 locs->set_in(1, Location::Pair(Location::RequiresRegister(), 826 locs->set_in(1, Location::Pair(Location::RequiresRegister(),
831 Location::RequiresRegister())); 827 Location::RequiresRegister()));
832 locs->set_temp(0, Location::RequiresRegister()); // TODO(regis): Improve.
833 locs->set_out(0, Location::RequiresRegister()); 828 locs->set_out(0, Location::RequiresRegister());
834 return locs; 829 return locs;
835 } 830 }
836 if (operation_cid() == kDoubleCid) { 831 if (operation_cid() == kDoubleCid) {
837 LocationSummary* summary = new(isolate) LocationSummary( 832 LocationSummary* summary = new(isolate) LocationSummary(
838 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 833 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
839 summary->set_in(0, Location::RequiresFpuRegister()); 834 summary->set_in(0, Location::RequiresFpuRegister());
840 summary->set_in(1, Location::RequiresFpuRegister()); 835 summary->set_in(1, Location::RequiresFpuRegister());
841 summary->set_out(0, Location::RequiresRegister()); 836 summary->set_out(0, Location::RequiresRegister());
842 return summary; 837 return summary;
(...skipping 10 matching lines...) Expand all
853 summary->set_out(0, Location::RequiresRegister()); 848 summary->set_out(0, Location::RequiresRegister());
854 return summary; 849 return summary;
855 } 850 }
856 851
857 852
858 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 853 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
859 BranchLabels labels) { 854 BranchLabels labels) {
860 if (operation_cid() == kSmiCid) { 855 if (operation_cid() == kSmiCid) {
861 return EmitSmiComparisonOp(compiler, locs(), kind()); 856 return EmitSmiComparisonOp(compiler, locs(), kind());
862 } else if (operation_cid() == kMintCid) { 857 } else if (operation_cid() == kMintCid) {
863 return EmitUnboxedMintComparisonOp(compiler, locs(), kind()); 858 return EmitUnboxedMintComparisonOp(compiler, locs(), kind(), labels);
864 } else { 859 } else {
865 ASSERT(operation_cid() == kDoubleCid); 860 ASSERT(operation_cid() == kDoubleCid);
866 return EmitDoubleComparisonOp(compiler, locs(), kind()); 861 return EmitDoubleComparisonOp(compiler, locs(), kind());
867 } 862 }
868 } 863 }
869 864
870 865
871 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 866 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
872 // The ARM code does not use true- and false-labels here. 867 Label is_true, is_false;
873 BranchLabels labels = { NULL, NULL, NULL }; 868 BranchLabels labels = { &is_true, &is_false, &is_false };
874 Condition true_condition = EmitComparisonCode(compiler, labels); 869 Condition true_condition = EmitComparisonCode(compiler, labels);
875 870
876 const Register result = locs()->out(0).reg(); 871 const Register result = locs()->out(0).reg();
877 if (operation_cid() == kSmiCid) { 872 if (operation_cid() == kSmiCid) {
878 __ LoadObject(result, Bool::True(), true_condition); 873 __ LoadObject(result, Bool::True(), true_condition);
879 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); 874 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
880 } else if (operation_cid() == kMintCid) { 875 } else if (operation_cid() == kMintCid) {
881 const Register cr = locs()->temp(0).reg(); 876 EmitBranchOnCondition(compiler, true_condition, labels);
877 Label done;
878 __ Bind(&is_false);
879 __ LoadObject(result, Bool::False());
880 __ b(&done);
881 __ Bind(&is_true);
882 __ LoadObject(result, Bool::True()); 882 __ LoadObject(result, Bool::True());
883 __ CompareImmediate(cr, 1); 883 __ Bind(&done);
884 __ LoadObject(result, Bool::False(), NE);
885 } else { 884 } else {
886 ASSERT(operation_cid() == kDoubleCid); 885 ASSERT(operation_cid() == kDoubleCid);
887 Label done; 886 Label done;
888 __ LoadObject(result, Bool::False()); 887 __ LoadObject(result, Bool::False());
889 if (true_condition != NE) { 888 if (true_condition != NE) {
890 __ b(&done, VS); // x == NaN -> false, x != NaN -> true. 889 __ b(&done, VS); // x == NaN -> false, x != NaN -> true.
891 } 890 }
892 __ LoadObject(result, Bool::True(), true_condition); 891 __ LoadObject(result, Bool::True(), true_condition);
893 __ Bind(&done); 892 __ Bind(&done);
894 } 893 }
895 } 894 }
896 895
897 896
898 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 897 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
899 BranchInstr* branch) { 898 BranchInstr* branch) {
900 BranchLabels labels = compiler->CreateBranchLabels(branch); 899 BranchLabels labels = compiler->CreateBranchLabels(branch);
901 Condition true_condition = EmitComparisonCode(compiler, labels); 900 Condition true_condition = EmitComparisonCode(compiler, labels);
902 901
903 if (operation_cid() == kSmiCid) { 902 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) {
904 EmitBranchOnCondition(compiler, true_condition, labels); 903 EmitBranchOnCondition(compiler, true_condition, labels);
905 } else if (operation_cid() == kMintCid) {
906 const Register result = locs()->temp(0).reg(); // TODO(regis): Improve.
907 __ CompareImmediate(result, 1);
908 __ b(labels.true_label, EQ);
909 __ b(labels.false_label, NE);
910 } else if (operation_cid() == kDoubleCid) { 904 } else if (operation_cid() == kDoubleCid) {
911 Label* nan_result = (true_condition == NE) ? 905 Label* nan_result = (true_condition == NE) ?
912 labels.true_label : labels.false_label; 906 labels.true_label : labels.false_label;
913 __ b(nan_result, VS); 907 __ b(nan_result, VS);
914 EmitBranchOnCondition(compiler, true_condition, labels); 908 EmitBranchOnCondition(compiler, true_condition, labels);
915 } 909 }
916 } 910 }
917 911
918 912
919 LocationSummary* NativeCallInstr::MakeLocationSummary(Isolate* isolate, 913 LocationSummary* NativeCallInstr::MakeLocationSummary(Isolate* isolate,
(...skipping 5983 matching lines...) Expand 10 before | Expand all | Expand 10 after
6903 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 6897 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
6904 #if defined(DEBUG) 6898 #if defined(DEBUG)
6905 __ LoadImmediate(R4, kInvalidObjectPointer); 6899 __ LoadImmediate(R4, kInvalidObjectPointer);
6906 __ LoadImmediate(R5, kInvalidObjectPointer); 6900 __ LoadImmediate(R5, kInvalidObjectPointer);
6907 #endif 6901 #endif
6908 } 6902 }
6909 6903
6910 } // namespace dart 6904 } // namespace dart
6911 6905
6912 #endif // defined TARGET_ARCH_ARM 6906 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698