| OLD | NEW |
| 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 case GT: return LE; | 120 case GT: return LE; |
| 121 case GE: return LT; | 121 case GE: return LT; |
| 122 default: | 122 default: |
| 123 OS::Print("Error: Condition not recognized: %d\n", condition); | 123 OS::Print("Error: Condition not recognized: %d\n", condition); |
| 124 UNIMPLEMENTED(); | 124 UNIMPLEMENTED(); |
| 125 return EQ; | 125 return EQ; |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 | 128 |
| 129 | 129 |
| 130 static bool BindsToSmiConstant(Value* val, intptr_t* smi_value) { | |
| 131 if (!val->BindsToConstant()) { | |
| 132 return false; | |
| 133 } | |
| 134 | |
| 135 const Object& bound_constant = val->BoundConstant(); | |
| 136 if (!bound_constant.IsSmi()) { | |
| 137 return false; | |
| 138 } | |
| 139 | |
| 140 *smi_value = Smi::Cast(bound_constant).Value(); | |
| 141 return true; | |
| 142 } | |
| 143 | |
| 144 | |
| 145 // 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. |
| 146 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 131 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
| 147 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 132 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
| 148 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 133 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
| 149 } | 134 } |
| 150 | 135 |
| 151 | 136 |
| 152 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, | |
| 153 Value* v1, | |
| 154 Value* v2) { | |
| 155 if (!(comparison->IsStrictCompare() && | |
| 156 !comparison->AsStrictCompare()->needs_number_check()) && | |
| 157 !(comparison->IsEqualityCompare() && | |
| 158 (comparison->AsEqualityCompare()->operation_cid() == kSmiCid))) { | |
| 159 return false; | |
| 160 } | |
| 161 | |
| 162 intptr_t v1_value, v2_value; | |
| 163 | |
| 164 if (!BindsToSmiConstant(v1, &v1_value) || | |
| 165 !BindsToSmiConstant(v2, &v2_value)) { | |
| 166 return false; | |
| 167 } | |
| 168 | |
| 169 return true; | |
| 170 } | |
| 171 | |
| 172 | |
| 173 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { | 137 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { |
| 174 const intptr_t kNumInputs = 2; | 138 const intptr_t kNumInputs = 2; |
| 175 const intptr_t kNumTemps = 0; | 139 const intptr_t kNumTemps = 0; |
| 176 LocationSummary* locs = | 140 LocationSummary* locs = |
| 177 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 141 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 178 locs->set_in(0, Location::RegisterOrConstant(left())); | 142 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 179 locs->set_in(1, Location::RegisterOrConstant(right())); | 143 locs->set_in(1, Location::RegisterOrConstant(right())); |
| 180 locs->set_out(Location::RequiresRegister()); | 144 locs->set_out(Location::RequiresRegister()); |
| 181 return locs; | 145 return locs; |
| 182 } | 146 } |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 case LE: return GE; | 462 case LE: return GE; |
| 499 case GT: return LT; | 463 case GT: return LT; |
| 500 case GE: return LE; | 464 case GE: return LE; |
| 501 default: | 465 default: |
| 502 UNREACHABLE(); | 466 UNREACHABLE(); |
| 503 return EQ; | 467 return EQ; |
| 504 } | 468 } |
| 505 } | 469 } |
| 506 | 470 |
| 507 | 471 |
| 472 static void EmitBranchOnValue(FlowGraphCompiler* compiler, |
| 473 TargetEntryInstr* true_successor, |
| 474 TargetEntryInstr* false_successor, |
| 475 bool value) { |
| 476 __ TraceSimMsg("ControlInstruction::EmitBranchOnValue"); |
| 477 if (value && !compiler->CanFallThroughTo(true_successor)) { |
| 478 __ b(compiler->GetJumpLabel(true_successor)); |
| 479 } else if (!value && !compiler->CanFallThroughTo(false_successor)) { |
| 480 __ b(compiler->GetJumpLabel(false_successor)); |
| 481 } |
| 482 } |
| 483 |
| 484 |
| 485 // The comparison result is in CMPRES1. |
| 486 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 487 TargetEntryInstr* true_successor, |
| 488 TargetEntryInstr* false_successor, |
| 489 Condition true_condition) { |
| 490 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition"); |
| 491 if (compiler->CanFallThroughTo(false_successor)) { |
| 492 // If the next block is the false successor, fall through to it. |
| 493 Label* label = compiler->GetJumpLabel(true_successor); |
| 494 EmitBranchAfterCompare(compiler, true_condition, label); |
| 495 } else { |
| 496 // If the next block is not the false successor, branch to it. |
| 497 Condition false_condition = NegateCondition(true_condition); |
| 498 Label* label = compiler->GetJumpLabel(false_successor); |
| 499 EmitBranchAfterCompare(compiler, false_condition, label); |
| 500 // Fall through or jump to the true successor. |
| 501 if (!compiler->CanFallThroughTo(true_successor)) { |
| 502 __ b(compiler->GetJumpLabel(true_successor)); |
| 503 } |
| 504 } |
| 505 } |
| 506 |
| 507 |
| 508 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, | 508 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, |
| 509 const LocationSummary& locs, | 509 const LocationSummary& locs, |
| 510 Token::Kind kind, | 510 Token::Kind kind, |
| 511 BranchInstr* branch) { | 511 BranchInstr* branch) { |
| 512 __ TraceSimMsg("EmitSmiComparisonOp"); | 512 __ TraceSimMsg("EmitSmiComparisonOp"); |
| 513 __ Comment("EmitSmiComparisonOp"); | 513 __ Comment("EmitSmiComparisonOp"); |
| 514 Location left = locs.in(0); | 514 Location left = locs.in(0); |
| 515 Location right = locs.in(1); | 515 Location right = locs.in(1); |
| 516 ASSERT(!left.IsConstant() || !right.IsConstant()); | 516 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 517 | 517 |
| 518 Condition true_condition = TokenKindToSmiCondition(kind); | 518 Condition true_condition = TokenKindToSmiCondition(kind); |
| 519 | 519 |
| 520 if (left.IsConstant()) { | 520 if (left.IsConstant()) { |
| 521 __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant()); | 521 __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant()); |
| 522 true_condition = FlipCondition(true_condition); | 522 true_condition = FlipCondition(true_condition); |
| 523 } else if (right.IsConstant()) { | 523 } else if (right.IsConstant()) { |
| 524 __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant()); | 524 __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant()); |
| 525 } else { | 525 } else { |
| 526 __ slt(CMPRES1, left.reg(), right.reg()); | 526 __ slt(CMPRES1, left.reg(), right.reg()); |
| 527 __ slt(CMPRES2, right.reg(), left.reg()); | 527 __ slt(CMPRES2, right.reg(), left.reg()); |
| 528 } | 528 } |
| 529 | 529 |
| 530 if (branch != NULL) { | 530 if (branch != NULL) { |
| 531 branch->EmitBranchOnCondition(compiler, true_condition); | 531 EmitBranchOnCondition(compiler, |
| 532 branch->true_successor(), |
| 533 branch->false_successor(), |
| 534 true_condition); |
| 532 } else { | 535 } else { |
| 533 Register result = locs.out().reg(); | 536 Register result = locs.out().reg(); |
| 534 Label done, is_true; | 537 Label done, is_true; |
| 535 EmitBranchAfterCompare(compiler, true_condition, &is_true); | 538 EmitBranchAfterCompare(compiler, true_condition, &is_true); |
| 536 __ LoadObject(result, Bool::False()); | 539 __ LoadObject(result, Bool::False()); |
| 537 __ b(&done); | 540 __ b(&done); |
| 538 __ Bind(&is_true); | 541 __ Bind(&is_true); |
| 539 __ LoadObject(result, Bool::True()); | 542 __ LoadObject(result, Bool::True()); |
| 540 __ Bind(&done); | 543 __ Bind(&done); |
| 541 } | 544 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 566 case Token::kGT: return GT; | 569 case Token::kGT: return GT; |
| 567 case Token::kLTE: return LE; | 570 case Token::kLTE: return LE; |
| 568 case Token::kGTE: return GE; | 571 case Token::kGTE: return GE; |
| 569 default: | 572 default: |
| 570 UNREACHABLE(); | 573 UNREACHABLE(); |
| 571 return VS; | 574 return VS; |
| 572 } | 575 } |
| 573 } | 576 } |
| 574 | 577 |
| 575 | 578 |
| 579 static void EmitDoubleCompareBranch(FlowGraphCompiler* compiler, |
| 580 Condition true_condition, |
| 581 FpuRegister left, |
| 582 FpuRegister right, |
| 583 BranchInstr* branch) { |
| 584 ASSERT(branch != NULL); |
| 585 __ Comment("DoubleCompareBranch"); |
| 586 __ cund(left, right); |
| 587 BlockEntryInstr* nan_result = (true_condition == NE) ? |
| 588 branch->true_successor() : branch->false_successor(); |
| 589 __ bc1t(compiler->GetJumpLabel(nan_result)); |
| 590 |
| 591 switch (true_condition) { |
| 592 case EQ: __ ceqd(left, right); break; |
| 593 case NE: __ ceqd(left, right); break; |
| 594 case LT: __ coltd(left, right); break; |
| 595 case LE: __ coled(left, right); break; |
| 596 case GT: __ coltd(right, left); break; |
| 597 case GE: __ coled(right, left); break; |
| 598 default: { |
| 599 // Should only passing the above conditions to this function. |
| 600 UNREACHABLE(); |
| 601 break; |
| 602 } |
| 603 } |
| 604 |
| 605 __ LoadImmediate(TMP, 1); |
| 606 if (true_condition == NE) { |
| 607 __ movf(CMPRES1, ZR); |
| 608 __ movt(CMPRES1, TMP); |
| 609 } else { |
| 610 __ movf(CMPRES1, TMP); |
| 611 __ movt(CMPRES1, ZR); |
| 612 } |
| 613 __ mov(CMPRES2, ZR); |
| 614 |
| 615 // EmitBranchOnCondition expects ordering to be described by CMPRES1, CMPRES2. |
| 616 EmitBranchOnCondition(compiler, |
| 617 branch->true_successor(), |
| 618 branch->false_successor(), |
| 619 EQ); |
| 620 } |
| 621 |
| 622 |
| 623 static void EmitDoubleCompareBool(FlowGraphCompiler* compiler, |
| 624 Condition true_condition, |
| 625 FpuRegister left, |
| 626 FpuRegister right, |
| 627 Register result) { |
| 628 Label done, is_true; |
| 629 Label* nan_label = (true_condition == NE) ? &is_true : &done; |
| 630 __ Comment("DoubleCompareBool"); |
| 631 __ LoadObject(result, Bool::False()); |
| 632 __ cund(left, right); |
| 633 __ bc1t(nan_label); |
| 634 |
| 635 switch (true_condition) { |
| 636 case EQ: __ ceqd(left, right); break; |
| 637 case NE: __ ceqd(left, right); break; |
| 638 case LT: __ coltd(left, right); break; |
| 639 case LE: __ coled(left, right); break; |
| 640 case GT: __ coltd(right, left); break; |
| 641 case GE: __ coled(right, left); break; |
| 642 default: { |
| 643 // Should only passing the above conditions to this function. |
| 644 UNREACHABLE(); |
| 645 break; |
| 646 } |
| 647 } |
| 648 |
| 649 if (true_condition == NE) { |
| 650 __ bc1t(&done); // False is already in result. |
| 651 } else { |
| 652 __ bc1f(&done); |
| 653 } |
| 654 __ Bind(&is_true); |
| 655 __ LoadObject(result, Bool::True()); |
| 656 __ Bind(&done); |
| 657 } |
| 658 |
| 659 |
| 576 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, | 660 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, |
| 577 const LocationSummary& locs, | 661 const LocationSummary& locs, |
| 578 Token::Kind kind, | 662 Token::Kind kind, |
| 579 BranchInstr* branch) { | 663 BranchInstr* branch) { |
| 580 DRegister left = locs.in(0).fpu_reg(); | 664 DRegister left = locs.in(0).fpu_reg(); |
| 581 DRegister right = locs.in(1).fpu_reg(); | 665 DRegister right = locs.in(1).fpu_reg(); |
| 582 | 666 |
| 583 __ Comment("DoubleComparisonOp(left=%d, right=%d)", left, right); | 667 __ Comment("DoubleComparisonOp(left=%d, right=%d)", left, right); |
| 584 | 668 |
| 585 Condition true_condition = TokenKindToDoubleCondition(kind); | 669 Condition true_condition = TokenKindToDoubleCondition(kind); |
| 586 if (branch != NULL) { | 670 if (branch != NULL) { |
| 587 compiler->EmitDoubleCompareBranch( | 671 EmitDoubleCompareBranch(compiler, true_condition, left, right, branch); |
| 588 true_condition, left, right, branch); | |
| 589 } else { | 672 } else { |
| 590 compiler->EmitDoubleCompareBool( | 673 EmitDoubleCompareBool(compiler, true_condition, |
| 591 true_condition, left, right, locs.out().reg()); | 674 left, right, locs.out().reg()); |
| 592 } | 675 } |
| 593 } | 676 } |
| 594 | 677 |
| 595 | 678 |
| 596 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 679 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 597 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 680 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 598 BranchInstr* kNoBranch = NULL; | 681 BranchInstr* kNoBranch = NULL; |
| 599 __ Comment("EqualityCompareInstr"); | 682 __ Comment("EqualityCompareInstr"); |
| 600 if (operation_cid() == kSmiCid) { | 683 if (operation_cid() == kSmiCid) { |
| 601 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); | 684 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 Location right = locs()->in(1); | 744 Location right = locs()->in(1); |
| 662 if (right.IsConstant()) { | 745 if (right.IsConstant()) { |
| 663 ASSERT(right.constant().IsSmi()); | 746 ASSERT(right.constant().IsSmi()); |
| 664 const int32_t imm = | 747 const int32_t imm = |
| 665 reinterpret_cast<int32_t>(right.constant().raw()); | 748 reinterpret_cast<int32_t>(right.constant().raw()); |
| 666 __ AndImmediate(CMPRES1, left, imm); | 749 __ AndImmediate(CMPRES1, left, imm); |
| 667 } else { | 750 } else { |
| 668 __ and_(CMPRES1, left, right.reg()); | 751 __ and_(CMPRES1, left, right.reg()); |
| 669 } | 752 } |
| 670 __ mov(CMPRES2, ZR); | 753 __ mov(CMPRES2, ZR); |
| 671 branch->EmitBranchOnCondition(compiler, branch_condition); | 754 EmitBranchOnCondition(compiler, |
| 755 branch->true_successor(), |
| 756 branch->false_successor(), |
| 757 branch_condition); |
| 672 } | 758 } |
| 673 | 759 |
| 674 | 760 |
| 675 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 761 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| 676 const intptr_t kNumInputs = 2; | 762 const intptr_t kNumInputs = 2; |
| 677 const intptr_t kNumTemps = 0; | 763 const intptr_t kNumTemps = 0; |
| 678 if (operation_cid() == kMintCid) { | 764 if (operation_cid() == kMintCid) { |
| 679 const intptr_t kNumTemps = 2; | 765 const intptr_t kNumTemps = 2; |
| 680 LocationSummary* locs = | 766 LocationSummary* locs = |
| 681 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 767 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| (...skipping 3021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3703 } | 3789 } |
| 3704 | 3790 |
| 3705 // We can fall through if the successor is the next block in the list. | 3791 // We can fall through if the successor is the next block in the list. |
| 3706 // Otherwise, we need a jump. | 3792 // Otherwise, we need a jump. |
| 3707 if (!compiler->CanFallThroughTo(successor())) { | 3793 if (!compiler->CanFallThroughTo(successor())) { |
| 3708 __ b(compiler->GetJumpLabel(successor())); | 3794 __ b(compiler->GetJumpLabel(successor())); |
| 3709 } | 3795 } |
| 3710 } | 3796 } |
| 3711 | 3797 |
| 3712 | 3798 |
| 3713 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler, | |
| 3714 bool value) { | |
| 3715 __ TraceSimMsg("ControlInstruction::EmitBranchOnValue"); | |
| 3716 if (value && !compiler->CanFallThroughTo(true_successor())) { | |
| 3717 __ b(compiler->GetJumpLabel(true_successor())); | |
| 3718 } else if (!value && !compiler->CanFallThroughTo(false_successor())) { | |
| 3719 __ b(compiler->GetJumpLabel(false_successor())); | |
| 3720 } | |
| 3721 } | |
| 3722 | |
| 3723 | |
| 3724 // The comparison result is in CMPRES1. | |
| 3725 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler, | |
| 3726 Condition true_condition) { | |
| 3727 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition"); | |
| 3728 if (compiler->CanFallThroughTo(false_successor())) { | |
| 3729 // If the next block is the false successor, fall through to it. | |
| 3730 Label* label = compiler->GetJumpLabel(true_successor()); | |
| 3731 EmitBranchAfterCompare(compiler, true_condition, label); | |
| 3732 } else { | |
| 3733 // If the next block is not the false successor, branch to it. | |
| 3734 Condition false_condition = NegateCondition(true_condition); | |
| 3735 Label* label = compiler->GetJumpLabel(false_successor()); | |
| 3736 EmitBranchAfterCompare(compiler, false_condition, label); | |
| 3737 // Fall through or jump to the true successor. | |
| 3738 if (!compiler->CanFallThroughTo(true_successor())) { | |
| 3739 __ b(compiler->GetJumpLabel(true_successor())); | |
| 3740 } | |
| 3741 } | |
| 3742 } | |
| 3743 | |
| 3744 | |
| 3745 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { | 3799 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { |
| 3746 return LocationSummary::Make(0, | 3800 return LocationSummary::Make(0, |
| 3747 Location::RequiresRegister(), | 3801 Location::RequiresRegister(), |
| 3748 LocationSummary::kNoCall); | 3802 LocationSummary::kNoCall); |
| 3749 } | 3803 } |
| 3750 | 3804 |
| 3751 | 3805 |
| 3752 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3806 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3753 __ mov(locs()->out().reg(), CTX); | 3807 __ mov(locs()->out().reg(), CTX); |
| 3754 } | 3808 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3818 BranchInstr* branch) { | 3872 BranchInstr* branch) { |
| 3819 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); | 3873 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); |
| 3820 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 3874 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 3821 Location left = locs()->in(0); | 3875 Location left = locs()->in(0); |
| 3822 Location right = locs()->in(1); | 3876 Location right = locs()->in(1); |
| 3823 if (left.IsConstant() && right.IsConstant()) { | 3877 if (left.IsConstant() && right.IsConstant()) { |
| 3824 // TODO(vegorov): should be eliminated earlier by constant propagation. | 3878 // TODO(vegorov): should be eliminated earlier by constant propagation. |
| 3825 const bool result = (kind() == Token::kEQ_STRICT) ? | 3879 const bool result = (kind() == Token::kEQ_STRICT) ? |
| 3826 left.constant().raw() == right.constant().raw() : | 3880 left.constant().raw() == right.constant().raw() : |
| 3827 left.constant().raw() != right.constant().raw(); | 3881 left.constant().raw() != right.constant().raw(); |
| 3828 branch->EmitBranchOnValue(compiler, result); | 3882 EmitBranchOnValue(compiler, |
| 3883 branch->true_successor(), |
| 3884 branch->false_successor(), |
| 3885 result); |
| 3829 return; | 3886 return; |
| 3830 } | 3887 } |
| 3831 if (left.IsConstant()) { | 3888 if (left.IsConstant()) { |
| 3832 compiler->EmitEqualityRegConstCompare(right.reg(), | 3889 compiler->EmitEqualityRegConstCompare(right.reg(), |
| 3833 left.constant(), | 3890 left.constant(), |
| 3834 needs_number_check(), | 3891 needs_number_check(), |
| 3835 token_pos()); | 3892 token_pos()); |
| 3836 } else if (right.IsConstant()) { | 3893 } else if (right.IsConstant()) { |
| 3837 compiler->EmitEqualityRegConstCompare(left.reg(), | 3894 compiler->EmitEqualityRegConstCompare(left.reg(), |
| 3838 right.constant(), | 3895 right.constant(), |
| 3839 needs_number_check(), | 3896 needs_number_check(), |
| 3840 token_pos()); | 3897 token_pos()); |
| 3841 } else { | 3898 } else { |
| 3842 compiler->EmitEqualityRegRegCompare(left.reg(), | 3899 compiler->EmitEqualityRegRegCompare(left.reg(), |
| 3843 right.reg(), | 3900 right.reg(), |
| 3844 needs_number_check(), | 3901 needs_number_check(), |
| 3845 token_pos()); | 3902 token_pos()); |
| 3846 } | 3903 } |
| 3847 | 3904 |
| 3848 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; | 3905 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; |
| 3849 branch->EmitBranchOnCondition(compiler, true_condition); | 3906 EmitBranchOnCondition(compiler, |
| 3907 branch->true_successor(), |
| 3908 branch->false_successor(), |
| 3909 true_condition); |
| 3850 } | 3910 } |
| 3851 | 3911 |
| 3852 | 3912 |
| 3853 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { | 3913 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { |
| 3854 return LocationSummary::Make(1, | 3914 return LocationSummary::Make(1, |
| 3855 Location::RequiresRegister(), | 3915 Location::RequiresRegister(), |
| 3856 LocationSummary::kNoCall); | 3916 LocationSummary::kNoCall); |
| 3857 } | 3917 } |
| 3858 | 3918 |
| 3859 | 3919 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3927 compiler->GenerateCall(token_pos(), | 3987 compiler->GenerateCall(token_pos(), |
| 3928 &label, | 3988 &label, |
| 3929 PcDescriptors::kOther, | 3989 PcDescriptors::kOther, |
| 3930 locs()); | 3990 locs()); |
| 3931 __ Drop(2); // Discard type arguments and receiver. | 3991 __ Drop(2); // Discard type arguments and receiver. |
| 3932 } | 3992 } |
| 3933 | 3993 |
| 3934 } // namespace dart | 3994 } // namespace dart |
| 3935 | 3995 |
| 3936 #endif // defined TARGET_ARCH_MIPS | 3996 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |