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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); | 593 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); |
594 } else if (operation_cid() == kMintCid) { | 594 } else if (operation_cid() == kMintCid) { |
595 return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels); | 595 return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels); |
596 } else { | 596 } else { |
597 ASSERT(operation_cid() == kDoubleCid); | 597 ASSERT(operation_cid() == kDoubleCid); |
598 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); | 598 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); |
599 } | 599 } |
600 } | 600 } |
601 | 601 |
602 | 602 |
603 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 603 template <intptr_t N, |
604 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 604 typename ThrowsTrait, |
605 | 605 template <typename Impure, typename Pure> class CSETrait> |
| 606 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitNativeCode( |
| 607 FlowGraphCompiler* compiler) { |
606 Label is_true, is_false; | 608 Label is_true, is_false; |
607 BranchLabels labels = {&is_true, &is_false, &is_false}; | 609 BranchLabels labels = {&is_true, &is_false, &is_false}; |
608 Condition true_condition = EmitComparisonCode(compiler, labels); | 610 Condition true_condition = EmitComparisonCode(compiler, labels); |
609 EmitBranchOnCondition(compiler, true_condition, labels); | 611 if (true_condition != INVALID_CONDITION) { |
| 612 EmitBranchOnCondition(compiler, true_condition, labels); |
| 613 } |
610 | 614 |
611 Register result = locs()->out(0).reg(); | 615 Register result = this->locs()->out(0).reg(); |
612 Label done; | 616 Label done; |
613 __ Bind(&is_false); | 617 __ Bind(&is_false); |
614 __ LoadObject(result, Bool::False()); | 618 __ LoadObject(result, Bool::False()); |
615 __ jmp(&done, Assembler::kNearJump); | 619 __ jmp(&done, Assembler::kNearJump); |
616 __ Bind(&is_true); | 620 __ Bind(&is_true); |
617 __ LoadObject(result, Bool::True()); | 621 __ LoadObject(result, Bool::True()); |
618 __ Bind(&done); | 622 __ Bind(&done); |
619 } | 623 } |
620 | 624 |
621 | 625 |
622 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 626 // IA32 compiler needs this to link. |
623 BranchInstr* branch) { | 627 template <> |
624 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 628 void TemplateComparison<2, Throws, NoCSE>::EmitNativeCode( |
| 629 FlowGraphCompiler* compiler) { |
| 630 UNREACHABLE(); |
| 631 } |
625 | 632 |
| 633 |
| 634 template <intptr_t N, |
| 635 typename ThrowsTrait, |
| 636 template <typename Impure, typename Pure> class CSETrait> |
| 637 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitBranchCode( |
| 638 FlowGraphCompiler* compiler, |
| 639 BranchInstr* branch) { |
626 BranchLabels labels = compiler->CreateBranchLabels(branch); | 640 BranchLabels labels = compiler->CreateBranchLabels(branch); |
627 Condition true_condition = EmitComparisonCode(compiler, labels); | 641 Condition true_condition = EmitComparisonCode(compiler, labels); |
628 EmitBranchOnCondition(compiler, true_condition, labels); | 642 if (true_condition != INVALID_CONDITION) { |
| 643 EmitBranchOnCondition(compiler, true_condition, labels); |
| 644 } |
629 } | 645 } |
630 | 646 |
631 | 647 |
| 648 // IA32 compiler needs this to link. |
| 649 template <> |
| 650 void TemplateComparison<2, Throws, NoCSE>::EmitBranchCode( |
| 651 FlowGraphCompiler* compiler, |
| 652 BranchInstr* branch) { |
| 653 UNREACHABLE(); |
| 654 } |
| 655 |
| 656 |
| 657 // Explicit template instantiations. |
| 658 template void TemplateComparison<1, NoThrow, Pure>::EmitNativeCode( |
| 659 FlowGraphCompiler*); |
| 660 template void TemplateComparison<2, NoThrow, Pure>::EmitNativeCode( |
| 661 FlowGraphCompiler*); |
| 662 template void TemplateComparison<1, NoThrow, Pure>::EmitBranchCode( |
| 663 FlowGraphCompiler* compiler, |
| 664 BranchInstr* branch); |
| 665 template void TemplateComparison<2, NoThrow, Pure>::EmitBranchCode( |
| 666 FlowGraphCompiler* compiler, |
| 667 BranchInstr* branch); |
| 668 |
| 669 |
632 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { | 670 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { |
633 const intptr_t kNumInputs = 2; | 671 const intptr_t kNumInputs = 2; |
634 const intptr_t kNumTemps = 0; | 672 const intptr_t kNumTemps = 0; |
635 LocationSummary* locs = new (zone) | 673 LocationSummary* locs = new (zone) |
636 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 674 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
637 locs->set_in(0, Location::RequiresRegister()); | 675 locs->set_in(0, Location::RequiresRegister()); |
638 // Only one input can be a constant operand. The case of two constant | 676 // Only one input can be a constant operand. The case of two constant |
639 // operands should be handled by constant propagation. | 677 // operands should be handled by constant propagation. |
640 locs->set_in(1, Location::RegisterOrConstant(right())); | 678 locs->set_in(1, Location::RegisterOrConstant(right())); |
641 return locs; | 679 return locs; |
642 } | 680 } |
643 | 681 |
644 | 682 |
645 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 683 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
646 BranchLabels labels) { | 684 BranchLabels labels) { |
647 Register left = locs()->in(0).reg(); | 685 Register left = locs()->in(0).reg(); |
648 Location right = locs()->in(1); | 686 Location right = locs()->in(1); |
649 if (right.IsConstant()) { | 687 if (right.IsConstant()) { |
650 ASSERT(right.constant().IsSmi()); | 688 ASSERT(right.constant().IsSmi()); |
651 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw()); | 689 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw()); |
652 __ testl(left, Immediate(imm)); | 690 __ testl(left, Immediate(imm)); |
653 } else { | 691 } else { |
654 __ testl(left, right.reg()); | 692 __ testl(left, right.reg()); |
655 } | 693 } |
656 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; | 694 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; |
657 return true_condition; | 695 return true_condition; |
658 } | 696 } |
659 | 697 |
660 | 698 |
661 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
662 // Never emitted outside of the BranchInstr. | |
663 UNREACHABLE(); | |
664 } | |
665 | |
666 | |
667 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
668 BranchInstr* branch) { | |
669 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
670 Condition true_condition = EmitComparisonCode(compiler, labels); | |
671 EmitBranchOnCondition(compiler, true_condition, labels); | |
672 } | |
673 | |
674 | |
675 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, | 699 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, |
676 bool opt) const { | 700 bool opt) const { |
677 const intptr_t kNumInputs = 1; | 701 const intptr_t kNumInputs = 1; |
678 const intptr_t kNumTemps = 1; | 702 const intptr_t kNumTemps = 1; |
679 LocationSummary* locs = new (zone) | 703 LocationSummary* locs = new (zone) |
680 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 704 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
681 locs->set_in(0, Location::RequiresRegister()); | 705 locs->set_in(0, Location::RequiresRegister()); |
682 locs->set_temp(0, Location::RequiresRegister()); | 706 locs->set_temp(0, Location::RequiresRegister()); |
683 locs->set_out(0, Location::RequiresRegister()); | 707 locs->set_out(0, Location::RequiresRegister()); |
684 return locs; | 708 return locs; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 // If the cid is not in the list, jump to the opposite label from the cids | 740 // If the cid is not in the list, jump to the opposite label from the cids |
717 // that are in the list. These must be all the same (see asserts in the | 741 // that are in the list. These must be all the same (see asserts in the |
718 // constructor). | 742 // constructor). |
719 Label* target = result ? labels.false_label : labels.true_label; | 743 Label* target = result ? labels.false_label : labels.true_label; |
720 if (target != labels.fall_through) { | 744 if (target != labels.fall_through) { |
721 __ jmp(target); | 745 __ jmp(target); |
722 } | 746 } |
723 } else { | 747 } else { |
724 __ jmp(deopt); | 748 __ jmp(deopt); |
725 } | 749 } |
726 // Dummy result as the last instruction is a jump, any conditional | 750 // Dummy result as this method already did the jump, there's no need |
727 // branch using the result will therefore be skipped. | 751 // for the caller to branch on a condition. |
728 return ZERO; | 752 return INVALID_CONDITION; |
729 } | 753 } |
730 | 754 |
731 | 755 |
732 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
733 BranchInstr* branch) { | |
734 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
735 EmitComparisonCode(compiler, labels); | |
736 } | |
737 | |
738 | |
739 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
740 Register result_reg = locs()->out(0).reg(); | |
741 Label is_true, is_false, done; | |
742 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
743 EmitComparisonCode(compiler, labels); | |
744 __ Bind(&is_false); | |
745 __ LoadObject(result_reg, Bool::False()); | |
746 __ jmp(&done, Assembler::kNearJump); | |
747 __ Bind(&is_true); | |
748 __ LoadObject(result_reg, Bool::True()); | |
749 __ Bind(&done); | |
750 } | |
751 | |
752 | |
753 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, | 756 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, |
754 bool opt) const { | 757 bool opt) const { |
755 const intptr_t kNumInputs = 2; | 758 const intptr_t kNumInputs = 2; |
756 const intptr_t kNumTemps = 0; | 759 const intptr_t kNumTemps = 0; |
757 if (operation_cid() == kMintCid) { | 760 if (operation_cid() == kMintCid) { |
758 const intptr_t kNumTemps = 0; | 761 const intptr_t kNumTemps = 0; |
759 LocationSummary* locs = new (zone) | 762 LocationSummary* locs = new (zone) |
760 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 763 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
761 locs->set_in(0, Location::Pair(Location::RequiresRegister(), | 764 locs->set_in(0, Location::Pair(Location::RequiresRegister(), |
762 Location::RequiresRegister())); | 765 Location::RequiresRegister())); |
(...skipping 30 matching lines...) Expand all Loading... |
793 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); | 796 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); |
794 } else if (operation_cid() == kMintCid) { | 797 } else if (operation_cid() == kMintCid) { |
795 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); | 798 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); |
796 } else { | 799 } else { |
797 ASSERT(operation_cid() == kDoubleCid); | 800 ASSERT(operation_cid() == kDoubleCid); |
798 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); | 801 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); |
799 } | 802 } |
800 } | 803 } |
801 | 804 |
802 | 805 |
803 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
804 Label is_true, is_false; | |
805 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
806 Condition true_condition = EmitComparisonCode(compiler, labels); | |
807 EmitBranchOnCondition(compiler, true_condition, labels); | |
808 | |
809 Register result = locs()->out(0).reg(); | |
810 Label done; | |
811 __ Bind(&is_false); | |
812 __ LoadObject(result, Bool::False()); | |
813 __ jmp(&done, Assembler::kNearJump); | |
814 __ Bind(&is_true); | |
815 __ LoadObject(result, Bool::True()); | |
816 __ Bind(&done); | |
817 } | |
818 | |
819 | |
820 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
821 BranchInstr* branch) { | |
822 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
823 Condition true_condition = EmitComparisonCode(compiler, labels); | |
824 EmitBranchOnCondition(compiler, true_condition, labels); | |
825 } | |
826 | |
827 | |
828 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, | 806 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, |
829 bool opt) const { | 807 bool opt) const { |
830 return MakeCallSummary(zone); | 808 return MakeCallSummary(zone); |
831 } | 809 } |
832 | 810 |
833 | 811 |
834 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 812 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
835 SetupNative(); | 813 SetupNative(); |
836 Register result = locs()->out(0).reg(); | 814 Register result = locs()->out(0).reg(); |
837 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); | 815 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); |
(...skipping 3150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3988 __ AddImmediate(ESP, Immediate(kDoubleSize)); | 3966 __ AddImmediate(ESP, Immediate(kDoubleSize)); |
3989 // Mask off sign bit. | 3967 // Mask off sign bit. |
3990 __ andl(temp, Immediate(0x7FFFFFFF)); | 3968 __ andl(temp, Immediate(0x7FFFFFFF)); |
3991 // Compare with +infinity. | 3969 // Compare with +infinity. |
3992 __ cmpl(temp, Immediate(0x7FF00000)); | 3970 __ cmpl(temp, Immediate(0x7FF00000)); |
3993 return is_negated ? NOT_EQUAL : EQUAL; | 3971 return is_negated ? NOT_EQUAL : EQUAL; |
3994 } | 3972 } |
3995 } | 3973 } |
3996 | 3974 |
3997 | 3975 |
3998 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
3999 BranchInstr* branch) { | |
4000 ASSERT(compiler->is_optimizing()); | |
4001 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
4002 Condition true_condition = EmitComparisonCode(compiler, labels); | |
4003 EmitBranchOnCondition(compiler, true_condition, labels); | |
4004 } | |
4005 | |
4006 | |
4007 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
4008 Label is_true, is_false; | |
4009 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
4010 Condition true_condition = EmitComparisonCode(compiler, labels); | |
4011 EmitBranchOnCondition(compiler, true_condition, labels); | |
4012 | |
4013 Register result = locs()->out(0).reg(); | |
4014 Label done; | |
4015 __ Bind(&is_false); | |
4016 __ LoadObject(result, Bool::False()); | |
4017 __ jmp(&done); | |
4018 __ Bind(&is_true); | |
4019 __ LoadObject(result, Bool::True()); | |
4020 __ Bind(&done); | |
4021 } | |
4022 | |
4023 | |
4024 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, | 3976 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, |
4025 bool opt) const { | 3977 bool opt) const { |
4026 const intptr_t kNumInputs = 2; | 3978 const intptr_t kNumInputs = 2; |
4027 const intptr_t kNumTemps = 0; | 3979 const intptr_t kNumTemps = 0; |
4028 LocationSummary* summary = new (zone) | 3980 LocationSummary* summary = new (zone) |
4029 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3981 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4030 summary->set_in(0, Location::RequiresFpuRegister()); | 3982 summary->set_in(0, Location::RequiresFpuRegister()); |
4031 summary->set_in(1, Location::RequiresFpuRegister()); | 3983 summary->set_in(1, Location::RequiresFpuRegister()); |
4032 summary->set_out(0, Location::SameAsFirstInput()); | 3984 summary->set_out(0, Location::SameAsFirstInput()); |
4033 return summary; | 3985 return summary; |
(...skipping 2676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6710 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); | 6662 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); |
6711 } | 6663 } |
6712 if (kind() != Token::kEQ_STRICT) { | 6664 if (kind() != Token::kEQ_STRICT) { |
6713 ASSERT(kind() == Token::kNE_STRICT); | 6665 ASSERT(kind() == Token::kNE_STRICT); |
6714 true_condition = NegateCondition(true_condition); | 6666 true_condition = NegateCondition(true_condition); |
6715 } | 6667 } |
6716 return true_condition; | 6668 return true_condition; |
6717 } | 6669 } |
6718 | 6670 |
6719 | 6671 |
6720 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6721 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | |
6722 | |
6723 Label is_true, is_false; | |
6724 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
6725 Condition true_condition = EmitComparisonCode(compiler, labels); | |
6726 EmitBranchOnCondition(compiler, true_condition, labels); | |
6727 | |
6728 Register result = locs()->out(0).reg(); | |
6729 Label done; | |
6730 __ Bind(&is_false); | |
6731 __ LoadObject(result, Bool::False()); | |
6732 __ jmp(&done, Assembler::kNearJump); | |
6733 __ Bind(&is_true); | |
6734 __ LoadObject(result, Bool::True()); | |
6735 __ Bind(&done); | |
6736 } | |
6737 | |
6738 | |
6739 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
6740 BranchInstr* branch) { | |
6741 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | |
6742 | |
6743 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
6744 Condition true_condition = EmitComparisonCode(compiler, labels); | |
6745 EmitBranchOnCondition(compiler, true_condition, labels); | |
6746 } | |
6747 | |
6748 | |
6749 // Detect pattern when one value is zero and another is a power of 2. | 6672 // Detect pattern when one value is zero and another is a power of 2. |
6750 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 6673 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
6751 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 6674 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
6752 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 6675 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
6753 } | 6676 } |
6754 | 6677 |
6755 | 6678 |
6756 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone, | 6679 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone, |
6757 bool opt) const { | 6680 bool opt) const { |
6758 comparison()->InitializeLocationSummary(zone, opt); | 6681 comparison()->InitializeLocationSummary(zone, opt); |
6759 // TODO(vegorov): support byte register constraints in the register allocator. | 6682 // TODO(vegorov): support byte register constraints in the register allocator. |
6760 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX)); | 6683 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX)); |
6761 return comparison()->locs(); | 6684 return comparison()->locs(); |
6762 } | 6685 } |
6763 | 6686 |
6764 | 6687 |
6765 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6688 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6766 ASSERT(locs()->out(0).reg() == EDX); | 6689 ASSERT(locs()->out(0).reg() == EDX); |
6767 | 6690 |
6768 // Clear upper part of the out register. We are going to use setcc on it | 6691 // Clear upper part of the out register. We are going to use setcc on it |
6769 // which is a byte move. | 6692 // which is a byte move. |
6770 __ xorl(EDX, EDX); | 6693 __ xorl(EDX, EDX); |
6771 | 6694 |
6772 // Emit comparison code. This must not overwrite the result register. | 6695 // Emit comparison code. This must not overwrite the result register. |
| 6696 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using |
| 6697 // the labels or returning an invalid condition. |
6773 BranchLabels labels = {NULL, NULL, NULL}; | 6698 BranchLabels labels = {NULL, NULL, NULL}; |
6774 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); | 6699 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); |
| 6700 ASSERT(true_condition != INVALID_CONDITION); |
6775 | 6701 |
6776 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); | 6702 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); |
6777 | 6703 |
6778 intptr_t true_value = if_true_; | 6704 intptr_t true_value = if_true_; |
6779 intptr_t false_value = if_false_; | 6705 intptr_t false_value = if_false_; |
6780 | 6706 |
6781 if (is_power_of_two_kind) { | 6707 if (is_power_of_two_kind) { |
6782 if (true_value == 0) { | 6708 if (true_value == 0) { |
6783 // We need to have zero in EDX on true_condition. | 6709 // We need to have zero in EDX on true_condition. |
6784 true_condition = NegateCondition(true_condition); | 6710 true_condition = NegateCondition(true_condition); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6921 __ Drop(1); | 6847 __ Drop(1); |
6922 __ popl(result); | 6848 __ popl(result); |
6923 } | 6849 } |
6924 | 6850 |
6925 | 6851 |
6926 } // namespace dart | 6852 } // namespace dart |
6927 | 6853 |
6928 #undef __ | 6854 #undef __ |
6929 | 6855 |
6930 #endif // defined TARGET_ARCH_IA32 | 6856 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |