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_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |