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

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

Issue 2937933002: Reduce copying, redundancy & repetition for codegen of comparison instructions (Closed)
Patch Set: 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
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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 ASSERT(locs()->out(0).reg() == RDX); 161 ASSERT(locs()->out(0).reg() == RDX);
162 162
163 // Clear upper part of the out register. We are going to use setcc on it 163 // Clear upper part of the out register. We are going to use setcc on it
164 // which is a byte move. 164 // which is a byte move.
165 __ xorq(RDX, RDX); 165 __ xorq(RDX, RDX);
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 != INVALID_CONDITION);
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 RDX on true_condition. 181 // We need to have zero in RDX on true_condition.
179 true_condition = NegateCondition(true_condition); 182 true_condition = NegateCondition(true_condition);
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 BranchLabels labels) { 569 BranchLabels labels) {
567 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) { 570 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) {
568 return EmitInt64ComparisonOp(compiler, *locs(), kind()); 571 return EmitInt64ComparisonOp(compiler, *locs(), kind());
569 } else { 572 } else {
570 ASSERT(operation_cid() == kDoubleCid); 573 ASSERT(operation_cid() == kDoubleCid);
571 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 574 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
572 } 575 }
573 } 576 }
574 577
575 578
576 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 579 template <intptr_t N,
577 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 580 typename ThrowsTrait,
578 581 template <typename Impure, typename Pure> class CSETrait>
582 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitNativeCode(
583 FlowGraphCompiler* compiler) {
579 Label is_true, is_false; 584 Label is_true, is_false;
580 BranchLabels labels = {&is_true, &is_false, &is_false}; 585 BranchLabels labels = {&is_true, &is_false, &is_false};
581 Condition true_condition = EmitComparisonCode(compiler, labels); 586 Condition true_condition = EmitComparisonCode(compiler, labels);
582 EmitBranchOnCondition(compiler, true_condition, labels); 587 if (true_condition != INVALID_CONDITION) {
588 EmitBranchOnCondition(compiler, true_condition, labels);
589 }
583 590
584 Register result = locs()->out(0).reg(); 591 Register result = this->locs()->out(0).reg();
585 Label done; 592 Label done;
586 __ Bind(&is_false); 593 __ Bind(&is_false);
587 __ LoadObject(result, Bool::False()); 594 __ LoadObject(result, Bool::False());
588 __ jmp(&done); 595 __ jmp(&done);
589 __ Bind(&is_true); 596 __ Bind(&is_true);
590 __ LoadObject(result, Bool::True()); 597 __ LoadObject(result, Bool::True());
591 __ Bind(&done); 598 __ Bind(&done);
592 } 599 }
593 600
594 601
595 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 602 template <intptr_t N,
596 BranchInstr* branch) { 603 typename ThrowsTrait,
597 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 604 template <typename Impure, typename Pure> class CSETrait>
598 605 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitBranchCode(
606 FlowGraphCompiler* compiler,
607 BranchInstr* branch) {
599 BranchLabels labels = compiler->CreateBranchLabels(branch); 608 BranchLabels labels = compiler->CreateBranchLabels(branch);
600 Condition true_condition = EmitComparisonCode(compiler, labels); 609 Condition true_condition = EmitComparisonCode(compiler, labels);
601 EmitBranchOnCondition(compiler, true_condition, labels); 610 if (true_condition != INVALID_CONDITION) {
611 EmitBranchOnCondition(compiler, true_condition, labels);
612 }
602 } 613 }
603 614
604 615
616 // Explicit template instantiations.
617 template void TemplateComparison<1, NoThrow, Pure>::EmitNativeCode(
618 FlowGraphCompiler*);
619 template void TemplateComparison<2, NoThrow, Pure>::EmitNativeCode(
620 FlowGraphCompiler*);
621 template void TemplateComparison<1, NoThrow, Pure>::EmitBranchCode(
622 FlowGraphCompiler* compiler,
623 BranchInstr* branch);
624 template void TemplateComparison<2, NoThrow, Pure>::EmitBranchCode(
625 FlowGraphCompiler* compiler,
626 BranchInstr* branch);
627
628
605 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { 629 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const {
606 const intptr_t kNumInputs = 2; 630 const intptr_t kNumInputs = 2;
607 const intptr_t kNumTemps = 0; 631 const intptr_t kNumTemps = 0;
608 LocationSummary* locs = new (zone) 632 LocationSummary* locs = new (zone)
609 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 633 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
610 locs->set_in(0, Location::RequiresRegister()); 634 locs->set_in(0, Location::RequiresRegister());
611 // Only one input can be a constant operand. The case of two constant 635 // Only one input can be a constant operand. The case of two constant
612 // operands should be handled by constant propagation. 636 // operands should be handled by constant propagation.
613 locs->set_in(1, Location::RegisterOrConstant(right())); 637 locs->set_in(1, Location::RegisterOrConstant(right()));
614 return locs; 638 return locs;
615 } 639 }
616 640
617 641
618 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 642 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
619 BranchLabels labels) { 643 BranchLabels labels) {
620 Register left_reg = locs()->in(0).reg(); 644 Register left_reg = locs()->in(0).reg();
621 Location right = locs()->in(1); 645 Location right = locs()->in(1);
622 if (right.IsConstant()) { 646 if (right.IsConstant()) {
623 ASSERT(right.constant().IsSmi()); 647 ASSERT(right.constant().IsSmi());
624 const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw()); 648 const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw());
625 __ TestImmediate(left_reg, Immediate(imm)); 649 __ TestImmediate(left_reg, Immediate(imm));
626 } else { 650 } else {
627 __ testq(left_reg, right.reg()); 651 __ testq(left_reg, right.reg());
628 } 652 }
629 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; 653 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
630 return true_condition; 654 return true_condition;
631 } 655 }
632 656
633 657
634 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
635 // Never emitted outside of the BranchInstr.
636 UNREACHABLE();
637 }
638
639
640 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
641 BranchInstr* branch) {
642 BranchLabels labels = compiler->CreateBranchLabels(branch);
643 Condition true_condition = EmitComparisonCode(compiler, labels);
644 EmitBranchOnCondition(compiler, true_condition, labels);
645 }
646
647
648 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, 658 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
649 bool opt) const { 659 bool opt) const {
650 const intptr_t kNumInputs = 1; 660 const intptr_t kNumInputs = 1;
651 const intptr_t kNumTemps = 1; 661 const intptr_t kNumTemps = 1;
652 LocationSummary* locs = new (zone) 662 LocationSummary* locs = new (zone)
653 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 663 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
654 locs->set_in(0, Location::RequiresRegister()); 664 locs->set_in(0, Location::RequiresRegister());
655 locs->set_temp(0, Location::RequiresRegister()); 665 locs->set_temp(0, Location::RequiresRegister());
656 locs->set_out(0, Location::RequiresRegister()); 666 locs->set_out(0, Location::RequiresRegister());
657 return locs; 667 return locs;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 // If the cid is not in the list, jump to the opposite label from the cids 699 // If the cid is not in the list, jump to the opposite label from the cids
690 // that are in the list. These must be all the same (see asserts in the 700 // that are in the list. These must be all the same (see asserts in the
691 // constructor). 701 // constructor).
692 Label* target = result ? labels.false_label : labels.true_label; 702 Label* target = result ? labels.false_label : labels.true_label;
693 if (target != labels.fall_through) { 703 if (target != labels.fall_through) {
694 __ jmp(target); 704 __ jmp(target);
695 } 705 }
696 } else { 706 } else {
697 __ jmp(deopt); 707 __ jmp(deopt);
698 } 708 }
699 // Dummy result as the last instruction is a jump, any conditional 709 // Dummy result as this method already did the jump, there's no need
700 // branch using the result will therefore be skipped. 710 // for the caller to branch on a condition.
701 return ZERO; 711 return INVALID_CONDITION;
702 } 712 }
703 713
704 714
705 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler,
706 BranchInstr* branch) {
707 BranchLabels labels = compiler->CreateBranchLabels(branch);
708 EmitComparisonCode(compiler, labels);
709 }
710
711
712 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
713 Register result_reg = locs()->out(0).reg();
714 Label is_true, is_false, done;
715 BranchLabels labels = {&is_true, &is_false, &is_false};
716 EmitComparisonCode(compiler, labels);
717 __ Bind(&is_false);
718 __ LoadObject(result_reg, Bool::False());
719 __ jmp(&done, Assembler::kNearJump);
720 __ Bind(&is_true);
721 __ LoadObject(result_reg, Bool::True());
722 __ Bind(&done);
723 }
724
725
726 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, 715 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
727 bool opt) const { 716 bool opt) const {
728 const intptr_t kNumInputs = 2; 717 const intptr_t kNumInputs = 2;
729 const intptr_t kNumTemps = 0; 718 const intptr_t kNumTemps = 0;
730 if (operation_cid() == kDoubleCid) { 719 if (operation_cid() == kDoubleCid) {
731 LocationSummary* summary = new (zone) 720 LocationSummary* summary = new (zone)
732 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 721 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
733 summary->set_in(0, Location::RequiresFpuRegister()); 722 summary->set_in(0, Location::RequiresFpuRegister());
734 summary->set_in(1, Location::RequiresFpuRegister()); 723 summary->set_in(1, Location::RequiresFpuRegister());
735 summary->set_out(0, Location::RequiresRegister()); 724 summary->set_out(0, Location::RequiresRegister());
(...skipping 24 matching lines...) Expand all
760 BranchLabels labels) { 749 BranchLabels labels) {
761 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) { 750 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) {
762 return EmitInt64ComparisonOp(compiler, *locs(), kind()); 751 return EmitInt64ComparisonOp(compiler, *locs(), kind());
763 } else { 752 } else {
764 ASSERT(operation_cid() == kDoubleCid); 753 ASSERT(operation_cid() == kDoubleCid);
765 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 754 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
766 } 755 }
767 } 756 }
768 757
769 758
770 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
771 Label is_true, is_false;
772 BranchLabels labels = {&is_true, &is_false, &is_false};
773 Condition true_condition = EmitComparisonCode(compiler, labels);
774 EmitBranchOnCondition(compiler, true_condition, labels);
775
776 Register result = locs()->out(0).reg();
777 Label done;
778 __ Bind(&is_false);
779 __ LoadObject(result, Bool::False());
780 __ jmp(&done);
781 __ Bind(&is_true);
782 __ LoadObject(result, Bool::True());
783 __ Bind(&done);
784 }
785
786
787 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
788 BranchInstr* branch) {
789 BranchLabels labels = compiler->CreateBranchLabels(branch);
790 Condition true_condition = EmitComparisonCode(compiler, labels);
791 EmitBranchOnCondition(compiler, true_condition, labels);
792 }
793
794
795 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, 759 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone,
796 bool opt) const { 760 bool opt) const {
797 return MakeCallSummary(zone); 761 return MakeCallSummary(zone);
798 } 762 }
799 763
800 764
801 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 765 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
802 SetupNative(); 766 SetupNative();
803 Register result = locs()->out(0).reg(); 767 Register result = locs()->out(0).reg();
804 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); 768 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
(...skipping 2297 matching lines...) Expand 10 before | Expand all | Expand 10 after
3102 3066
3103 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, 3067 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3104 BranchInstr* branch) { 3068 BranchInstr* branch) {
3105 BranchLabels labels = compiler->CreateBranchLabels(branch); 3069 BranchLabels labels = compiler->CreateBranchLabels(branch);
3106 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( 3070 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
3107 this, compiler->CurrentTryIndex(), labels, 3071 this, compiler->CurrentTryIndex(), labels,
3108 /* merged = */ true); 3072 /* merged = */ true);
3109 compiler->AddSlowPathCode(slow_path); 3073 compiler->AddSlowPathCode(slow_path);
3110 EMIT_SMI_CHECK; 3074 EMIT_SMI_CHECK;
3111 Condition true_condition = EmitComparisonCode(compiler, labels); 3075 Condition true_condition = EmitComparisonCode(compiler, labels);
3076 ASSERT(true_condition != INVALID_CONDITION);
3112 EmitBranchOnCondition(compiler, true_condition, labels); 3077 EmitBranchOnCondition(compiler, true_condition, labels);
3113 __ Bind(slow_path->exit_label()); 3078 __ Bind(slow_path->exit_label());
3114 } 3079 }
3115 3080
3116 3081
3117 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3082 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3118 Label true_label, false_label, done; 3083 Label true_label, false_label, done;
3119 BranchLabels labels = {&true_label, &false_label, &false_label}; 3084 BranchLabels labels = {&true_label, &false_label, &false_label};
3120 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( 3085 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
3121 this, compiler->CurrentTryIndex(), labels, 3086 this, compiler->CurrentTryIndex(), labels,
3122 /* merged = */ false); 3087 /* merged = */ false);
3123 compiler->AddSlowPathCode(slow_path); 3088 compiler->AddSlowPathCode(slow_path);
3124 EMIT_SMI_CHECK; 3089 EMIT_SMI_CHECK;
3125 Condition true_condition = EmitComparisonCode(compiler, labels); 3090 Condition true_condition = EmitComparisonCode(compiler, labels);
3091 ASSERT(true_condition != INVALID_CONDITION);
3126 EmitBranchOnCondition(compiler, true_condition, labels); 3092 EmitBranchOnCondition(compiler, true_condition, labels);
3127 Register result = locs()->out(0).reg(); 3093 Register result = locs()->out(0).reg();
3128 __ Bind(&false_label); 3094 __ Bind(&false_label);
3129 __ LoadObject(result, Bool::False()); 3095 __ LoadObject(result, Bool::False());
3130 __ jmp(&done); 3096 __ jmp(&done);
3131 __ Bind(&true_label); 3097 __ Bind(&true_label);
3132 __ LoadObject(result, Bool::True()); 3098 __ LoadObject(result, Bool::True());
3133 __ Bind(&done); 3099 __ Bind(&done);
3134 __ Bind(slow_path->exit_label()); 3100 __ Bind(slow_path->exit_label());
3135 } 3101 }
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
3944 __ AddImmediate(RSP, Immediate(kDoubleSize)); 3910 __ AddImmediate(RSP, Immediate(kDoubleSize));
3945 // Mask off the sign. 3911 // Mask off the sign.
3946 __ AndImmediate(temp, Immediate(0x7FFFFFFFFFFFFFFFLL)); 3912 __ AndImmediate(temp, Immediate(0x7FFFFFFFFFFFFFFFLL));
3947 // Compare with +infinity. 3913 // Compare with +infinity.
3948 __ CompareImmediate(temp, Immediate(0x7FF0000000000000LL)); 3914 __ CompareImmediate(temp, Immediate(0x7FF0000000000000LL));
3949 return is_negated ? NOT_EQUAL : EQUAL; 3915 return is_negated ? NOT_EQUAL : EQUAL;
3950 } 3916 }
3951 } 3917 }
3952 3918
3953 3919
3954 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3955 BranchInstr* branch) {
3956 ASSERT(compiler->is_optimizing());
3957 BranchLabels labels = compiler->CreateBranchLabels(branch);
3958 Condition true_condition = EmitComparisonCode(compiler, labels);
3959 EmitBranchOnCondition(compiler, true_condition, labels);
3960 }
3961
3962
3963 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3964 Label is_true, is_false;
3965 BranchLabels labels = {&is_true, &is_false, &is_false};
3966 Condition true_condition = EmitComparisonCode(compiler, labels);
3967 EmitBranchOnCondition(compiler, true_condition, labels);
3968
3969 Register result = locs()->out(0).reg();
3970 Label done;
3971 __ Bind(&is_false);
3972 __ LoadObject(result, Bool::False());
3973 __ jmp(&done);
3974 __ Bind(&is_true);
3975 __ LoadObject(result, Bool::True());
3976 __ Bind(&done);
3977 }
3978
3979
3980 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, 3920 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone,
3981 bool opt) const { 3921 bool opt) const {
3982 const intptr_t kNumInputs = 2; 3922 const intptr_t kNumInputs = 2;
3983 const intptr_t kNumTemps = 0; 3923 const intptr_t kNumTemps = 0;
3984 LocationSummary* summary = new (zone) 3924 LocationSummary* summary = new (zone)
3985 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3925 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3986 summary->set_in(0, Location::RequiresFpuRegister()); 3926 summary->set_in(0, Location::RequiresFpuRegister());
3987 summary->set_in(1, Location::RequiresFpuRegister()); 3927 summary->set_in(1, Location::RequiresFpuRegister());
3988 summary->set_out(0, Location::SameAsFirstInput()); 3928 summary->set_out(0, Location::SameAsFirstInput());
3989 return summary; 3929 return summary;
(...skipping 2641 matching lines...) Expand 10 before | Expand all | Expand 10 after
6631 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); 6571 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
6632 } 6572 }
6633 if (kind() != Token::kEQ_STRICT) { 6573 if (kind() != Token::kEQ_STRICT) {
6634 ASSERT(kind() == Token::kNE_STRICT); 6574 ASSERT(kind() == Token::kNE_STRICT);
6635 true_condition = NegateCondition(true_condition); 6575 true_condition = NegateCondition(true_condition);
6636 } 6576 }
6637 return true_condition; 6577 return true_condition;
6638 } 6578 }
6639 6579
6640 6580
6641 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6642 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
6643
6644 Label is_true, is_false;
6645 BranchLabels labels = {&is_true, &is_false, &is_false};
6646
6647 Condition true_condition = EmitComparisonCode(compiler, labels);
6648 EmitBranchOnCondition(compiler, true_condition, labels);
6649
6650 Register result = locs()->out(0).reg();
6651 Label done;
6652 __ Bind(&is_false);
6653 __ LoadObject(result, Bool::False());
6654 __ jmp(&done);
6655 __ Bind(&is_true);
6656 __ LoadObject(result, Bool::True());
6657 __ Bind(&done);
6658 }
6659
6660
6661 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
6662 BranchInstr* branch) {
6663 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
6664
6665 BranchLabels labels = compiler->CreateBranchLabels(branch);
6666 Condition true_condition = EmitComparisonCode(compiler, labels);
6667 EmitBranchOnCondition(compiler, true_condition, labels);
6668 }
6669
6670
6671 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone, 6581 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
6672 bool opt) const { 6582 bool opt) const {
6673 const intptr_t kNumInputs = 1; 6583 const intptr_t kNumInputs = 1;
6674 const intptr_t kNumTemps = 0; 6584 const intptr_t kNumTemps = 0;
6675 LocationSummary* summary = new (zone) 6585 LocationSummary* summary = new (zone)
6676 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); 6586 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
6677 summary->set_in(0, Location::RegisterLocation(RAX)); // Function. 6587 summary->set_in(0, Location::RegisterLocation(RAX)); // Function.
6678 summary->set_out(0, Location::RegisterLocation(RAX)); 6588 summary->set_out(0, Location::RegisterLocation(RAX));
6679 return summary; 6589 return summary;
6680 } 6590 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
6781 __ Drop(1); 6691 __ Drop(1);
6782 __ popq(result); 6692 __ popq(result);
6783 } 6693 }
6784 6694
6785 6695
6786 } // namespace dart 6696 } // namespace dart
6787 6697
6788 #undef __ 6698 #undef __
6789 6699
6790 #endif // defined TARGET_ARCH_X64 6700 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/intermediate_language_dbc.cc ('K') | « runtime/vm/intermediate_language_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698