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

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

Issue 2947633002: VM-codegen: Clean up the way we emit code for comparison instructions. (Closed)
Patch Set: Simplify DBC ComparisonInstr::EmitNativeCode 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.h ('k') | runtime/vm/intermediate_language_arm64.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 1
2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
3 // for details. All rights reserved. Use of this source code is governed by a 3 // for details. All rights reserved. Use of this source code is governed by a
4 // BSD-style license that can be found in the LICENSE file. 4 // BSD-style license that can be found in the LICENSE file.
5 5
6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
7 #if defined(TARGET_ARCH_ARM) 7 #if defined(TARGET_ARCH_ARM)
8 8
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 10
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 const Register result = locs()->out(0).reg(); 163 const Register result = locs()->out(0).reg();
164 164
165 Location left = locs()->in(0); 165 Location left = locs()->in(0);
166 Location right = locs()->in(1); 166 Location right = locs()->in(1);
167 ASSERT(!left.IsConstant() || !right.IsConstant()); 167 ASSERT(!left.IsConstant() || !right.IsConstant());
168 168
169 // Clear out register. 169 // Clear out register.
170 __ eor(result, result, Operand(result)); 170 __ eor(result, result, Operand(result));
171 171
172 // Emit comparison code. This must not overwrite the result register. 172 // Emit comparison code. This must not overwrite the result register.
173 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
174 // the labels or returning an invalid condition.
173 BranchLabels labels = {NULL, NULL, NULL}; 175 BranchLabels labels = {NULL, NULL, NULL};
174 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); 176 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
177 ASSERT(true_condition != kInvalidCondition);
175 178
176 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); 179 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
177 180
178 intptr_t true_value = if_true_; 181 intptr_t true_value = if_true_;
179 intptr_t false_value = if_false_; 182 intptr_t false_value = if_false_;
180 183
181 if (is_power_of_two_kind) { 184 if (is_power_of_two_kind) {
182 if (true_value == 0) { 185 if (true_value == 0) {
183 // We need to have zero in result on true_condition. 186 // We need to have zero in result on true_condition.
184 true_condition = NegateCondition(true_condition); 187 true_condition = NegateCondition(true_condition);
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 return GE; 663 return GE;
661 default: 664 default:
662 UNREACHABLE(); 665 UNREACHABLE();
663 return VS; 666 return VS;
664 } 667 }
665 } 668 }
666 669
667 670
668 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 671 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
669 LocationSummary* locs, 672 LocationSummary* locs,
673 BranchLabels labels,
670 Token::Kind kind) { 674 Token::Kind kind) {
671 const QRegister left = locs->in(0).fpu_reg(); 675 const QRegister left = locs->in(0).fpu_reg();
672 const QRegister right = locs->in(1).fpu_reg(); 676 const QRegister right = locs->in(1).fpu_reg();
673 const DRegister dleft = EvenDRegisterOf(left); 677 const DRegister dleft = EvenDRegisterOf(left);
674 const DRegister dright = EvenDRegisterOf(right); 678 const DRegister dright = EvenDRegisterOf(right);
675 __ vcmpd(dleft, dright); 679 __ vcmpd(dleft, dright);
676 __ vmstat(); 680 __ vmstat();
677 Condition true_condition = TokenKindToDoubleCondition(kind); 681 Condition true_condition = TokenKindToDoubleCondition(kind);
682 if (true_condition != NE) {
683 // Special case for NaN comparison. Result is always false unless
684 // relational operator is !=.
685 __ b(labels.false_label, VS);
686 }
678 return true_condition; 687 return true_condition;
679 } 688 }
680 689
681 690
682 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 691 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
683 BranchLabels labels) { 692 BranchLabels labels) {
684 if (operation_cid() == kSmiCid) { 693 if (operation_cid() == kSmiCid) {
685 return EmitSmiComparisonOp(compiler, locs(), kind()); 694 return EmitSmiComparisonOp(compiler, locs(), kind());
686 } else if (operation_cid() == kMintCid) { 695 } else if (operation_cid() == kMintCid) {
687 return EmitUnboxedMintEqualityOp(compiler, locs(), kind()); 696 return EmitUnboxedMintEqualityOp(compiler, locs(), kind());
688 } else { 697 } else {
689 ASSERT(operation_cid() == kDoubleCid); 698 ASSERT(operation_cid() == kDoubleCid);
690 return EmitDoubleComparisonOp(compiler, locs(), kind()); 699 return EmitDoubleComparisonOp(compiler, locs(), labels, kind());
691 } 700 }
692 } 701 }
693 702
694 703
695 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
696 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
697
698 // The ARM code does not use true- and false-labels here.
699 BranchLabels labels = {NULL, NULL, NULL};
700 Condition true_condition = EmitComparisonCode(compiler, labels);
701
702 const Register result = locs()->out(0).reg();
703 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) {
704 __ LoadObject(result, Bool::True(), true_condition);
705 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
706 } else {
707 ASSERT(operation_cid() == kDoubleCid);
708 Label done;
709 __ LoadObject(result, Bool::False());
710 if (true_condition != NE) {
711 __ b(&done, VS); // x == NaN -> false, x != NaN -> true.
712 }
713 __ LoadObject(result, Bool::True(), true_condition);
714 __ Bind(&done);
715 }
716 }
717
718
719 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
720 BranchInstr* branch) {
721 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
722
723 BranchLabels labels = compiler->CreateBranchLabels(branch);
724 Condition true_condition = EmitComparisonCode(compiler, labels);
725
726 if (operation_cid() == kDoubleCid) {
727 Label* nan_result =
728 (true_condition == NE) ? labels.true_label : labels.false_label;
729 __ b(nan_result, VS);
730 }
731 EmitBranchOnCondition(compiler, true_condition, labels);
732 }
733
734
735 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { 704 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const {
736 const intptr_t kNumInputs = 2; 705 const intptr_t kNumInputs = 2;
737 const intptr_t kNumTemps = 0; 706 const intptr_t kNumTemps = 0;
738 LocationSummary* locs = new (zone) 707 LocationSummary* locs = new (zone)
739 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 708 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
740 locs->set_in(0, Location::RequiresRegister()); 709 locs->set_in(0, Location::RequiresRegister());
741 // Only one input can be a constant operand. The case of two constant 710 // Only one input can be a constant operand. The case of two constant
742 // operands should be handled by constant propagation. 711 // operands should be handled by constant propagation.
743 locs->set_in(1, Location::RegisterOrConstant(right())); 712 locs->set_in(1, Location::RegisterOrConstant(right()));
744 return locs; 713 return locs;
745 } 714 }
746 715
747 716
748 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 717 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
749 BranchLabels labels) { 718 BranchLabels labels) {
750 const Register left = locs()->in(0).reg(); 719 const Register left = locs()->in(0).reg();
751 Location right = locs()->in(1); 720 Location right = locs()->in(1);
752 if (right.IsConstant()) { 721 if (right.IsConstant()) {
753 ASSERT(right.constant().IsSmi()); 722 ASSERT(right.constant().IsSmi());
754 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw()); 723 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw());
755 __ TestImmediate(left, imm); 724 __ TestImmediate(left, imm);
756 } else { 725 } else {
757 __ tst(left, Operand(right.reg())); 726 __ tst(left, Operand(right.reg()));
758 } 727 }
759 Condition true_condition = (kind() == Token::kNE) ? NE : EQ; 728 Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
760 return true_condition; 729 return true_condition;
761 } 730 }
762 731
763 732
764 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
765 // Never emitted outside of the BranchInstr.
766 UNREACHABLE();
767 }
768
769
770 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
771 BranchInstr* branch) {
772 BranchLabels labels = compiler->CreateBranchLabels(branch);
773 Condition true_condition = EmitComparisonCode(compiler, labels);
774 EmitBranchOnCondition(compiler, true_condition, labels);
775 }
776
777
778 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, 733 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
779 bool opt) const { 734 bool opt) const {
780 const intptr_t kNumInputs = 1; 735 const intptr_t kNumInputs = 1;
781 const intptr_t kNumTemps = 1; 736 const intptr_t kNumTemps = 1;
782 LocationSummary* locs = new (zone) 737 LocationSummary* locs = new (zone)
783 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 738 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
784 locs->set_in(0, Location::RequiresRegister()); 739 locs->set_in(0, Location::RequiresRegister());
785 locs->set_temp(0, Location::RequiresRegister()); 740 locs->set_temp(0, Location::RequiresRegister());
786 locs->set_out(0, Location::RequiresRegister()); 741 locs->set_out(0, Location::RequiresRegister());
787 return locs; 742 return locs;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 // If the cid is not in the list, jump to the opposite label from the cids 775 // If the cid is not in the list, jump to the opposite label from the cids
821 // that are in the list. These must be all the same (see asserts in the 776 // that are in the list. These must be all the same (see asserts in the
822 // constructor). 777 // constructor).
823 Label* target = result ? labels.false_label : labels.true_label; 778 Label* target = result ? labels.false_label : labels.true_label;
824 if (target != labels.fall_through) { 779 if (target != labels.fall_through) {
825 __ b(target); 780 __ b(target);
826 } 781 }
827 } else { 782 } else {
828 __ b(deopt); 783 __ b(deopt);
829 } 784 }
830 // Dummy result as the last instruction is a jump, any conditional 785 // Dummy result as this method already did the jump, there's no need
831 // branch using the result will therefore be skipped. 786 // for the caller to branch on a condition.
832 return EQ; 787 return kInvalidCondition;
833 } 788 }
834 789
835 790
836 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler,
837 BranchInstr* branch) {
838 BranchLabels labels = compiler->CreateBranchLabels(branch);
839 EmitComparisonCode(compiler, labels);
840 }
841
842
843 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
844 const Register result_reg = locs()->out(0).reg();
845 Label is_true, is_false, done;
846 BranchLabels labels = {&is_true, &is_false, &is_false};
847 EmitComparisonCode(compiler, labels);
848 __ Bind(&is_false);
849 __ LoadObject(result_reg, Bool::False());
850 __ b(&done);
851 __ Bind(&is_true);
852 __ LoadObject(result_reg, Bool::True());
853 __ Bind(&done);
854 }
855
856
857 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, 791 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
858 bool opt) const { 792 bool opt) const {
859 const intptr_t kNumInputs = 2; 793 const intptr_t kNumInputs = 2;
860 const intptr_t kNumTemps = 0; 794 const intptr_t kNumTemps = 0;
861 if (operation_cid() == kMintCid) { 795 if (operation_cid() == kMintCid) {
862 const intptr_t kNumTemps = 0; 796 const intptr_t kNumTemps = 0;
863 LocationSummary* locs = new (zone) 797 LocationSummary* locs = new (zone)
864 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 798 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
865 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 799 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
866 Location::RequiresRegister())); 800 Location::RequiresRegister()));
(...skipping 25 matching lines...) Expand all
892 826
893 827
894 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 828 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
895 BranchLabels labels) { 829 BranchLabels labels) {
896 if (operation_cid() == kSmiCid) { 830 if (operation_cid() == kSmiCid) {
897 return EmitSmiComparisonOp(compiler, locs(), kind()); 831 return EmitSmiComparisonOp(compiler, locs(), kind());
898 } else if (operation_cid() == kMintCid) { 832 } else if (operation_cid() == kMintCid) {
899 return EmitUnboxedMintComparisonOp(compiler, locs(), kind(), labels); 833 return EmitUnboxedMintComparisonOp(compiler, locs(), kind(), labels);
900 } else { 834 } else {
901 ASSERT(operation_cid() == kDoubleCid); 835 ASSERT(operation_cid() == kDoubleCid);
902 return EmitDoubleComparisonOp(compiler, locs(), kind()); 836 return EmitDoubleComparisonOp(compiler, locs(), labels, kind());
903 } 837 }
904 } 838 }
905 839
906
907 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
908 Label is_true, is_false;
909 BranchLabels labels = {&is_true, &is_false, &is_false};
910 Condition true_condition = EmitComparisonCode(compiler, labels);
911
912 const Register result = locs()->out(0).reg();
913 if (operation_cid() == kSmiCid) {
914 __ LoadObject(result, Bool::True(), true_condition);
915 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
916 } else if (operation_cid() == kMintCid) {
917 EmitBranchOnCondition(compiler, true_condition, labels);
918 Label done;
919 __ Bind(&is_false);
920 __ LoadObject(result, Bool::False());
921 __ b(&done);
922 __ Bind(&is_true);
923 __ LoadObject(result, Bool::True());
924 __ Bind(&done);
925 } else {
926 ASSERT(operation_cid() == kDoubleCid);
927 Label done;
928 __ LoadObject(result, Bool::False());
929 if (true_condition != NE) {
930 __ b(&done, VS); // x == NaN -> false, x != NaN -> true.
931 }
932 __ LoadObject(result, Bool::True(), true_condition);
933 __ Bind(&done);
934 }
935 }
936
937
938 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
939 BranchInstr* branch) {
940 BranchLabels labels = compiler->CreateBranchLabels(branch);
941 Condition true_condition = EmitComparisonCode(compiler, labels);
942
943 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) {
944 EmitBranchOnCondition(compiler, true_condition, labels);
945 } else if (operation_cid() == kDoubleCid) {
946 Label* nan_result =
947 (true_condition == NE) ? labels.true_label : labels.false_label;
948 __ b(nan_result, VS);
949 EmitBranchOnCondition(compiler, true_condition, labels);
950 }
951 }
952
953 840
954 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, 841 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone,
955 bool opt) const { 842 bool opt) const {
956 return MakeCallSummary(zone); 843 return MakeCallSummary(zone);
957 } 844 }
958 845
959 846
960 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 847 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
961 SetupNative(); 848 SetupNative();
962 const Register result = locs()->out(0).reg(); 849 const Register result = locs()->out(0).reg();
(...skipping 2415 matching lines...) Expand 10 before | Expand all | Expand 10 after
3378 3265
3379 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, 3266 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3380 BranchInstr* branch) { 3267 BranchInstr* branch) {
3381 BranchLabels labels = compiler->CreateBranchLabels(branch); 3268 BranchLabels labels = compiler->CreateBranchLabels(branch);
3382 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( 3269 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
3383 this, compiler->CurrentTryIndex(), labels, 3270 this, compiler->CurrentTryIndex(), labels,
3384 /* merged = */ true); 3271 /* merged = */ true);
3385 compiler->AddSlowPathCode(slow_path); 3272 compiler->AddSlowPathCode(slow_path);
3386 EMIT_SMI_CHECK; 3273 EMIT_SMI_CHECK;
3387 Condition true_condition = EmitComparisonCode(compiler, labels); 3274 Condition true_condition = EmitComparisonCode(compiler, labels);
3275 ASSERT(true_condition != kInvalidCondition);
3388 EmitBranchOnCondition(compiler, true_condition, labels); 3276 EmitBranchOnCondition(compiler, true_condition, labels);
3389 __ Bind(slow_path->exit_label()); 3277 __ Bind(slow_path->exit_label());
3390 } 3278 }
3391 3279
3392 3280
3393 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3281 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3394 BranchLabels labels = {NULL, NULL, NULL}; 3282 BranchLabels labels = {NULL, NULL, NULL};
3395 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( 3283 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
3396 this, compiler->CurrentTryIndex(), labels, 3284 this, compiler->CurrentTryIndex(), labels,
3397 /* merged = */ false); 3285 /* merged = */ false);
3398 compiler->AddSlowPathCode(slow_path); 3286 compiler->AddSlowPathCode(slow_path);
3399 EMIT_SMI_CHECK; 3287 EMIT_SMI_CHECK;
3400 Condition true_condition = EmitComparisonCode(compiler, labels); 3288 Condition true_condition = EmitComparisonCode(compiler, labels);
3289 ASSERT(true_condition != kInvalidCondition);
3401 Register result = locs()->out(0).reg(); 3290 Register result = locs()->out(0).reg();
3402 __ LoadObject(result, Bool::True(), true_condition); 3291 __ LoadObject(result, Bool::True(), true_condition);
3403 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); 3292 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
3404 __ Bind(slow_path->exit_label()); 3293 __ Bind(slow_path->exit_label());
3405 } 3294 }
3406 #undef EMIT_SMI_CHECK 3295 #undef EMIT_SMI_CHECK
3407 3296
3408 3297
3409 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, 3298 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone,
3410 bool opt) const { 3299 bool opt) const {
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after
4354 __ b(is_negated ? labels.true_label : labels.false_label, NE); 4243 __ b(is_negated ? labels.true_label : labels.false_label, NE);
4355 4244
4356 // Mask off the sign bit. 4245 // Mask off the sign bit.
4357 __ AndImmediate(temp, temp, 0x7FFFFFFF); 4246 __ AndImmediate(temp, temp, 0x7FFFFFFF);
4358 // Compare with +infinity. 4247 // Compare with +infinity.
4359 __ CompareImmediate(temp, 0x7FF00000); 4248 __ CompareImmediate(temp, 0x7FF00000);
4360 return is_negated ? NE : EQ; 4249 return is_negated ? NE : EQ;
4361 } 4250 }
4362 } 4251 }
4363 4252
4364 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
4365 BranchInstr* branch) {
4366 ASSERT(compiler->is_optimizing());
4367 BranchLabels labels = compiler->CreateBranchLabels(branch);
4368 Condition true_condition = EmitComparisonCode(compiler, labels);
4369 EmitBranchOnCondition(compiler, true_condition, labels);
4370 }
4371
4372
4373 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4374 ASSERT(compiler->is_optimizing());
4375 Label is_true, is_false;
4376 BranchLabels labels = {&is_true, &is_false, &is_false};
4377 Condition true_condition = EmitComparisonCode(compiler, labels);
4378 const Register result = locs()->out(0).reg();
4379 if (op_kind() == MethodRecognizer::kDouble_getIsNaN) {
4380 __ LoadObject(result, Bool::True(), true_condition);
4381 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
4382 } else {
4383 ASSERT(op_kind() == MethodRecognizer::kDouble_getIsInfinite);
4384 EmitBranchOnCondition(compiler, true_condition, labels);
4385 Label done;
4386 __ Bind(&is_false);
4387 __ LoadObject(result, Bool::False());
4388 __ b(&done);
4389 __ Bind(&is_true);
4390 __ LoadObject(result, Bool::True());
4391 __ Bind(&done);
4392 }
4393 }
4394
4395
4396 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, 4253 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone,
4397 bool opt) const { 4254 bool opt) const {
4398 const intptr_t kNumInputs = 2; 4255 const intptr_t kNumInputs = 2;
4399 const intptr_t kNumTemps = 0; 4256 const intptr_t kNumTemps = 0;
4400 LocationSummary* summary = new (zone) 4257 LocationSummary* summary = new (zone)
4401 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4258 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4402 summary->set_in(0, Location::RequiresFpuRegister()); 4259 summary->set_in(0, Location::RequiresFpuRegister());
4403 summary->set_in(1, Location::RequiresFpuRegister()); 4260 summary->set_in(1, Location::RequiresFpuRegister());
4404 summary->set_out(0, Location::RequiresFpuRegister()); 4261 summary->set_out(0, Location::RequiresFpuRegister());
4405 return summary; 4262 return summary;
(...skipping 2761 matching lines...) Expand 10 before | Expand all | Expand 10 after
7167 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); 7024 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
7168 } 7025 }
7169 if (kind() != Token::kEQ_STRICT) { 7026 if (kind() != Token::kEQ_STRICT) {
7170 ASSERT(kind() == Token::kNE_STRICT); 7027 ASSERT(kind() == Token::kNE_STRICT);
7171 true_condition = NegateCondition(true_condition); 7028 true_condition = NegateCondition(true_condition);
7172 } 7029 }
7173 return true_condition; 7030 return true_condition;
7174 } 7031 }
7175 7032
7176 7033
7177 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 7034 void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
7178 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 7035 // The ARM code may not use true- and false-labels here.
7179 7036 Label is_true, is_false, done;
7180 // The ARM code does not use true- and false-labels here. 7037 BranchLabels labels = {&is_true, &is_false, &is_false};
7181 BranchLabels labels = {NULL, NULL, NULL};
7182 Condition true_condition = EmitComparisonCode(compiler, labels); 7038 Condition true_condition = EmitComparisonCode(compiler, labels);
7183 7039
7184 const Register result = locs()->out(0).reg(); 7040 const Register result = this->locs()->out(0).reg();
7185 __ LoadObject(result, Bool::True(), true_condition); 7041 if (is_false.IsLinked() || is_true.IsLinked()) {
7186 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); 7042 if (true_condition != kInvalidCondition) {
7043 EmitBranchOnCondition(compiler, true_condition, labels);
7044 }
7045 __ Bind(&is_false);
7046 __ LoadObject(result, Bool::False());
7047 __ b(&done);
7048 __ Bind(&is_true);
7049 __ LoadObject(result, Bool::True());
7050 __ Bind(&done);
7051 } else {
7052 // If EmitComparisonCode did not use the labels and just returned
7053 // a condition we can avoid the branch and use conditional loads.
7054 ASSERT(true_condition != kInvalidCondition);
7055 __ LoadObject(result, Bool::True(), true_condition);
7056 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
7057 }
7187 } 7058 }
7188 7059
7189 7060
7190 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 7061 void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
7191 BranchInstr* branch) { 7062 BranchInstr* branch) {
7192 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
7193
7194 BranchLabels labels = compiler->CreateBranchLabels(branch); 7063 BranchLabels labels = compiler->CreateBranchLabels(branch);
7195 Condition true_condition = EmitComparisonCode(compiler, labels); 7064 Condition true_condition = EmitComparisonCode(compiler, labels);
7196 EmitBranchOnCondition(compiler, true_condition, labels); 7065 if (true_condition != kInvalidCondition) {
7066 EmitBranchOnCondition(compiler, true_condition, labels);
7067 }
7197 } 7068 }
7198 7069
7199 7070
7200 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone, 7071 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
7201 bool opt) const { 7072 bool opt) const {
7202 return LocationSummary::Make(zone, 1, Location::RequiresRegister(), 7073 return LocationSummary::Make(zone, 1, Location::RequiresRegister(),
7203 LocationSummary::kNoCall); 7074 LocationSummary::kNoCall);
7204 } 7075 }
7205 7076
7206 7077
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
7259 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), 7130 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(),
7260 kGrowRegExpStackRuntimeEntry, 1, locs()); 7131 kGrowRegExpStackRuntimeEntry, 1, locs());
7261 __ Drop(1); 7132 __ Drop(1);
7262 __ Pop(result); 7133 __ Pop(result);
7263 } 7134 }
7264 7135
7265 7136
7266 } // namespace dart 7137 } // namespace dart
7267 7138
7268 #endif // defined TARGET_ARCH_ARM 7139 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698