| 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 |