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

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

Issue 2937933002: Reduce copying, redundancy & repetition for codegen of comparison instructions (Closed)
Patch Set: Feedback from Slava Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_dbc.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 158
159 159
160 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 160 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
161 const Register result = locs()->out(0).reg(); 161 const Register result = locs()->out(0).reg();
162 162
163 Location left = locs()->in(0); 163 Location left = locs()->in(0);
164 Location right = locs()->in(1); 164 Location right = locs()->in(1);
165 ASSERT(!left.IsConstant() || !right.IsConstant()); 165 ASSERT(!left.IsConstant() || !right.IsConstant());
166 166
167 // Emit comparison code. This must not overwrite the result register. 167 // Emit comparison code. This must not overwrite the result register.
168 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
169 // the labels or returning an invalid condition.
168 BranchLabels labels = {NULL, NULL, NULL}; 170 BranchLabels labels = {NULL, NULL, NULL};
169 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); 171 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
172 ASSERT(true_condition != kInvalidCondition);
170 173
171 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); 174 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
172 175
173 intptr_t true_value = if_true_; 176 intptr_t true_value = if_true_;
174 intptr_t false_value = if_false_; 177 intptr_t false_value = if_false_;
175 178
176 if (is_power_of_two_kind) { 179 if (is_power_of_two_kind) {
177 if (true_value == 0) { 180 if (true_value == 0) {
178 // We need to have zero in result on true_condition. 181 // We need to have zero in result on true_condition.
179 true_condition = NegateCondition(true_condition); 182 true_condition = NegateCondition(true_condition);
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 return GE; 536 return GE;
534 default: 537 default:
535 UNREACHABLE(); 538 UNREACHABLE();
536 return VS; 539 return VS;
537 } 540 }
538 } 541 }
539 542
540 543
541 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 544 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
542 LocationSummary* locs, 545 LocationSummary* locs,
546 BranchLabels labels,
543 Token::Kind kind) { 547 Token::Kind kind) {
544 const VRegister left = locs->in(0).fpu_reg(); 548 const VRegister left = locs->in(0).fpu_reg();
545 const VRegister right = locs->in(1).fpu_reg(); 549 const VRegister right = locs->in(1).fpu_reg();
546 __ fcmpd(left, right); 550 __ fcmpd(left, right);
547 Condition true_condition = TokenKindToDoubleCondition(kind); 551 Condition true_condition = TokenKindToDoubleCondition(kind);
552 if (true_condition != NE) {
553 // Special case for NaN comparison. Result is always false unless
554 // relational operator is !=.
555 __ b(labels.false_label, VS);
556 }
548 return true_condition; 557 return true_condition;
549 } 558 }
550 559
551 560
552 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 561 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
553 BranchLabels labels) { 562 BranchLabels labels) {
554 if (operation_cid() == kSmiCid) { 563 if (operation_cid() == kSmiCid) {
555 return EmitSmiComparisonOp(compiler, locs(), kind()); 564 return EmitSmiComparisonOp(compiler, locs(), kind());
556 } else { 565 } else {
557 ASSERT(operation_cid() == kDoubleCid); 566 ASSERT(operation_cid() == kDoubleCid);
558 return EmitDoubleComparisonOp(compiler, locs(), kind()); 567 return EmitDoubleComparisonOp(compiler, locs(), labels, kind());
559 } 568 }
560 } 569 }
561 570
562 571
563 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
564 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
565 Label is_true, is_false;
566 BranchLabels labels = {&is_true, &is_false, &is_false};
567 Condition true_condition = EmitComparisonCode(compiler, labels);
568 if ((operation_cid() == kDoubleCid) && (true_condition != NE)) {
569 // Special case for NaN comparison. Result is always false unless
570 // relational operator is !=.
571 __ b(&is_false, VS);
572 }
573 EmitBranchOnCondition(compiler, true_condition, labels);
574 // TODO(zra): instead of branching, use the csel instruction to get
575 // True or False into result.
576 const Register result = locs()->out(0).reg();
577 Label done;
578 __ Bind(&is_false);
579 __ LoadObject(result, Bool::False());
580 __ b(&done);
581 __ Bind(&is_true);
582 __ LoadObject(result, Bool::True());
583 __ Bind(&done);
584 }
585
586
587 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
588 BranchInstr* branch) {
589 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
590
591 BranchLabels labels = compiler->CreateBranchLabels(branch);
592 Condition true_condition = EmitComparisonCode(compiler, labels);
593 if ((operation_cid() == kDoubleCid) && (true_condition != NE)) {
594 // Special case for NaN comparison. Result is always false unless
595 // relational operator is !=.
596 __ b(labels.false_label, VS);
597 }
598 EmitBranchOnCondition(compiler, true_condition, labels);
599 }
600
601
602 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { 572 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const {
603 const intptr_t kNumInputs = 2; 573 const intptr_t kNumInputs = 2;
604 const intptr_t kNumTemps = 0; 574 const intptr_t kNumTemps = 0;
605 LocationSummary* locs = new (zone) 575 LocationSummary* locs = new (zone)
606 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 576 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
607 locs->set_in(0, Location::RequiresRegister()); 577 locs->set_in(0, Location::RequiresRegister());
608 // Only one input can be a constant operand. The case of two constant 578 // Only one input can be a constant operand. The case of two constant
609 // operands should be handled by constant propagation. 579 // operands should be handled by constant propagation.
610 locs->set_in(1, Location::RegisterOrConstant(right())); 580 locs->set_in(1, Location::RegisterOrConstant(right()));
611 return locs; 581 return locs;
612 } 582 }
613 583
614 584
615 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 585 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
616 BranchLabels labels) { 586 BranchLabels labels) {
617 const Register left = locs()->in(0).reg(); 587 const Register left = locs()->in(0).reg();
618 Location right = locs()->in(1); 588 Location right = locs()->in(1);
619 if (right.IsConstant()) { 589 if (right.IsConstant()) {
620 ASSERT(right.constant().IsSmi()); 590 ASSERT(right.constant().IsSmi());
621 const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw()); 591 const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw());
622 __ TestImmediate(left, imm); 592 __ TestImmediate(left, imm);
623 } else { 593 } else {
624 __ tst(left, Operand(right.reg())); 594 __ tst(left, Operand(right.reg()));
625 } 595 }
626 Condition true_condition = (kind() == Token::kNE) ? NE : EQ; 596 Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
627 return true_condition; 597 return true_condition;
628 } 598 }
629 599
630 600
631 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
632 // Never emitted outside of the BranchInstr.
633 UNREACHABLE();
634 }
635
636
637 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
638 BranchInstr* branch) {
639 BranchLabels labels = compiler->CreateBranchLabels(branch);
640 Condition true_condition = EmitComparisonCode(compiler, labels);
641 EmitBranchOnCondition(compiler, true_condition, labels);
642 }
643
644
645 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, 601 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
646 bool opt) const { 602 bool opt) const {
647 const intptr_t kNumInputs = 1; 603 const intptr_t kNumInputs = 1;
648 const intptr_t kNumTemps = 1; 604 const intptr_t kNumTemps = 1;
649 LocationSummary* locs = new (zone) 605 LocationSummary* locs = new (zone)
650 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 606 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
651 locs->set_in(0, Location::RequiresRegister()); 607 locs->set_in(0, Location::RequiresRegister());
652 locs->set_temp(0, Location::RequiresRegister()); 608 locs->set_temp(0, Location::RequiresRegister());
653 locs->set_out(0, Location::RequiresRegister()); 609 locs->set_out(0, Location::RequiresRegister());
654 return locs; 610 return locs;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 // If the cid is not in the list, jump to the opposite label from the cids 643 // If the cid is not in the list, jump to the opposite label from the cids
688 // that are in the list. These must be all the same (see asserts in the 644 // that are in the list. These must be all the same (see asserts in the
689 // constructor). 645 // constructor).
690 Label* target = result ? labels.false_label : labels.true_label; 646 Label* target = result ? labels.false_label : labels.true_label;
691 if (target != labels.fall_through) { 647 if (target != labels.fall_through) {
692 __ b(target); 648 __ b(target);
693 } 649 }
694 } else { 650 } else {
695 __ b(deopt); 651 __ b(deopt);
696 } 652 }
697 // Dummy result as the last instruction is a jump, any conditional 653 // Dummy result as this method already did the jump, there's no need
698 // branch using the result will therefore be skipped. 654 // for the caller to branch on a condition.
699 return EQ; 655 return kInvalidCondition;
700 } 656 }
701 657
702 658
703 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler,
704 BranchInstr* branch) {
705 BranchLabels labels = compiler->CreateBranchLabels(branch);
706 EmitComparisonCode(compiler, labels);
707 }
708
709
710 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
711 const Register result_reg = locs()->out(0).reg();
712 Label is_true, is_false, done;
713 BranchLabels labels = {&is_true, &is_false, &is_false};
714 EmitComparisonCode(compiler, labels);
715 // TODO(zra): instead of branching, use the csel instruction to get
716 // True or False into result.
717 __ Bind(&is_false);
718 __ LoadObject(result_reg, Bool::False());
719 __ b(&done);
720 __ Bind(&is_true);
721 __ LoadObject(result_reg, Bool::True());
722 __ Bind(&done);
723 }
724
725
726 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, 659 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
727 bool opt) const { 660 bool opt) const {
728 const intptr_t kNumInputs = 2; 661 const intptr_t kNumInputs = 2;
729 const intptr_t kNumTemps = 0; 662 const intptr_t kNumTemps = 0;
730 if (operation_cid() == kDoubleCid) { 663 if (operation_cid() == kDoubleCid) {
731 LocationSummary* summary = new (zone) 664 LocationSummary* summary = new (zone)
732 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 665 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
733 summary->set_in(0, Location::RequiresFpuRegister()); 666 summary->set_in(0, Location::RequiresFpuRegister());
734 summary->set_in(1, Location::RequiresFpuRegister()); 667 summary->set_in(1, Location::RequiresFpuRegister());
735 summary->set_out(0, Location::RequiresRegister()); 668 summary->set_out(0, Location::RequiresRegister());
(...skipping 12 matching lines...) Expand all
748 return summary; 681 return summary;
749 } 682 }
750 683
751 684
752 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 685 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
753 BranchLabels labels) { 686 BranchLabels labels) {
754 if (operation_cid() == kSmiCid) { 687 if (operation_cid() == kSmiCid) {
755 return EmitSmiComparisonOp(compiler, locs(), kind()); 688 return EmitSmiComparisonOp(compiler, locs(), kind());
756 } else { 689 } else {
757 ASSERT(operation_cid() == kDoubleCid); 690 ASSERT(operation_cid() == kDoubleCid);
758 return EmitDoubleComparisonOp(compiler, locs(), kind()); 691 return EmitDoubleComparisonOp(compiler, locs(), labels, kind());
759 } 692 }
760 } 693 }
761 694
762 695
763 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
764 Label is_true, is_false;
765 BranchLabels labels = {&is_true, &is_false, &is_false};
766 Condition true_condition = EmitComparisonCode(compiler, labels);
767 if ((operation_cid() == kDoubleCid) && (true_condition != NE)) {
768 // Special case for NaN comparison. Result is always false unless
769 // relational operator is !=.
770 __ b(&is_false, VS);
771 }
772 EmitBranchOnCondition(compiler, true_condition, labels);
773 // TODO(zra): instead of branching, use the csel instruction to get
774 // True or False into result.
775 const Register result = locs()->out(0).reg();
776 Label done;
777 __ Bind(&is_false);
778 __ LoadObject(result, Bool::False());
779 __ b(&done);
780 __ Bind(&is_true);
781 __ LoadObject(result, Bool::True());
782 __ Bind(&done);
783 }
784
785
786 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
787 BranchInstr* branch) {
788 BranchLabels labels = compiler->CreateBranchLabels(branch);
789 Condition true_condition = EmitComparisonCode(compiler, labels);
790 if ((operation_cid() == kDoubleCid) && (true_condition != NE)) {
791 // Special case for NaN comparison. Result is always false unless
792 // relational operator is !=.
793 __ b(labels.false_label, VS);
794 }
795 EmitBranchOnCondition(compiler, true_condition, labels);
796 }
797
798
799 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, 696 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone,
800 bool opt) const { 697 bool opt) const {
801 return MakeCallSummary(zone); 698 return MakeCallSummary(zone);
802 } 699 }
803 700
804 701
805 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 702 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
806 SetupNative(); 703 SetupNative();
807 const Register result = locs()->out(0).reg(); 704 const Register result = locs()->out(0).reg();
808 705
(...skipping 2301 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 3007
3111 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, 3008 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3112 BranchInstr* branch) { 3009 BranchInstr* branch) {
3113 BranchLabels labels = compiler->CreateBranchLabels(branch); 3010 BranchLabels labels = compiler->CreateBranchLabels(branch);
3114 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( 3011 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
3115 this, compiler->CurrentTryIndex(), labels, 3012 this, compiler->CurrentTryIndex(), labels,
3116 /* merged = */ true); 3013 /* merged = */ true);
3117 compiler->AddSlowPathCode(slow_path); 3014 compiler->AddSlowPathCode(slow_path);
3118 EMIT_SMI_CHECK; 3015 EMIT_SMI_CHECK;
3119 Condition true_condition = EmitComparisonCode(compiler, labels); 3016 Condition true_condition = EmitComparisonCode(compiler, labels);
3017 ASSERT(true_condition != kInvalidCondition);
3120 EmitBranchOnCondition(compiler, true_condition, labels); 3018 EmitBranchOnCondition(compiler, true_condition, labels);
3121 __ Bind(slow_path->exit_label()); 3019 __ Bind(slow_path->exit_label());
3122 } 3020 }
3123 3021
3124 3022
3125 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3023 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3126 Label true_label, false_label, done; 3024 Label true_label, false_label, done;
3127 BranchLabels labels = {&true_label, &false_label, &false_label}; 3025 BranchLabels labels = {&true_label, &false_label, &false_label};
3128 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( 3026 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
3129 this, compiler->CurrentTryIndex(), labels, 3027 this, compiler->CurrentTryIndex(), labels,
3130 /* merged = */ false); 3028 /* merged = */ false);
3131 compiler->AddSlowPathCode(slow_path); 3029 compiler->AddSlowPathCode(slow_path);
3132 EMIT_SMI_CHECK; 3030 EMIT_SMI_CHECK;
3133 Condition true_condition = EmitComparisonCode(compiler, labels); 3031 Condition true_condition = EmitComparisonCode(compiler, labels);
3032 ASSERT(true_condition != kInvalidCondition);
3134 EmitBranchOnCondition(compiler, true_condition, labels); 3033 EmitBranchOnCondition(compiler, true_condition, labels);
3135 Register result = locs()->out(0).reg(); 3034 Register result = locs()->out(0).reg();
3136 __ Bind(&false_label); 3035 __ Bind(&false_label);
3137 __ LoadObject(result, Bool::False()); 3036 __ LoadObject(result, Bool::False());
3138 __ b(&done); 3037 __ b(&done);
3139 __ Bind(&true_label); 3038 __ Bind(&true_label);
3140 __ LoadObject(result, Bool::True()); 3039 __ LoadObject(result, Bool::True());
3141 __ Bind(&done); 3040 __ Bind(&done);
3142 __ Bind(slow_path->exit_label()); 3041 __ Bind(slow_path->exit_label());
3143 } 3042 }
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
3752 __ vmovrd(temp, value, 0); 3651 __ vmovrd(temp, value, 0);
3753 // Mask off the sign. 3652 // Mask off the sign.
3754 __ AndImmediate(temp, temp, 0x7FFFFFFFFFFFFFFFLL); 3653 __ AndImmediate(temp, temp, 0x7FFFFFFFFFFFFFFFLL);
3755 // Compare with +infinity. 3654 // Compare with +infinity.
3756 __ CompareImmediate(temp, 0x7FF0000000000000LL); 3655 __ CompareImmediate(temp, 0x7FF0000000000000LL);
3757 return is_negated ? NE : EQ; 3656 return is_negated ? NE : EQ;
3758 } 3657 }
3759 } 3658 }
3760 3659
3761 3660
3762 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3763 BranchInstr* branch) {
3764 ASSERT(compiler->is_optimizing());
3765 BranchLabels labels = compiler->CreateBranchLabels(branch);
3766 Condition true_condition = EmitComparisonCode(compiler, labels);
3767 EmitBranchOnCondition(compiler, true_condition, labels);
3768 }
3769
3770
3771 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3772 ASSERT(compiler->is_optimizing());
3773 Label is_true, is_false;
3774 BranchLabels labels = {&is_true, &is_false, &is_false};
3775 Condition true_condition = EmitComparisonCode(compiler, labels);
3776 const Register result = locs()->out(0).reg();
3777 if (op_kind() == MethodRecognizer::kDouble_getIsNaN) {
3778 __ LoadObject(result, Bool::False());
3779 __ LoadObject(TMP, Bool::True());
3780 __ csel(result, TMP, result, true_condition);
3781 } else {
3782 __ LoadObject(result, Bool::False());
3783 __ LoadObject(TMP, Bool::True());
3784 __ csel(result, TMP, result, true_condition);
3785 }
3786 }
3787
3788
3789 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, 3661 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone,
3790 bool opt) const { 3662 bool opt) const {
3791 const intptr_t kNumInputs = 2; 3663 const intptr_t kNumInputs = 2;
3792 const intptr_t kNumTemps = 0; 3664 const intptr_t kNumTemps = 0;
3793 LocationSummary* summary = new (zone) 3665 LocationSummary* summary = new (zone)
3794 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3666 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3795 summary->set_in(0, Location::RequiresFpuRegister()); 3667 summary->set_in(0, Location::RequiresFpuRegister());
3796 summary->set_in(1, Location::RequiresFpuRegister()); 3668 summary->set_in(1, Location::RequiresFpuRegister());
3797 summary->set_out(0, Location::RequiresFpuRegister()); 3669 summary->set_out(0, Location::RequiresFpuRegister());
3798 return summary; 3670 return summary;
(...skipping 2183 matching lines...) Expand 10 before | Expand all | Expand 10 after
5982 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); 5854 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
5983 } 5855 }
5984 if (kind() != Token::kEQ_STRICT) { 5856 if (kind() != Token::kEQ_STRICT) {
5985 ASSERT(kind() == Token::kNE_STRICT); 5857 ASSERT(kind() == Token::kNE_STRICT);
5986 true_condition = NegateCondition(true_condition); 5858 true_condition = NegateCondition(true_condition);
5987 } 5859 }
5988 return true_condition; 5860 return true_condition;
5989 } 5861 }
5990 5862
5991 5863
5992 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5864 void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5993 __ Comment("StrictCompareInstr");
5994 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
5995
5996 Label is_true, is_false; 5865 Label is_true, is_false;
5997 BranchLabels labels = {&is_true, &is_false, &is_false}; 5866 BranchLabels labels = {&is_true, &is_false, &is_false};
5998 Condition true_condition = EmitComparisonCode(compiler, labels); 5867 Condition true_condition = EmitComparisonCode(compiler, labels);
5999 EmitBranchOnCondition(compiler, true_condition, labels); 5868 const Register result = this->locs()->out(0).reg();
6000 5869
6001 const Register result = locs()->out(0).reg(); 5870 // TODO(dartbug.com/29908): Use csel here for better branch prediction?
5871 if (true_condition != kInvalidCondition) {
5872 EmitBranchOnCondition(compiler, true_condition, labels);
5873 }
6002 Label done; 5874 Label done;
6003 __ Bind(&is_false); 5875 __ Bind(&is_false);
6004 __ LoadObject(result, Bool::False()); 5876 __ LoadObject(result, Bool::False());
6005 __ b(&done); 5877 __ b(&done);
6006 __ Bind(&is_true); 5878 __ Bind(&is_true);
6007 __ LoadObject(result, Bool::True()); 5879 __ LoadObject(result, Bool::True());
6008 __ Bind(&done); 5880 __ Bind(&done);
6009 } 5881 }
6010 5882
6011 5883
6012 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 5884 void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
6013 BranchInstr* branch) { 5885 BranchInstr* branch) {
6014 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
6015
6016 BranchLabels labels = compiler->CreateBranchLabels(branch); 5886 BranchLabels labels = compiler->CreateBranchLabels(branch);
6017 Condition true_condition = EmitComparisonCode(compiler, labels); 5887 Condition true_condition = EmitComparisonCode(compiler, labels);
6018 EmitBranchOnCondition(compiler, true_condition, labels); 5888 if (true_condition != kInvalidCondition) {
5889 EmitBranchOnCondition(compiler, true_condition, labels);
5890 }
6019 } 5891 }
6020 5892
6021 5893
6022 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone, 5894 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
6023 bool opt) const { 5895 bool opt) const {
6024 return LocationSummary::Make(zone, 1, Location::RequiresRegister(), 5896 return LocationSummary::Make(zone, 1, Location::RequiresRegister(),
6025 LocationSummary::kNoCall); 5897 LocationSummary::kNoCall);
6026 } 5898 }
6027 5899
6028 5900
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
6082 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), 5954 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(),
6083 kGrowRegExpStackRuntimeEntry, 1, locs()); 5955 kGrowRegExpStackRuntimeEntry, 1, locs());
6084 __ Drop(1); 5956 __ Drop(1);
6085 __ Pop(result); 5957 __ Pop(result);
6086 } 5958 }
6087 5959
6088 5960
6089 } // namespace dart 5961 } // namespace dart
6090 5962
6091 #endif // defined TARGET_ARCH_ARM64 5963 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_dbc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698