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

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

Issue 78733002: Generalize if-conversion to arbitrary smi comparisons. (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
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.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_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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 128
129 129
130 // Detect pattern when one value is zero and another is a power of 2. 130 // Detect pattern when one value is zero and another is a power of 2.
131 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 131 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
132 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 132 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
133 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 133 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
134 } 134 }
135 135
136 136
137 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { 137 LocationSummary* IfThenElseInstr::MakeLocationSummary() const {
138 const intptr_t kNumInputs = 2; 138 return comparison()->MakeLocationSummary();
139 const intptr_t kNumTemps = 0;
140 LocationSummary* locs =
141 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
142 locs->set_in(0, Location::RegisterOrConstant(left()));
143 // Only one of the inputs can be a constant. Choose register if the first one
144 // is a constant.
145 locs->set_in(1, locs->in(0).IsConstant()
146 ? Location::RequiresRegister()
147 : Location::RegisterOrConstant(right()));
148 locs->set_out(Location::RequiresRegister());
149 return locs;
150 } 139 }
151 140
152 141
153 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 142 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
154 const Register result = locs()->out().reg(); 143 const Register result = locs()->out().reg();
155 ASSERT(Token::IsEqualityOperator(kind()));
156 144
157 Location left = locs()->in(0); 145 Location left = locs()->in(0);
158 Location right = locs()->in(1); 146 Location right = locs()->in(1);
159 ASSERT(!left.IsConstant() || !right.IsConstant()); 147 ASSERT(!left.IsConstant() || !right.IsConstant());
160 148
161 // Clear out register. 149 // Clear out register.
162 __ mov(result, ZR); 150 __ mov(result, ZR);
163 151
164 // Compare left and right. For now only equality comparison is supported. 152 // Emit comparison code. This must not overwrite the result register.
165 // TODO(vegorov): reuse code from the other comparison instructions instead of 153 BranchLabels labels = { NULL, NULL, NULL };
166 // generating it inline here. 154 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
167 if (left.IsConstant()) {
168 __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant());
169 } else if (right.IsConstant()) {
170 __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant());
171 } else {
172 __ slt(CMPRES1, left.reg(), right.reg());
173 __ slt(CMPRES2, right.reg(), left.reg());
174 }
175
176 Condition true_condition =
177 ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQ : NE;
178 155
179 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); 156 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
180 157
181 intptr_t true_value = if_true_; 158 intptr_t true_value = if_true_;
182 intptr_t false_value = if_false_; 159 intptr_t false_value = if_false_;
183 160
184 if (is_power_of_two_kind) { 161 if (is_power_of_two_kind) {
185 if (true_value == 0) { 162 if (true_value == 0) {
186 // We need to have zero in result on true_condition. 163 // We need to have zero in result on true_condition.
187 true_condition = NegateCondition(true_condition); 164 true_condition = NegateCondition(true_condition);
188 } 165 }
189 } else { 166 } else {
190 if (true_value == 0) { 167 if (true_value == 0) {
191 // Swap values so that false_value is zero. 168 // Swap values so that false_value is zero.
192 intptr_t temp = true_value; 169 intptr_t temp = true_value;
193 true_value = false_value; 170 true_value = false_value;
194 false_value = temp; 171 false_value = temp;
195 } else { 172 } else {
196 true_condition = NegateCondition(true_condition); 173 true_condition = NegateCondition(true_condition);
197 } 174 }
198 } 175 }
199 176
200 if (true_condition == EQ) { 177 switch (true_condition) {
201 __ xor_(result, CMPRES1, CMPRES2); 178 case EQ:
202 __ xori(result, result, Immediate(1)); 179 __ xor_(result, CMPRES1, CMPRES2);
203 } else { 180 __ xori(result, result, Immediate(1));
204 ASSERT(true_condition == NE); 181 break;
205 __ xor_(result, CMPRES1, CMPRES2); 182 case NE:
183 __ xor_(result, CMPRES1, CMPRES2);
184 break;
185 case GT:
186 __ mov(result, CMPRES2);
187 break;
188 case GE:
189 __ xori(result, CMPRES1, Immediate(1));
190 break;
191 case LT:
192 __ mov(result, CMPRES1);
193 break;
194 case LE:
195 __ xori(result, CMPRES2, Immediate(1));
196 break;
197 default:
198 UNREACHABLE();
199 break;
206 } 200 }
207 201
208 if (is_power_of_two_kind) { 202 if (is_power_of_two_kind) {
209 const intptr_t shift = 203 const intptr_t shift =
210 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); 204 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value));
211 __ sll(result, result, shift + kSmiTagSize); 205 __ sll(result, result, shift + kSmiTagSize);
212 } else { 206 } else {
213 __ AddImmediate(result, result, -1); 207 __ AddImmediate(result, result, -1);
214 const int32_t val = 208 const int32_t val =
215 Smi::RawValue(true_value) - Smi::RawValue(false_value); 209 Smi::RawValue(true_value) - Smi::RawValue(false_value);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 Condition false_condition = NegateCondition(true_condition); 469 Condition false_condition = NegateCondition(true_condition);
476 EmitBranchAfterCompare(compiler, false_condition, labels.false_label); 470 EmitBranchAfterCompare(compiler, false_condition, labels.false_label);
477 // Fall through or jump to the true successor. 471 // Fall through or jump to the true successor.
478 if (labels.fall_through != labels.true_label) { 472 if (labels.fall_through != labels.true_label) {
479 __ b(labels.true_label); 473 __ b(labels.true_label);
480 } 474 }
481 } 475 }
482 } 476 }
483 477
484 478
485 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 479 static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
486 const LocationSummary& locs, 480 const LocationSummary& locs,
487 Token::Kind kind, 481 Token::Kind kind,
488 BranchLabels labels) { 482 BranchLabels labels) {
489 __ TraceSimMsg("EmitSmiComparisonOp"); 483 __ TraceSimMsg("EmitSmiComparisonOp");
490 __ Comment("EmitSmiComparisonOp"); 484 __ Comment("EmitSmiComparisonOp");
491 Location left = locs.in(0); 485 Location left = locs.in(0);
492 Location right = locs.in(1); 486 Location right = locs.in(1);
493 ASSERT(!left.IsConstant() || !right.IsConstant()); 487 ASSERT(!left.IsConstant() || !right.IsConstant());
494 488
495 Condition true_condition = TokenKindToSmiCondition(kind); 489 Condition true_condition = TokenKindToSmiCondition(kind);
496 490
497 if (left.IsConstant()) { 491 if (left.IsConstant()) {
498 __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant()); 492 __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant());
499 true_condition = FlipCondition(true_condition); 493 true_condition = FlipCondition(true_condition);
500 } else if (right.IsConstant()) { 494 } else if (right.IsConstant()) {
501 __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant()); 495 __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant());
502 } else { 496 } else {
503 __ slt(CMPRES1, left.reg(), right.reg()); 497 __ slt(CMPRES1, left.reg(), right.reg());
504 __ slt(CMPRES2, right.reg(), left.reg()); 498 __ slt(CMPRES2, right.reg(), left.reg());
505 } 499 }
506 EmitBranchOnCondition(compiler, true_condition, labels); 500 return true_condition;
507 } 501 }
508 502
509 503
510 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 504 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
511 switch (kind) { 505 switch (kind) {
512 case Token::kEQ: return EQ; 506 case Token::kEQ: return EQ;
513 case Token::kNE: return NE; 507 case Token::kNE: return NE;
514 case Token::kLT: return LT; 508 case Token::kLT: return LT;
515 case Token::kGT: return GT; 509 case Token::kGT: return GT;
516 case Token::kLTE: return LE; 510 case Token::kLTE: return LE;
517 case Token::kGTE: return GE; 511 case Token::kGTE: return GE;
518 default: 512 default:
519 UNREACHABLE(); 513 UNREACHABLE();
520 return VS; 514 return VS;
521 } 515 }
522 } 516 }
523 517
524 518
525 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 519 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
526 const LocationSummary& locs, 520 const LocationSummary& locs,
527 Token::Kind kind, 521 Token::Kind kind,
528 BranchLabels labels) { 522 BranchLabels labels) {
529 DRegister left = locs.in(0).fpu_reg(); 523 DRegister left = locs.in(0).fpu_reg();
530 DRegister right = locs.in(1).fpu_reg(); 524 DRegister right = locs.in(1).fpu_reg();
531 525
532 __ Comment("DoubleComparisonOp(left=%d, right=%d)", left, right); 526 __ Comment("DoubleComparisonOp(left=%d, right=%d)", left, right);
533 527
534 Condition true_condition = TokenKindToDoubleCondition(kind); 528 Condition true_condition = TokenKindToDoubleCondition(kind);
535 __ cund(left, right); 529 __ cund(left, right);
536 Label* nan_label = (true_condition == NE) 530 Label* nan_label = (true_condition == NE)
537 ? labels.true_label : labels.false_label; 531 ? labels.true_label : labels.false_label;
538 __ bc1t(nan_label); 532 __ bc1t(nan_label);
539 533
540 switch (true_condition) { 534 switch (true_condition) {
541 case EQ: __ ceqd(left, right); break; 535 case EQ: __ ceqd(left, right); break;
542 case NE: __ ceqd(left, right); break; 536 case NE: __ ceqd(left, right); break;
543 case LT: __ coltd(left, right); break; 537 case LT: __ coltd(left, right); break;
544 case LE: __ coled(left, right); break; 538 case LE: __ coled(left, right); break;
545 case GT: __ coltd(right, left); break; 539 case GT: __ coltd(right, left); break;
546 case GE: __ coled(right, left); break; 540 case GE: __ coled(right, left); break;
547 default: { 541 default: {
548 // Should only passing the above conditions to this function. 542 // Should only passing the above conditions to this function.
549 UNREACHABLE(); 543 UNREACHABLE();
550 break; 544 break;
551 } 545 }
552 } 546 }
553 547
548 // Ordering is expected to be described by CMPRES1, CMPRES2.
554 __ LoadImmediate(TMP, 1); 549 __ LoadImmediate(TMP, 1);
555 if (true_condition == NE) { 550 if (true_condition == NE) {
556 __ movf(CMPRES1, ZR); 551 __ movf(CMPRES1, ZR);
557 __ movt(CMPRES1, TMP); 552 __ movt(CMPRES1, TMP);
558 } else { 553 } else {
559 __ movf(CMPRES1, TMP); 554 __ movf(CMPRES1, TMP);
560 __ movt(CMPRES1, ZR); 555 __ movt(CMPRES1, ZR);
561 } 556 }
562 __ mov(CMPRES2, ZR); 557 __ mov(CMPRES2, ZR);
563 558 return EQ;
564 // EmitBranchOnCondition expects ordering to be described by CMPRES1, CMPRES2.
565 EmitBranchOnCondition(compiler, EQ, labels);
566 } 559 }
567 560
568 561
562 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
563 BranchLabels labels) {
564 if (operation_cid() == kSmiCid) {
565 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
566 } else {
567 ASSERT(operation_cid() == kDoubleCid);
568 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
569 }
570 }
571
572
569 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 573 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
570 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 574 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
571 __ Comment("EqualityCompareInstr"); 575 __ Comment("EqualityCompareInstr");
572 576
573 Label is_true, is_false; 577 Label is_true, is_false;
574 BranchLabels labels = { &is_true, &is_false, &is_false }; 578 BranchLabels labels = { &is_true, &is_false, &is_false };
579 Condition true_condition = EmitComparisonCode(compiler, labels);
580 EmitBranchOnCondition(compiler, true_condition, labels);
575 581
576 if (operation_cid() == kSmiCid) {
577 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
578 } else {
579 ASSERT(operation_cid() == kDoubleCid);
580 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
581 }
582 Register result = locs()->out().reg(); 582 Register result = locs()->out().reg();
583 Label done; 583 Label done;
584 __ Bind(&is_false); 584 __ Bind(&is_false);
585 __ LoadObject(result, Bool::False()); 585 __ LoadObject(result, Bool::False());
586 __ b(&done); 586 __ b(&done);
587 __ Bind(&is_true); 587 __ Bind(&is_true);
588 __ LoadObject(result, Bool::True()); 588 __ LoadObject(result, Bool::True());
589 __ Bind(&done); 589 __ Bind(&done);
590 } 590 }
591 591
592 592
593 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 593 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
594 BranchInstr* branch) { 594 BranchInstr* branch) {
595 __ TraceSimMsg("EqualityCompareInstr"); 595 __ TraceSimMsg("EqualityCompareInstr");
596 __ Comment("EqualityCompareInstr:BranchCode"); 596 __ Comment("EqualityCompareInstr:BranchCode");
597 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 597 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
598 598
599 BranchLabels labels = compiler->CreateBranchLabels(branch); 599 BranchLabels labels = compiler->CreateBranchLabels(branch);
600 600 Condition true_condition = EmitComparisonCode(compiler, labels);
601 if (operation_cid() == kSmiCid) { 601 EmitBranchOnCondition(compiler, true_condition, labels);
602 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
603 } else {
604 ASSERT(operation_cid() == kDoubleCid);
605 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
606 }
607 } 602 }
608 603
609 604
610 LocationSummary* TestSmiInstr::MakeLocationSummary() const { 605 LocationSummary* TestSmiInstr::MakeLocationSummary() const {
611 const intptr_t kNumInputs = 2; 606 const intptr_t kNumInputs = 2;
612 const intptr_t kNumTemps = 0; 607 const intptr_t kNumTemps = 0;
613 LocationSummary* locs = 608 LocationSummary* locs =
614 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
615 locs->set_in(0, Location::RequiresRegister()); 610 locs->set_in(0, Location::RequiresRegister());
616 // Only one input can be a constant operand. The case of two constant 611 // Only one input can be a constant operand. The case of two constant
617 // operands should be handled by constant propagation. 612 // operands should be handled by constant propagation.
618 locs->set_in(1, Location::RegisterOrConstant(right())); 613 locs->set_in(1, Location::RegisterOrConstant(right()));
619 return locs; 614 return locs;
620 } 615 }
621 616
622 617
623 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 618 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
624 // Never emitted outside of the BranchInstr. 619 BranchLabels labels) {
625 UNREACHABLE();
626 }
627
628
629 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
630 BranchInstr* branch) {
631 BranchLabels labels = compiler->CreateBranchLabels(branch);
632
633 Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
634 Register left = locs()->in(0).reg(); 620 Register left = locs()->in(0).reg();
635 Location right = locs()->in(1); 621 Location right = locs()->in(1);
636 if (right.IsConstant()) { 622 if (right.IsConstant()) {
637 ASSERT(right.constant().IsSmi()); 623 ASSERT(right.constant().IsSmi());
638 const int32_t imm = 624 const int32_t imm =
639 reinterpret_cast<int32_t>(right.constant().raw()); 625 reinterpret_cast<int32_t>(right.constant().raw());
640 __ AndImmediate(CMPRES1, left, imm); 626 __ AndImmediate(CMPRES1, left, imm);
641 } else { 627 } else {
642 __ and_(CMPRES1, left, right.reg()); 628 __ and_(CMPRES1, left, right.reg());
643 } 629 }
644 __ mov(CMPRES2, ZR); 630 __ mov(CMPRES2, ZR);
631 Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
632 return true_condition;
633 }
634
635
636 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
637 // Never emitted outside of the BranchInstr.
638 UNREACHABLE();
639 }
640
641
642 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
643 BranchInstr* branch) {
644 BranchLabels labels = compiler->CreateBranchLabels(branch);
645 Condition true_condition = EmitComparisonCode(compiler, labels);
645 EmitBranchOnCondition(compiler, true_condition, labels); 646 EmitBranchOnCondition(compiler, true_condition, labels);
646 } 647 }
647 648
648 649
649 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 650 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
650 const intptr_t kNumInputs = 2; 651 const intptr_t kNumInputs = 2;
651 const intptr_t kNumTemps = 0; 652 const intptr_t kNumTemps = 0;
652 if (operation_cid() == kMintCid) { 653 if (operation_cid() == kMintCid) {
653 const intptr_t kNumTemps = 2; 654 const intptr_t kNumTemps = 2;
654 LocationSummary* locs = 655 LocationSummary* locs =
(...skipping 20 matching lines...) Expand all
675 // Only one input can be a constant operand. The case of two constant 676 // Only one input can be a constant operand. The case of two constant
676 // operands should be handled by constant propagation. 677 // operands should be handled by constant propagation.
677 summary->set_in(1, summary->in(0).IsConstant() 678 summary->set_in(1, summary->in(0).IsConstant()
678 ? Location::RequiresRegister() 679 ? Location::RequiresRegister()
679 : Location::RegisterOrConstant(right())); 680 : Location::RegisterOrConstant(right()));
680 summary->set_out(Location::RequiresRegister()); 681 summary->set_out(Location::RequiresRegister());
681 return summary; 682 return summary;
682 } 683 }
683 684
684 685
686 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
687 BranchLabels labels) {
688 if (operation_cid() == kSmiCid) {
689 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
690 } else {
691 ASSERT(operation_cid() == kDoubleCid);
692 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
693 }
694 }
695
696
685 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 697 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
686 __ TraceSimMsg("RelationalOpInstr"); 698 __ TraceSimMsg("RelationalOpInstr");
687 699
688 Label is_true, is_false; 700 Label is_true, is_false;
689 BranchLabels labels = { &is_true, &is_false, &is_false }; 701 BranchLabels labels = { &is_true, &is_false, &is_false };
702 Condition true_condition = EmitComparisonCode(compiler, labels);
703 EmitBranchOnCondition(compiler, true_condition, labels);
690 704
691 if (operation_cid() == kSmiCid) {
692 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
693 } else {
694 ASSERT(operation_cid() == kDoubleCid);
695 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
696 }
697 Register result = locs()->out().reg(); 705 Register result = locs()->out().reg();
698 Label done; 706 Label done;
699 __ Bind(&is_false); 707 __ Bind(&is_false);
700 __ LoadObject(result, Bool::False()); 708 __ LoadObject(result, Bool::False());
701 __ b(&done); 709 __ b(&done);
702 __ Bind(&is_true); 710 __ Bind(&is_true);
703 __ LoadObject(result, Bool::True()); 711 __ LoadObject(result, Bool::True());
704 __ Bind(&done); 712 __ Bind(&done);
705 } 713 }
706 714
707 715
708 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 716 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
709 BranchInstr* branch) { 717 BranchInstr* branch) {
710 __ TraceSimMsg("RelationalOpInstr"); 718 __ TraceSimMsg("RelationalOpInstr");
711 719
712 BranchLabels labels = compiler->CreateBranchLabels(branch); 720 BranchLabels labels = compiler->CreateBranchLabels(branch);
713 721 Condition true_condition = EmitComparisonCode(compiler, labels);
714 if (operation_cid() == kSmiCid) { 722 EmitBranchOnCondition(compiler, true_condition, labels);
715 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
716 } else {
717 ASSERT(operation_cid() == kDoubleCid);
718 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
719 }
720 } 723 }
721 724
722 725
723 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 726 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
724 const intptr_t kNumInputs = 0; 727 const intptr_t kNumInputs = 0;
725 const intptr_t kNumTemps = 3; 728 const intptr_t kNumTemps = 3;
726 LocationSummary* locs = 729 LocationSummary* locs =
727 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 730 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
728 locs->set_temp(0, Location::RegisterLocation(A1)); 731 locs->set_temp(0, Location::RegisterLocation(A1));
729 locs->set_temp(1, Location::RegisterLocation(A2)); 732 locs->set_temp(1, Location::RegisterLocation(A2));
(...skipping 3018 matching lines...) Expand 10 before | Expand all | Expand 10 after
3748 // Only one of the inputs can be a constant. Choose register if the first one 3751 // Only one of the inputs can be a constant. Choose register if the first one
3749 // is a constant. 3752 // is a constant.
3750 locs->set_in(1, locs->in(0).IsConstant() 3753 locs->set_in(1, locs->in(0).IsConstant()
3751 ? Location::RequiresRegister() 3754 ? Location::RequiresRegister()
3752 : Location::RegisterOrConstant(right())); 3755 : Location::RegisterOrConstant(right()));
3753 locs->set_out(Location::RequiresRegister()); 3756 locs->set_out(Location::RequiresRegister());
3754 return locs; 3757 return locs;
3755 } 3758 }
3756 3759
3757 3760
3758 static void EmitStrictComparison(FlowGraphCompiler* compiler, 3761 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
3759 StrictCompareInstr* compare, 3762 BranchLabels labels) {
3760 BranchLabels labels) { 3763 Location left = locs()->in(0);
3761 LocationSummary* locs = compare->locs(); 3764 Location right = locs()->in(1);
3762 bool needs_number_check = compare->needs_number_check();
3763 intptr_t token_pos = compare->token_pos();
3764 Token::Kind kind = compare->kind();
3765 Location left = locs->in(0);
3766 Location right = locs->in(1);
3767 ASSERT(!left.IsConstant() || !right.IsConstant()); 3765 ASSERT(!left.IsConstant() || !right.IsConstant());
3768 if (left.IsConstant()) { 3766 if (left.IsConstant()) {
3769 compiler->EmitEqualityRegConstCompare(right.reg(), 3767 compiler->EmitEqualityRegConstCompare(right.reg(),
3770 left.constant(), 3768 left.constant(),
3771 needs_number_check, 3769 needs_number_check(),
3772 token_pos); 3770 token_pos());
3773 } else if (right.IsConstant()) { 3771 } else if (right.IsConstant()) {
3774 compiler->EmitEqualityRegConstCompare(left.reg(), 3772 compiler->EmitEqualityRegConstCompare(left.reg(),
3775 right.constant(), 3773 right.constant(),
3776 needs_number_check, 3774 needs_number_check(),
3777 token_pos); 3775 token_pos());
3778 } else { 3776 } else {
3779 compiler->EmitEqualityRegRegCompare(left.reg(), 3777 compiler->EmitEqualityRegRegCompare(left.reg(),
3780 right.reg(), 3778 right.reg(),
3781 needs_number_check, 3779 needs_number_check(),
3782 token_pos); 3780 token_pos());
3783 } 3781 }
3784 Condition true_condition = (kind == Token::kEQ_STRICT) ? EQ : NE; 3782 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
3785 EmitBranchOnCondition(compiler, true_condition, labels); 3783 return true_condition;
3786 } 3784 }
3787 3785
3788 // Special code for numbers (compare values instead of references.) 3786
3789 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3787 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3790 __ TraceSimMsg("StrictCompareInstr"); 3788 __ TraceSimMsg("StrictCompareInstr");
3791 __ Comment("StrictCompareInstr"); 3789 __ Comment("StrictCompareInstr");
3792 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 3790 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
3793 3791
3794 Label is_true, is_false; 3792 Label is_true, is_false;
3795 BranchLabels labels = { &is_true, &is_false, &is_false }; 3793 BranchLabels labels = { &is_true, &is_false, &is_false };
3796 3794 Condition true_condition = EmitComparisonCode(compiler, labels);
3797 EmitStrictComparison(compiler, this, labels); 3795 EmitBranchOnCondition(compiler, true_condition, labels);
3798 3796
3799 Register result = locs()->out().reg(); 3797 Register result = locs()->out().reg();
3800 Label done; 3798 Label done;
3801 __ Bind(&is_false); 3799 __ Bind(&is_false);
3802 __ LoadObject(result, Bool::False()); 3800 __ LoadObject(result, Bool::False());
3803 __ b(&done); 3801 __ b(&done);
3804 __ Bind(&is_true); 3802 __ Bind(&is_true);
3805 __ LoadObject(result, Bool::True()); 3803 __ LoadObject(result, Bool::True());
3806 __ Bind(&done); 3804 __ Bind(&done);
3807 } 3805 }
3808 3806
3809 3807
3810 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 3808 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3811 BranchInstr* branch) { 3809 BranchInstr* branch) {
3812 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); 3810 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode");
3813 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 3811 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
3814 3812
3815 BranchLabels labels = compiler->CreateBranchLabels(branch); 3813 BranchLabels labels = compiler->CreateBranchLabels(branch);
3816 3814 Condition true_condition = EmitComparisonCode(compiler, labels);
3817 EmitStrictComparison(compiler, this, labels); 3815 EmitBranchOnCondition(compiler, true_condition, labels);
3818 } 3816 }
3819 3817
3820 3818
3821 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 3819 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
3822 return LocationSummary::Make(1, 3820 return LocationSummary::Make(1,
3823 Location::RequiresRegister(), 3821 Location::RequiresRegister(),
3824 LocationSummary::kNoCall); 3822 LocationSummary::kNoCall);
3825 } 3823 }
3826 3824
3827 3825
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3895 compiler->GenerateCall(token_pos(), 3893 compiler->GenerateCall(token_pos(),
3896 &label, 3894 &label,
3897 PcDescriptors::kOther, 3895 PcDescriptors::kOther,
3898 locs()); 3896 locs());
3899 __ Drop(2); // Discard type arguments and receiver. 3897 __ Drop(2); // Discard type arguments and receiver.
3900 } 3898 }
3901 3899
3902 } // namespace dart 3900 } // namespace dart
3903 3901
3904 #endif // defined TARGET_ARCH_MIPS 3902 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698