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

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

Issue 2949513002: Revert "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
« no previous file with comments | « runtime/vm/intermediate_language_dbc.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // 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
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 ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 603 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
604 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
605
604 Label is_true, is_false; 606 Label is_true, is_false;
605 BranchLabels labels = {&is_true, &is_false, &is_false}; 607 BranchLabels labels = {&is_true, &is_false, &is_false};
606 Condition true_condition = EmitComparisonCode(compiler, labels); 608 Condition true_condition = EmitComparisonCode(compiler, labels);
607 if (true_condition != INVALID_CONDITION) { 609 EmitBranchOnCondition(compiler, true_condition, labels);
608 EmitBranchOnCondition(compiler, true_condition, labels);
609 }
610 610
611 Register result = locs()->out(0).reg(); 611 Register result = locs()->out(0).reg();
612 Label done; 612 Label done;
613 __ Bind(&is_false); 613 __ Bind(&is_false);
614 __ LoadObject(result, Bool::False()); 614 __ LoadObject(result, Bool::False());
615 __ jmp(&done, Assembler::kNearJump); 615 __ jmp(&done, Assembler::kNearJump);
616 __ Bind(&is_true); 616 __ Bind(&is_true);
617 __ LoadObject(result, Bool::True()); 617 __ LoadObject(result, Bool::True());
618 __ Bind(&done); 618 __ Bind(&done);
619 } 619 }
620 620
621 621
622 void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, 622 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
623 BranchInstr* branch) { 623 BranchInstr* branch) {
624 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
625
624 BranchLabels labels = compiler->CreateBranchLabels(branch); 626 BranchLabels labels = compiler->CreateBranchLabels(branch);
625 Condition true_condition = EmitComparisonCode(compiler, labels); 627 Condition true_condition = EmitComparisonCode(compiler, labels);
626 if (true_condition != INVALID_CONDITION) { 628 EmitBranchOnCondition(compiler, true_condition, labels);
627 EmitBranchOnCondition(compiler, true_condition, labels);
628 }
629 } 629 }
630 630
631 631
632 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { 632 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const {
633 const intptr_t kNumInputs = 2; 633 const intptr_t kNumInputs = 2;
634 const intptr_t kNumTemps = 0; 634 const intptr_t kNumTemps = 0;
635 LocationSummary* locs = new (zone) 635 LocationSummary* locs = new (zone)
636 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 636 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
637 locs->set_in(0, Location::RequiresRegister()); 637 locs->set_in(0, Location::RequiresRegister());
638 // Only one input can be a constant operand. The case of two constant 638 // Only one input can be a constant operand. The case of two constant
(...skipping 12 matching lines...) Expand all
651 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw()); 651 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw());
652 __ testl(left, Immediate(imm)); 652 __ testl(left, Immediate(imm));
653 } else { 653 } else {
654 __ testl(left, right.reg()); 654 __ testl(left, right.reg());
655 } 655 }
656 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; 656 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
657 return true_condition; 657 return true_condition;
658 } 658 }
659 659
660 660
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
661 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, 675 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
662 bool opt) const { 676 bool opt) const {
663 const intptr_t kNumInputs = 1; 677 const intptr_t kNumInputs = 1;
664 const intptr_t kNumTemps = 1; 678 const intptr_t kNumTemps = 1;
665 LocationSummary* locs = new (zone) 679 LocationSummary* locs = new (zone)
666 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 680 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
667 locs->set_in(0, Location::RequiresRegister()); 681 locs->set_in(0, Location::RequiresRegister());
668 locs->set_temp(0, Location::RequiresRegister()); 682 locs->set_temp(0, Location::RequiresRegister());
669 locs->set_out(0, Location::RequiresRegister()); 683 locs->set_out(0, Location::RequiresRegister());
670 return locs; 684 return locs;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 // If the cid is not in the list, jump to the opposite label from the cids 716 // If the cid is not in the list, jump to the opposite label from the cids
703 // that are in the list. These must be all the same (see asserts in the 717 // that are in the list. These must be all the same (see asserts in the
704 // constructor). 718 // constructor).
705 Label* target = result ? labels.false_label : labels.true_label; 719 Label* target = result ? labels.false_label : labels.true_label;
706 if (target != labels.fall_through) { 720 if (target != labels.fall_through) {
707 __ jmp(target); 721 __ jmp(target);
708 } 722 }
709 } else { 723 } else {
710 __ jmp(deopt); 724 __ jmp(deopt);
711 } 725 }
712 // Dummy result as this method already did the jump, there's no need 726 // Dummy result as the last instruction is a jump, any conditional
713 // for the caller to branch on a condition. 727 // branch using the result will therefore be skipped.
714 return INVALID_CONDITION; 728 return ZERO;
715 } 729 }
716 730
717 731
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
718 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, 753 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
719 bool opt) const { 754 bool opt) const {
720 const intptr_t kNumInputs = 2; 755 const intptr_t kNumInputs = 2;
721 const intptr_t kNumTemps = 0; 756 const intptr_t kNumTemps = 0;
722 if (operation_cid() == kMintCid) { 757 if (operation_cid() == kMintCid) {
723 const intptr_t kNumTemps = 0; 758 const intptr_t kNumTemps = 0;
724 LocationSummary* locs = new (zone) 759 LocationSummary* locs = new (zone)
725 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 760 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
726 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 761 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
727 Location::RequiresRegister())); 762 Location::RequiresRegister()));
(...skipping 30 matching lines...) Expand all
758 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 793 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
759 } else if (operation_cid() == kMintCid) { 794 } else if (operation_cid() == kMintCid) {
760 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); 795 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
761 } else { 796 } else {
762 ASSERT(operation_cid() == kDoubleCid); 797 ASSERT(operation_cid() == kDoubleCid);
763 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 798 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
764 } 799 }
765 } 800 }
766 801
767 802
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
768 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, 828 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone,
769 bool opt) const { 829 bool opt) const {
770 return MakeCallSummary(zone); 830 return MakeCallSummary(zone);
771 } 831 }
772 832
773 833
774 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 834 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
775 SetupNative(); 835 SetupNative();
776 Register result = locs()->out(0).reg(); 836 Register result = locs()->out(0).reg();
777 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); 837 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
(...skipping 3150 matching lines...) Expand 10 before | Expand all | Expand 10 after
3928 __ AddImmediate(ESP, Immediate(kDoubleSize)); 3988 __ AddImmediate(ESP, Immediate(kDoubleSize));
3929 // Mask off sign bit. 3989 // Mask off sign bit.
3930 __ andl(temp, Immediate(0x7FFFFFFF)); 3990 __ andl(temp, Immediate(0x7FFFFFFF));
3931 // Compare with +infinity. 3991 // Compare with +infinity.
3932 __ cmpl(temp, Immediate(0x7FF00000)); 3992 __ cmpl(temp, Immediate(0x7FF00000));
3933 return is_negated ? NOT_EQUAL : EQUAL; 3993 return is_negated ? NOT_EQUAL : EQUAL;
3934 } 3994 }
3935 } 3995 }
3936 3996
3937 3997
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
3938 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, 4024 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone,
3939 bool opt) const { 4025 bool opt) const {
3940 const intptr_t kNumInputs = 2; 4026 const intptr_t kNumInputs = 2;
3941 const intptr_t kNumTemps = 0; 4027 const intptr_t kNumTemps = 0;
3942 LocationSummary* summary = new (zone) 4028 LocationSummary* summary = new (zone)
3943 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4029 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3944 summary->set_in(0, Location::RequiresFpuRegister()); 4030 summary->set_in(0, Location::RequiresFpuRegister());
3945 summary->set_in(1, Location::RequiresFpuRegister()); 4031 summary->set_in(1, Location::RequiresFpuRegister());
3946 summary->set_out(0, Location::SameAsFirstInput()); 4032 summary->set_out(0, Location::SameAsFirstInput());
3947 return summary; 4033 return summary;
(...skipping 2676 matching lines...) Expand 10 before | Expand all | Expand 10 after
6624 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); 6710 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
6625 } 6711 }
6626 if (kind() != Token::kEQ_STRICT) { 6712 if (kind() != Token::kEQ_STRICT) {
6627 ASSERT(kind() == Token::kNE_STRICT); 6713 ASSERT(kind() == Token::kNE_STRICT);
6628 true_condition = NegateCondition(true_condition); 6714 true_condition = NegateCondition(true_condition);
6629 } 6715 }
6630 return true_condition; 6716 return true_condition;
6631 } 6717 }
6632 6718
6633 6719
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
6634 // Detect pattern when one value is zero and another is a power of 2. 6749 // Detect pattern when one value is zero and another is a power of 2.
6635 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 6750 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
6636 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 6751 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
6637 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 6752 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
6638 } 6753 }
6639 6754
6640 6755
6641 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone, 6756 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
6642 bool opt) const { 6757 bool opt) const {
6643 comparison()->InitializeLocationSummary(zone, opt); 6758 comparison()->InitializeLocationSummary(zone, opt);
6644 // TODO(vegorov): support byte register constraints in the register allocator. 6759 // TODO(vegorov): support byte register constraints in the register allocator.
6645 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX)); 6760 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX));
6646 return comparison()->locs(); 6761 return comparison()->locs();
6647 } 6762 }
6648 6763
6649 6764
6650 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6765 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6651 ASSERT(locs()->out(0).reg() == EDX); 6766 ASSERT(locs()->out(0).reg() == EDX);
6652 6767
6653 // Clear upper part of the out register. We are going to use setcc on it 6768 // Clear upper part of the out register. We are going to use setcc on it
6654 // which is a byte move. 6769 // which is a byte move.
6655 __ xorl(EDX, EDX); 6770 __ xorl(EDX, EDX);
6656 6771
6657 // Emit comparison code. This must not overwrite the result register. 6772 // Emit comparison code. This must not overwrite the result register.
6658 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
6659 // the labels or returning an invalid condition.
6660 BranchLabels labels = {NULL, NULL, NULL}; 6773 BranchLabels labels = {NULL, NULL, NULL};
6661 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); 6774 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
6662 ASSERT(true_condition != INVALID_CONDITION);
6663 6775
6664 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); 6776 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
6665 6777
6666 intptr_t true_value = if_true_; 6778 intptr_t true_value = if_true_;
6667 intptr_t false_value = if_false_; 6779 intptr_t false_value = if_false_;
6668 6780
6669 if (is_power_of_two_kind) { 6781 if (is_power_of_two_kind) {
6670 if (true_value == 0) { 6782 if (true_value == 0) {
6671 // We need to have zero in EDX on true_condition. 6783 // We need to have zero in EDX on true_condition.
6672 true_condition = NegateCondition(true_condition); 6784 true_condition = NegateCondition(true_condition);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
6809 __ Drop(1); 6921 __ Drop(1);
6810 __ popl(result); 6922 __ popl(result);
6811 } 6923 }
6812 6924
6813 6925
6814 } // namespace dart 6926 } // namespace dart
6815 6927
6816 #undef __ 6928 #undef __
6817 6929
6818 #endif // defined TARGET_ARCH_IA32 6930 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_dbc.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698