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

Side by Side Diff: src/compiler/arm/code-generator-arm.cc

Issue 850653002: [turbofan] Improve code generation for unordered comparisons. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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 | « no previous file | src/compiler/arm/instruction-selector-arm.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/arm/macro-assembler-arm.h" 7 #include "src/arm/macro-assembler-arm.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 public: 193 public:
194 OutOfLineLoadInteger(CodeGenerator* gen, Register result) 194 OutOfLineLoadInteger(CodeGenerator* gen, Register result)
195 : OutOfLineCode(gen), result_(result) {} 195 : OutOfLineCode(gen), result_(result) {}
196 196
197 void Generate() FINAL { __ mov(result_, Operand::Zero()); } 197 void Generate() FINAL { __ mov(result_, Operand::Zero()); }
198 198
199 private: 199 private:
200 Register const result_; 200 Register const result_;
201 }; 201 };
202 202
203
204 Condition FlagsConditionToCondition(FlagsCondition condition) {
205 switch (condition) {
206 case kEqual:
207 return eq;
208 case kNotEqual:
209 return ne;
210 case kSignedLessThan:
211 return lt;
212 case kSignedGreaterThanOrEqual:
213 return ge;
214 case kSignedLessThanOrEqual:
215 return le;
216 case kSignedGreaterThan:
217 return gt;
218 case kUnsignedLessThan:
219 return lo;
220 case kUnsignedGreaterThanOrEqual:
221 return hs;
222 case kUnsignedLessThanOrEqual:
223 return ls;
224 case kUnsignedGreaterThan:
225 return hi;
226 case kOverflow:
227 return vs;
228 case kNotOverflow:
229 return vc;
230 case kUnorderedEqual:
231 case kUnorderedNotEqual:
232 break;
233 }
234 UNREACHABLE();
235 return kNoCondition;
236 }
237
203 } // namespace 238 } // namespace
204 239
205 240
206 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ 241 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \
207 do { \ 242 do { \
208 auto result = i.OutputFloat##width##Register(); \ 243 auto result = i.OutputFloat##width##Register(); \
209 auto offset = i.InputRegister(0); \ 244 auto offset = i.InputRegister(0); \
210 if (instr->InputAt(1)->IsRegister()) { \ 245 if (instr->InputAt(1)->IsRegister()) { \
211 __ cmp(offset, i.InputRegister(1)); \ 246 __ cmp(offset, i.InputRegister(1)); \
212 } else { \ 247 } else { \
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 break; 714 break;
680 } 715 }
681 } 716 }
682 717
683 718
684 // Assembles branches after an instruction. 719 // Assembles branches after an instruction.
685 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 720 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
686 ArmOperandConverter i(this, instr); 721 ArmOperandConverter i(this, instr);
687 Label* tlabel = branch->true_label; 722 Label* tlabel = branch->true_label;
688 Label* flabel = branch->false_label; 723 Label* flabel = branch->false_label;
689 switch (branch->condition) { 724 Condition cc = FlagsConditionToCondition(branch->condition);
690 case kUnorderedEqual: 725 __ b(cc, tlabel);
691 // The "eq" condition will not catch the unordered case.
692 // The jump/fall through to false label will be used if the comparison
693 // was unordered.
694 case kEqual:
695 __ b(eq, tlabel);
696 break;
697 case kUnorderedNotEqual:
698 // Unordered or not equal can be tested with "ne" condtion.
699 // See ARMv7 manual A8.3 - Conditional execution.
700 case kNotEqual:
701 __ b(ne, tlabel);
702 break;
703 case kSignedLessThan:
704 __ b(lt, tlabel);
705 break;
706 case kSignedGreaterThanOrEqual:
707 __ b(ge, tlabel);
708 break;
709 case kSignedLessThanOrEqual:
710 __ b(le, tlabel);
711 break;
712 case kSignedGreaterThan:
713 __ b(gt, tlabel);
714 break;
715 case kUnorderedLessThan:
716 // The "lo" condition will not catch the unordered case.
717 // The jump/fall through to false label will be used if the comparison
718 // was unordered.
719 case kUnsignedLessThan:
720 __ b(lo, tlabel);
721 break;
722 case kUnorderedGreaterThanOrEqual:
723 // Unordered, greater than or equal can be tested with "hs" condtion.
724 // See ARMv7 manual A8.3 - Conditional execution.
725 case kUnsignedGreaterThanOrEqual:
726 __ b(hs, tlabel);
727 break;
728 case kUnorderedLessThanOrEqual:
729 // The "ls" condition will not catch the unordered case.
730 // The jump/fall through to false label will be used if the comparison
731 // was unordered.
732 case kUnsignedLessThanOrEqual:
733 __ b(ls, tlabel);
734 break;
735 case kUnorderedGreaterThan:
736 // Unordered or greater than can be tested with "hi" condtion.
737 // See ARMv7 manual A8.3 - Conditional execution.
738 case kUnsignedGreaterThan:
739 __ b(hi, tlabel);
740 break;
741 case kOverflow:
742 __ b(vs, tlabel);
743 break;
744 case kNotOverflow:
745 __ b(vc, tlabel);
746 break;
747 }
748 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. 726 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel.
749 } 727 }
750 728
751 729
752 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { 730 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
753 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); 731 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
754 } 732 }
755 733
756 734
757 // Assembles boolean materializations after an instruction. 735 // Assembles boolean materializations after an instruction.
758 void CodeGenerator::AssembleArchBoolean(Instruction* instr, 736 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
759 FlagsCondition condition) { 737 FlagsCondition condition) {
760 ArmOperandConverter i(this, instr); 738 ArmOperandConverter i(this, instr);
761 Label done;
762 739
763 // Materialize a full 32-bit 1 or 0 value. The result register is always the 740 // Materialize a full 32-bit 1 or 0 value. The result register is always the
764 // last output of the instruction. 741 // last output of the instruction.
765 Label check;
766 DCHECK_NE(0, instr->OutputCount()); 742 DCHECK_NE(0, instr->OutputCount());
767 Register reg = i.OutputRegister(instr->OutputCount() - 1); 743 Register reg = i.OutputRegister(instr->OutputCount() - 1);
768 Condition cc = kNoCondition; 744 Condition cc = FlagsConditionToCondition(condition);
769 switch (condition) {
770 case kUnorderedEqual:
771 __ b(vc, &check);
772 __ mov(reg, Operand(0));
773 __ b(&done);
774 // Fall through.
775 case kEqual:
776 cc = eq;
777 break;
778 case kUnorderedNotEqual:
779 __ b(vc, &check);
780 __ mov(reg, Operand(1));
781 __ b(&done);
782 // Fall through.
783 case kNotEqual:
784 cc = ne;
785 break;
786 case kSignedLessThan:
787 cc = lt;
788 break;
789 case kSignedGreaterThanOrEqual:
790 cc = ge;
791 break;
792 case kSignedLessThanOrEqual:
793 cc = le;
794 break;
795 case kSignedGreaterThan:
796 cc = gt;
797 break;
798 case kUnorderedLessThan:
799 __ b(vc, &check);
800 __ mov(reg, Operand(0));
801 __ b(&done);
802 // Fall through.
803 case kUnsignedLessThan:
804 cc = lo;
805 break;
806 case kUnorderedGreaterThanOrEqual:
807 __ b(vc, &check);
808 __ mov(reg, Operand(1));
809 __ b(&done);
810 // Fall through.
811 case kUnsignedGreaterThanOrEqual:
812 cc = hs;
813 break;
814 case kUnorderedLessThanOrEqual:
815 __ b(vc, &check);
816 __ mov(reg, Operand(0));
817 __ b(&done);
818 // Fall through.
819 case kUnsignedLessThanOrEqual:
820 cc = ls;
821 break;
822 case kUnorderedGreaterThan:
823 __ b(vc, &check);
824 __ mov(reg, Operand(1));
825 __ b(&done);
826 // Fall through.
827 case kUnsignedGreaterThan:
828 cc = hi;
829 break;
830 case kOverflow:
831 cc = vs;
832 break;
833 case kNotOverflow:
834 cc = vc;
835 break;
836 }
837 __ bind(&check);
838 __ mov(reg, Operand(0)); 745 __ mov(reg, Operand(0));
839 __ mov(reg, Operand(1), LeaveCC, cc); 746 __ mov(reg, Operand(1), LeaveCC, cc);
840 __ bind(&done);
841 } 747 }
842 748
843 749
844 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { 750 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
845 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 751 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
846 isolate(), deoptimization_id, Deoptimizer::LAZY); 752 isolate(), deoptimization_id, Deoptimizer::LAZY);
847 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 753 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
848 } 754 }
849 755
850 756
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 } 1029 }
1124 } 1030 }
1125 MarkLazyDeoptSite(); 1031 MarkLazyDeoptSite();
1126 } 1032 }
1127 1033
1128 #undef __ 1034 #undef __
1129 1035
1130 } // namespace compiler 1036 } // namespace compiler
1131 } // namespace internal 1037 } // namespace internal
1132 } // namespace v8 1038 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/arm/instruction-selector-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698