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

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

Issue 64483002: Streamline code generator for branches and comparisons. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: added other platformd, comments addressed 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 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 case Token::kGTE: return GE; 432 case Token::kGTE: return GE;
433 default: 433 default:
434 UNREACHABLE(); 434 UNREACHABLE();
435 return VS; 435 return VS;
436 } 436 }
437 } 437 }
438 438
439 439
440 // Branches on condition c assuming comparison results in CMPRES1 and CMPRES2. 440 // Branches on condition c assuming comparison results in CMPRES1 and CMPRES2.
441 static void EmitBranchAfterCompare( 441 static void EmitBranchAfterCompare(
442 FlowGraphCompiler* compiler, Condition c, Label* is_true) { 442 FlowGraphCompiler* compiler, Condition condition, Label* is_true) {
443 switch (c) { 443 switch (condition) {
444 case EQ: __ beq(CMPRES1, CMPRES2, is_true); break; 444 case EQ: __ beq(CMPRES1, CMPRES2, is_true); break;
445 case NE: __ bne(CMPRES1, CMPRES2, is_true); break; 445 case NE: __ bne(CMPRES1, CMPRES2, is_true); break;
446 case GT: __ bne(CMPRES2, ZR, is_true); break; 446 case GT: __ bne(CMPRES2, ZR, is_true); break;
447 case GE: __ beq(CMPRES1, ZR, is_true); break; 447 case GE: __ beq(CMPRES1, ZR, is_true); break;
448 case LT: __ bne(CMPRES1, ZR, is_true); break; 448 case LT: __ bne(CMPRES1, ZR, is_true); break;
449 case LE: __ beq(CMPRES2, ZR, is_true); break; 449 case LE: __ beq(CMPRES2, ZR, is_true); break;
450 default: 450 default:
451 UNREACHABLE(); 451 UNREACHABLE();
452 break; 452 break;
453 } 453 }
454 } 454 }
455 455
456 456
457 static Condition FlipCondition(Condition condition) { 457 static Condition FlipCondition(Condition condition) {
458 switch (condition) { 458 switch (condition) {
459 case EQ: return EQ; 459 case EQ: return EQ;
460 case NE: return NE; 460 case NE: return NE;
461 case LT: return GT; 461 case LT: return GT;
462 case LE: return GE; 462 case LE: return GE;
463 case GT: return LT; 463 case GT: return LT;
464 case GE: return LE; 464 case GE: return LE;
465 default: 465 default:
466 UNREACHABLE(); 466 UNREACHABLE();
467 return EQ; 467 return EQ;
468 } 468 }
469 } 469 }
470 470
471 471
472 // The comparison result is in CMPRES1. 472 // The comparison result is in CMPRES1/CMPRES2.
473 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, 473 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
474 TargetEntryInstr* true_successor, 474 Condition true_condition,
475 TargetEntryInstr* false_successor, 475 BranchLabels labels) {
476 Condition true_condition) {
477 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition"); 476 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition");
478 if (compiler->CanFallThroughTo(false_successor)) { 477 if (labels.fall_through == labels.false_label) {
479 // If the next block is the false successor, fall through to it. 478 // If the next block is the false successor, fall through to it.
480 Label* label = compiler->GetJumpLabel(true_successor); 479 EmitBranchAfterCompare(compiler, true_condition, labels.true_label);
481 EmitBranchAfterCompare(compiler, true_condition, label);
482 } else { 480 } else {
483 // If the next block is not the false successor, branch to it. 481 // If the next block is not the false successor, branch to it.
484 Condition false_condition = NegateCondition(true_condition); 482 Condition false_condition = NegateCondition(true_condition);
485 Label* label = compiler->GetJumpLabel(false_successor); 483 EmitBranchAfterCompare(compiler, false_condition, labels.false_label);
486 EmitBranchAfterCompare(compiler, false_condition, label);
487 // Fall through or jump to the true successor. 484 // Fall through or jump to the true successor.
488 if (!compiler->CanFallThroughTo(true_successor)) { 485 if (labels.fall_through != labels.true_label) {
489 __ b(compiler->GetJumpLabel(true_successor)); 486 __ b(labels.true_label);
490 } 487 }
491 } 488 }
492 } 489 }
493 490
494 491
495 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 492 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
496 const LocationSummary& locs, 493 const LocationSummary& locs,
497 Token::Kind kind, 494 Token::Kind kind,
498 BranchInstr* branch) { 495 BranchLabels labels) {
499 __ TraceSimMsg("EmitSmiComparisonOp"); 496 __ TraceSimMsg("EmitSmiComparisonOp");
500 __ Comment("EmitSmiComparisonOp"); 497 __ Comment("EmitSmiComparisonOp");
501 Location left = locs.in(0); 498 Location left = locs.in(0);
502 Location right = locs.in(1); 499 Location right = locs.in(1);
503 ASSERT(!left.IsConstant() || !right.IsConstant()); 500 ASSERT(!left.IsConstant() || !right.IsConstant());
504 501
505 Condition true_condition = TokenKindToSmiCondition(kind); 502 Condition true_condition = TokenKindToSmiCondition(kind);
506 503
507 if (left.IsConstant()) { 504 if (left.IsConstant()) {
508 __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant()); 505 __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant());
509 true_condition = FlipCondition(true_condition); 506 true_condition = FlipCondition(true_condition);
510 } else if (right.IsConstant()) { 507 } else if (right.IsConstant()) {
511 __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant()); 508 __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant());
512 } else { 509 } else {
513 __ slt(CMPRES1, left.reg(), right.reg()); 510 __ slt(CMPRES1, left.reg(), right.reg());
514 __ slt(CMPRES2, right.reg(), left.reg()); 511 __ slt(CMPRES2, right.reg(), left.reg());
515 } 512 }
516 513 EmitBranchOnCondition(compiler, true_condition, labels);
517 if (branch != NULL) {
518 EmitBranchOnCondition(compiler,
519 branch->true_successor(),
520 branch->false_successor(),
521 true_condition);
522 } else {
523 Register result = locs.out().reg();
524 Label done, is_true;
525 EmitBranchAfterCompare(compiler, true_condition, &is_true);
526 __ LoadObject(result, Bool::False());
527 __ b(&done);
528 __ Bind(&is_true);
529 __ LoadObject(result, Bool::True());
530 __ Bind(&done);
531 }
532 }
533
534
535 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
536 const LocationSummary& locs,
537 Token::Kind kind,
538 BranchInstr* branch) {
539 UNIMPLEMENTED();
540 }
541
542
543 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
544 const LocationSummary& locs,
545 Token::Kind kind,
546 BranchInstr* branch) {
547 UNIMPLEMENTED();
548 } 514 }
549 515
550 516
551 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 517 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
552 switch (kind) { 518 switch (kind) {
553 case Token::kEQ: return EQ; 519 case Token::kEQ: return EQ;
554 case Token::kNE: return NE; 520 case Token::kNE: return NE;
555 case Token::kLT: return LT; 521 case Token::kLT: return LT;
556 case Token::kGT: return GT; 522 case Token::kGT: return GT;
557 case Token::kLTE: return LE; 523 case Token::kLTE: return LE;
558 case Token::kGTE: return GE; 524 case Token::kGTE: return GE;
559 default: 525 default:
560 UNREACHABLE(); 526 UNREACHABLE();
561 return VS; 527 return VS;
562 } 528 }
563 } 529 }
564 530
565 531
566 static void EmitDoubleCompareBranch(FlowGraphCompiler* compiler, 532 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
567 Condition true_condition, 533 const LocationSummary& locs,
568 FpuRegister left, 534 Token::Kind kind,
569 FpuRegister right, 535 BranchLabels labels) {
570 BranchInstr* branch) { 536 DRegister left = locs.in(0).fpu_reg();
571 ASSERT(branch != NULL); 537 DRegister right = locs.in(1).fpu_reg();
572 __ Comment("DoubleCompareBranch"); 538
539 __ Comment("DoubleComparisonOp(left=%d, right=%d)", left, right);
540
541 Condition true_condition = TokenKindToDoubleCondition(kind);
573 __ cund(left, right); 542 __ cund(left, right);
574 BlockEntryInstr* nan_result = (true_condition == NE) ? 543 Label* nan_label = (true_condition == NE)
575 branch->true_successor() : branch->false_successor(); 544 ? labels.true_label : labels.false_label;
576 __ bc1t(compiler->GetJumpLabel(nan_result)); 545 __ bc1t(nan_label);
577 546
578 switch (true_condition) { 547 switch (true_condition) {
579 case EQ: __ ceqd(left, right); break; 548 case EQ: __ ceqd(left, right); break;
580 case NE: __ ceqd(left, right); break; 549 case NE: __ ceqd(left, right); break;
581 case LT: __ coltd(left, right); break; 550 case LT: __ coltd(left, right); break;
582 case LE: __ coled(left, right); break; 551 case LE: __ coled(left, right); break;
583 case GT: __ coltd(right, left); break; 552 case GT: __ coltd(right, left); break;
584 case GE: __ coled(right, left); break; 553 case GE: __ coled(right, left); break;
585 default: { 554 default: {
586 // Should only passing the above conditions to this function. 555 // Should only passing the above conditions to this function.
587 UNREACHABLE(); 556 UNREACHABLE();
588 break; 557 break;
589 } 558 }
590 } 559 }
591 560
592 __ LoadImmediate(TMP, 1); 561 __ LoadImmediate(TMP, 1);
593 if (true_condition == NE) { 562 if (true_condition == NE) {
594 __ movf(CMPRES1, ZR); 563 __ movf(CMPRES1, ZR);
595 __ movt(CMPRES1, TMP); 564 __ movt(CMPRES1, TMP);
596 } else { 565 } else {
597 __ movf(CMPRES1, TMP); 566 __ movf(CMPRES1, TMP);
598 __ movt(CMPRES1, ZR); 567 __ movt(CMPRES1, ZR);
599 } 568 }
600 __ mov(CMPRES2, ZR); 569 __ mov(CMPRES2, ZR);
601 570
602 // EmitBranchOnCondition expects ordering to be described by CMPRES1, CMPRES2. 571 // EmitBranchOnCondition expects ordering to be described by CMPRES1, CMPRES2.
603 EmitBranchOnCondition(compiler, 572 EmitBranchOnCondition(compiler, EQ, labels);
604 branch->true_successor(),
605 branch->false_successor(),
606 EQ);
607 }
608
609
610 static void EmitDoubleCompareBool(FlowGraphCompiler* compiler,
611 Condition true_condition,
612 FpuRegister left,
613 FpuRegister right,
614 Register result) {
615 Label done, is_true;
616 Label* nan_label = (true_condition == NE) ? &is_true : &done;
617 __ Comment("DoubleCompareBool");
618 __ LoadObject(result, Bool::False());
619 __ cund(left, right);
620 __ bc1t(nan_label);
621
622 switch (true_condition) {
623 case EQ: __ ceqd(left, right); break;
624 case NE: __ ceqd(left, right); break;
625 case LT: __ coltd(left, right); break;
626 case LE: __ coled(left, right); break;
627 case GT: __ coltd(right, left); break;
628 case GE: __ coled(right, left); break;
629 default: {
630 // Should only passing the above conditions to this function.
631 UNREACHABLE();
632 break;
633 }
634 }
635
636 if (true_condition == NE) {
637 __ bc1t(&done); // False is already in result.
638 } else {
639 __ bc1f(&done);
640 }
641 __ Bind(&is_true);
642 __ LoadObject(result, Bool::True());
643 __ Bind(&done);
644 }
645
646
647 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
648 const LocationSummary& locs,
649 Token::Kind kind,
650 BranchInstr* branch) {
651 DRegister left = locs.in(0).fpu_reg();
652 DRegister right = locs.in(1).fpu_reg();
653
654 __ Comment("DoubleComparisonOp(left=%d, right=%d)", left, right);
655
656 Condition true_condition = TokenKindToDoubleCondition(kind);
657 if (branch != NULL) {
658 EmitDoubleCompareBranch(compiler, true_condition, left, right, branch);
659 } else {
660 EmitDoubleCompareBool(compiler, true_condition,
661 left, right, locs.out().reg());
662 }
663 } 573 }
664 574
665 575
666 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 576 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
667 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 577 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
668 BranchInstr* kNoBranch = NULL;
669 __ Comment("EqualityCompareInstr"); 578 __ Comment("EqualityCompareInstr");
579
580 Label is_true, is_false;
581 BranchLabels labels = { &is_true, &is_false, &is_false };
582
670 if (operation_cid() == kSmiCid) { 583 if (operation_cid() == kSmiCid) {
671 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); 584 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
672 return; 585 } else {
586 ASSERT(operation_cid() == kDoubleCid);
587 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
673 } 588 }
674 if (operation_cid() == kMintCid) { 589 Register result = locs()->out().reg();
675 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch); 590 Label done;
676 return; 591 __ Bind(&is_false);
677 } 592 __ LoadObject(result, Bool::False());
678 if (operation_cid() == kDoubleCid) { 593 __ b(&done);
679 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); 594 __ Bind(&is_true);
680 return; 595 __ LoadObject(result, Bool::True());
681 } 596 __ Bind(&done);
682 UNREACHABLE();
683 } 597 }
684 598
685 599
686 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 600 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
687 BranchInstr* branch) { 601 BranchInstr* branch) {
688 __ TraceSimMsg("EqualityCompareInstr"); 602 __ TraceSimMsg("EqualityCompareInstr");
689 __ Comment("EqualityCompareInstr:BranchCode"); 603 __ Comment("EqualityCompareInstr:BranchCode");
690 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 604 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
605
606 BranchLabels labels = compiler->CreateBranchLabels(branch);
607
691 if (operation_cid() == kSmiCid) { 608 if (operation_cid() == kSmiCid) {
692 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 609 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
693 return; 610 } else {
611 ASSERT(operation_cid() == kDoubleCid);
612 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
694 } 613 }
695 if (operation_cid() == kMintCid) {
696 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
697 return;
698 }
699 if (operation_cid() == kDoubleCid) {
700 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
701 return;
702 }
703 UNREACHABLE();
704 } 614 }
705 615
706 616
707 LocationSummary* TestSmiInstr::MakeLocationSummary() const { 617 LocationSummary* TestSmiInstr::MakeLocationSummary() const {
708 const intptr_t kNumInputs = 2; 618 const intptr_t kNumInputs = 2;
709 const intptr_t kNumTemps = 0; 619 const intptr_t kNumTemps = 0;
710 LocationSummary* locs = 620 LocationSummary* locs =
711 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 621 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
712 locs->set_in(0, Location::RequiresRegister()); 622 locs->set_in(0, Location::RequiresRegister());
713 // Only one input can be a constant operand. The case of two constant 623 // Only one input can be a constant operand. The case of two constant
714 // operands should be handled by constant propagation. 624 // operands should be handled by constant propagation.
715 locs->set_in(1, Location::RegisterOrConstant(right())); 625 locs->set_in(1, Location::RegisterOrConstant(right()));
716 return locs; 626 return locs;
717 } 627 }
718 628
719 629
720 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 630 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
721 // Never emitted outside of the BranchInstr. 631 // Never emitted outside of the BranchInstr.
722 UNREACHABLE(); 632 UNREACHABLE();
723 } 633 }
724 634
725 635
726 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, 636 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
727 BranchInstr* branch) { 637 BranchInstr* branch) {
728 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; 638 BranchLabels labels = compiler->CreateBranchLabels(branch);
639
640 Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
729 Register left = locs()->in(0).reg(); 641 Register left = locs()->in(0).reg();
730 Location right = locs()->in(1); 642 Location right = locs()->in(1);
731 if (right.IsConstant()) { 643 if (right.IsConstant()) {
732 ASSERT(right.constant().IsSmi()); 644 ASSERT(right.constant().IsSmi());
733 const int32_t imm = 645 const int32_t imm =
734 reinterpret_cast<int32_t>(right.constant().raw()); 646 reinterpret_cast<int32_t>(right.constant().raw());
735 __ AndImmediate(CMPRES1, left, imm); 647 __ AndImmediate(CMPRES1, left, imm);
736 } else { 648 } else {
737 __ and_(CMPRES1, left, right.reg()); 649 __ and_(CMPRES1, left, right.reg());
738 } 650 }
739 __ mov(CMPRES2, ZR); 651 __ mov(CMPRES2, ZR);
740 EmitBranchOnCondition(compiler, 652 EmitBranchOnCondition(compiler, true_condition, labels);
741 branch->true_successor(),
742 branch->false_successor(),
743 branch_condition);
744 } 653 }
745 654
746 655
747 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 656 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
748 const intptr_t kNumInputs = 2; 657 const intptr_t kNumInputs = 2;
749 const intptr_t kNumTemps = 0; 658 const intptr_t kNumTemps = 0;
750 if (operation_cid() == kMintCid) { 659 if (operation_cid() == kMintCid) {
751 const intptr_t kNumTemps = 2; 660 const intptr_t kNumTemps = 2;
752 LocationSummary* locs = 661 LocationSummary* locs =
753 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 662 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 21 matching lines...) Expand all
775 summary->set_in(1, summary->in(0).IsConstant() 684 summary->set_in(1, summary->in(0).IsConstant()
776 ? Location::RequiresRegister() 685 ? Location::RequiresRegister()
777 : Location::RegisterOrConstant(right())); 686 : Location::RegisterOrConstant(right()));
778 summary->set_out(Location::RequiresRegister()); 687 summary->set_out(Location::RequiresRegister());
779 return summary; 688 return summary;
780 } 689 }
781 690
782 691
783 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 692 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
784 __ TraceSimMsg("RelationalOpInstr"); 693 __ TraceSimMsg("RelationalOpInstr");
694
695 Label is_true, is_false;
696 BranchLabels labels = { &is_true, &is_false, &is_false };
697
785 if (operation_cid() == kSmiCid) { 698 if (operation_cid() == kSmiCid) {
786 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 699 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
787 return; 700 } else {
701 ASSERT(operation_cid() == kDoubleCid);
702 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
788 } 703 }
789 if (operation_cid() == kMintCid) { 704 Register result = locs()->out().reg();
790 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); 705 Label done;
791 return; 706 __ Bind(&is_false);
792 } 707 __ LoadObject(result, Bool::False());
793 ASSERT(operation_cid() == kDoubleCid); 708 __ b(&done);
794 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); 709 __ Bind(&is_true);
795 return; 710 __ LoadObject(result, Bool::True());
711 __ Bind(&done);
796 } 712 }
797 713
798 714
799 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 715 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
800 BranchInstr* branch) { 716 BranchInstr* branch) {
801 __ TraceSimMsg("RelationalOpInstr"); 717 __ TraceSimMsg("RelationalOpInstr");
718
719 BranchLabels labels = compiler->CreateBranchLabels(branch);
720
802 if (operation_cid() == kSmiCid) { 721 if (operation_cid() == kSmiCid) {
803 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 722 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
804 return; 723 } else {
724 ASSERT(operation_cid() == kDoubleCid);
725 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
805 } 726 }
806 if (operation_cid() == kMintCid) {
807 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
808 return;
809 }
810 ASSERT(operation_cid() == kDoubleCid);
811 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
812 } 727 }
813 728
814 729
815 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 730 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
816 const intptr_t kNumInputs = 0; 731 const intptr_t kNumInputs = 0;
817 const intptr_t kNumTemps = 3; 732 const intptr_t kNumTemps = 3;
818 LocationSummary* locs = 733 LocationSummary* locs =
819 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 734 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
820 locs->set_temp(0, Location::RegisterLocation(A1)); 735 locs->set_temp(0, Location::RegisterLocation(A1));
821 locs->set_temp(1, Location::RegisterLocation(A2)); 736 locs->set_temp(1, Location::RegisterLocation(A2));
(...skipping 3018 matching lines...) Expand 10 before | Expand all | Expand 10 after
3840 // Only one of the inputs can be a constant. Choose register if the first one 3755 // Only one of the inputs can be a constant. Choose register if the first one
3841 // is a constant. 3756 // is a constant.
3842 locs->set_in(1, locs->in(0).IsConstant() 3757 locs->set_in(1, locs->in(0).IsConstant()
3843 ? Location::RequiresRegister() 3758 ? Location::RequiresRegister()
3844 : Location::RegisterOrConstant(right())); 3759 : Location::RegisterOrConstant(right()));
3845 locs->set_out(Location::RequiresRegister()); 3760 locs->set_out(Location::RequiresRegister());
3846 return locs; 3761 return locs;
3847 } 3762 }
3848 3763
3849 3764
3765 static void EmitStrictComparison(FlowGraphCompiler* compiler,
3766 StrictCompareInstr* compare,
3767 BranchLabels labels) {
3768 LocationSummary* locs = compare->locs();
3769 bool needs_number_check = compare->needs_number_check();
3770 intptr_t token_pos = compare->token_pos();
3771 Token::Kind kind = compare->kind();
3772 Location left = locs->in(0);
3773 Location right = locs->in(1);
3774 ASSERT(!left.IsConstant() || !right.IsConstant());
3775 if (left.IsConstant()) {
3776 compiler->EmitEqualityRegConstCompare(right.reg(),
3777 left.constant(),
3778 needs_number_check,
3779 token_pos);
3780 } else if (right.IsConstant()) {
3781 compiler->EmitEqualityRegConstCompare(left.reg(),
3782 right.constant(),
3783 needs_number_check,
3784 token_pos);
3785 } else {
3786 compiler->EmitEqualityRegRegCompare(left.reg(),
3787 right.reg(),
3788 needs_number_check,
3789 token_pos);
3790 }
3791 Condition true_condition = (kind == Token::kEQ_STRICT) ? EQ : NE;
3792 EmitBranchOnCondition(compiler, true_condition, labels);
3793 }
3794
3850 // Special code for numbers (compare values instead of references.) 3795 // Special code for numbers (compare values instead of references.)
3851 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3796 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3852 __ TraceSimMsg("StrictCompareInstr"); 3797 __ TraceSimMsg("StrictCompareInstr");
3853 __ Comment("StrictCompareInstr"); 3798 __ Comment("StrictCompareInstr");
3854 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 3799 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
3855 Location left = locs()->in(0); 3800
3856 Location right = locs()->in(1); 3801 Label is_true, is_false;
3857 ASSERT(!left.IsConstant() || !right.IsConstant()); 3802 BranchLabels labels = { &is_true, &is_false, &is_false };
3858 if (left.IsConstant()) { 3803
3859 compiler->EmitEqualityRegConstCompare(right.reg(), 3804 EmitStrictComparison(compiler, this, labels);
3860 left.constant(),
3861 needs_number_check(),
3862 token_pos());
3863 } else if (right.IsConstant()) {
3864 compiler->EmitEqualityRegConstCompare(left.reg(),
3865 right.constant(),
3866 needs_number_check(),
3867 token_pos());
3868 } else {
3869 compiler->EmitEqualityRegRegCompare(left.reg(),
3870 right.reg(),
3871 needs_number_check(),
3872 token_pos());
3873 }
3874 3805
3875 Register result = locs()->out().reg(); 3806 Register result = locs()->out().reg();
3876 Label load_true, done; 3807 Label done;
3877 if (kind() == Token::kEQ_STRICT) { 3808 __ Bind(&is_false);
3878 __ beq(CMPRES1, CMPRES2, &load_true);
3879 } else {
3880 ASSERT(kind() == Token::kNE_STRICT);
3881 __ bne(CMPRES1, CMPRES2, &load_true);
3882 }
3883 __ LoadObject(result, Bool::False()); 3809 __ LoadObject(result, Bool::False());
3884 __ b(&done); 3810 __ b(&done);
3885 __ Bind(&load_true); 3811 __ Bind(&is_true);
3886 __ LoadObject(result, Bool::True()); 3812 __ LoadObject(result, Bool::True());
3887 __ Bind(&done); 3813 __ Bind(&done);
3888 } 3814 }
3889 3815
3890 3816
3891 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 3817 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3892 BranchInstr* branch) { 3818 BranchInstr* branch) {
3893 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); 3819 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode");
3894 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 3820 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
3895 Location left = locs()->in(0);
3896 Location right = locs()->in(1);
3897 ASSERT(!left.IsConstant() || !right.IsConstant());
3898 if (left.IsConstant()) {
3899 compiler->EmitEqualityRegConstCompare(right.reg(),
3900 left.constant(),
3901 needs_number_check(),
3902 token_pos());
3903 } else if (right.IsConstant()) {
3904 compiler->EmitEqualityRegConstCompare(left.reg(),
3905 right.constant(),
3906 needs_number_check(),
3907 token_pos());
3908 } else {
3909 compiler->EmitEqualityRegRegCompare(left.reg(),
3910 right.reg(),
3911 needs_number_check(),
3912 token_pos());
3913 }
3914 3821
3915 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; 3822 BranchLabels labels = compiler->CreateBranchLabels(branch);
3916 EmitBranchOnCondition(compiler, 3823
3917 branch->true_successor(), 3824 EmitStrictComparison(compiler, this, labels);
3918 branch->false_successor(),
3919 true_condition);
3920 } 3825 }
3921 3826
3922 3827
3923 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 3828 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
3924 return LocationSummary::Make(1, 3829 return LocationSummary::Make(1,
3925 Location::RequiresRegister(), 3830 Location::RequiresRegister(),
3926 LocationSummary::kNoCall); 3831 LocationSummary::kNoCall);
3927 } 3832 }
3928 3833
3929 3834
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3997 compiler->GenerateCall(token_pos(), 3902 compiler->GenerateCall(token_pos(),
3998 &label, 3903 &label,
3999 PcDescriptors::kOther, 3904 PcDescriptors::kOther,
4000 locs()); 3905 locs());
4001 __ Drop(2); // Discard type arguments and receiver. 3906 __ Drop(2); // Discard type arguments and receiver.
4002 } 3907 }
4003 3908
4004 } // namespace dart 3909 } // namespace dart
4005 3910
4006 #endif // defined TARGET_ARCH_MIPS 3911 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698