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

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

Issue 850733004: MIPS: [turbofan] Improve code generation for unordered comparisons. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix switch cases. 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/mips/instruction-selector-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 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 #include "src/compiler/code-generator-impl.h" 6 #include "src/compiler/code-generator-impl.h"
7 #include "src/compiler/gap-resolver.h" 7 #include "src/compiler/gap-resolver.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties-inl.h" 9 #include "src/compiler/node-properties-inl.h"
10 #include "src/compiler/osr.h" 10 #include "src/compiler/osr.h"
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 : OutOfLineRound(gen, result) {} 196 : OutOfLineRound(gen, result) {}
197 }; 197 };
198 198
199 199
200 class OutOfLineCeil FINAL : public OutOfLineRound { 200 class OutOfLineCeil FINAL : public OutOfLineRound {
201 public: 201 public:
202 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result) 202 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result)
203 : OutOfLineRound(gen, result) {} 203 : OutOfLineRound(gen, result) {}
204 }; 204 };
205 205
206
207 Condition FlagsConditionToConditionCmp(FlagsCondition condition) {
208 switch (condition) {
209 case kEqual:
210 return eq;
211 case kNotEqual:
212 return ne;
213 case kSignedLessThan:
214 return lt;
215 case kSignedGreaterThanOrEqual:
216 return ge;
217 case kSignedLessThanOrEqual:
218 return le;
219 case kSignedGreaterThan:
220 return gt;
221 case kUnsignedLessThan:
222 return lo;
223 case kUnsignedGreaterThanOrEqual:
224 return hs;
225 case kUnsignedLessThanOrEqual:
226 return ls;
227 case kUnsignedGreaterThan:
228 return hi;
229 case kUnorderedEqual:
230 case kUnorderedNotEqual:
231 break;
232 default:
233 break;
234 }
235 UNREACHABLE();
236 return kNoCondition;
237 }
238
239
240 Condition FlagsConditionToConditionTst(FlagsCondition condition) {
241 switch (condition) {
242 case kNotEqual:
243 return ne;
244 case kEqual:
245 return eq;
246 default:
247 break;
248 }
249 UNREACHABLE();
250 return kNoCondition;
251 }
252
253
254 Condition FlagsConditionToConditionOvf(FlagsCondition condition) {
255 switch (condition) {
256 case kOverflow:
257 return lt;
258 case kNotOverflow:
259 return ge;
260 default:
261 break;
262 }
263 UNREACHABLE();
264 return kNoCondition;
265 }
266
206 } // namespace 267 } // namespace
207 268
208 269
209 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ 270 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \
210 do { \ 271 do { \
211 auto result = i.Output##width##Register(); \ 272 auto result = i.Output##width##Register(); \
212 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ 273 auto ool = new (zone()) OutOfLineLoad##width(this, result); \
213 if (instr->InputAt(0)->IsRegister()) { \ 274 if (instr->InputAt(0)->IsRegister()) { \
214 auto offset = i.InputRegister(0); \ 275 auto offset = i.InputRegister(0); \
215 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ 276 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 // MIPS does not have condition code flags, so compare and branch are 700 // MIPS does not have condition code flags, so compare and branch are
640 // implemented differently than on the other arch's. The compare operations 701 // implemented differently than on the other arch's. The compare operations
641 // emit mips pseudo-instructions, which are handled here by branch 702 // emit mips pseudo-instructions, which are handled here by branch
642 // instructions that do the actual comparison. Essential that the input 703 // instructions that do the actual comparison. Essential that the input
643 // registers to compare pseudo-op are not modified before this branch op, as 704 // registers to compare pseudo-op are not modified before this branch op, as
644 // they are tested here. 705 // they are tested here.
645 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were 706 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
646 // not separated by other instructions. 707 // not separated by other instructions.
647 708
648 if (instr->arch_opcode() == kMipsTst) { 709 if (instr->arch_opcode() == kMipsTst) {
649 switch (branch->condition) { 710 cc = FlagsConditionToConditionTst(branch->condition);
650 case kNotEqual:
651 cc = ne;
652 break;
653 case kEqual:
654 cc = eq;
655 break;
656 default:
657 UNSUPPORTED_COND(kMipsTst, branch->condition);
658 break;
659 }
660 __ And(at, i.InputRegister(0), i.InputOperand(1)); 711 __ And(at, i.InputRegister(0), i.InputOperand(1));
661 __ Branch(tlabel, cc, at, Operand(zero_reg)); 712 __ Branch(tlabel, cc, at, Operand(zero_reg));
662 713
663 } else if (instr->arch_opcode() == kMipsAddOvf || 714 } else if (instr->arch_opcode() == kMipsAddOvf ||
664 instr->arch_opcode() == kMipsSubOvf) { 715 instr->arch_opcode() == kMipsSubOvf) {
665 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow. 716 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow.
666 switch (branch->condition) { 717 cc = FlagsConditionToConditionOvf(branch->condition);
667 case kOverflow:
668 cc = lt;
669 break;
670 case kNotOverflow:
671 cc = ge;
672 break;
673 default:
674 UNSUPPORTED_COND(kMipsAddOvf, branch->condition);
675 break;
676 }
677 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg)); 718 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg));
678 719
679 } else if (instr->arch_opcode() == kMipsCmp) { 720 } else if (instr->arch_opcode() == kMipsCmp) {
680 switch (branch->condition) { 721 cc = FlagsConditionToConditionCmp(branch->condition);
681 case kEqual:
682 cc = eq;
683 break;
684 case kNotEqual:
685 cc = ne;
686 break;
687 case kSignedLessThan:
688 cc = lt;
689 break;
690 case kSignedGreaterThanOrEqual:
691 cc = ge;
692 break;
693 case kSignedLessThanOrEqual:
694 cc = le;
695 break;
696 case kSignedGreaterThan:
697 cc = gt;
698 break;
699 case kUnsignedLessThan:
700 cc = lo;
701 break;
702 case kUnsignedGreaterThanOrEqual:
703 cc = hs;
704 break;
705 case kUnsignedLessThanOrEqual:
706 cc = ls;
707 break;
708 case kUnsignedGreaterThan:
709 cc = hi;
710 break;
711 default:
712 UNSUPPORTED_COND(kMipsCmp, branch->condition);
713 break;
714 }
715 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); 722 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
716 723
717 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. 724 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel.
718 725
719 } else if (instr->arch_opcode() == kMipsCmpD) { 726 } else if (instr->arch_opcode() == kMipsCmpD) {
720 // TODO(dusmil) optimize unordered checks to use fewer instructions 727 // TODO(dusmil) optimize unordered checks to use fewer instructions
721 // even if we have to unfold BranchF macro. 728 // even if we have to unfold BranchF macro.
722 Label* nan = flabel; 729 Label* nan = flabel;
723 switch (branch->condition) { 730 switch (branch->condition) {
724 case kUnorderedEqual: 731 case kEqual:
725 cc = eq; 732 cc = eq;
726 break; 733 break;
727 case kUnorderedNotEqual: 734 case kNotEqual:
728 cc = ne; 735 cc = ne;
729 nan = tlabel; 736 nan = tlabel;
730 break; 737 break;
731 case kUnorderedLessThan: 738 case kUnsignedLessThan:
732 cc = lt; 739 cc = lt;
733 break; 740 break;
734 case kUnorderedGreaterThanOrEqual: 741 case kUnsignedGreaterThanOrEqual:
735 cc = ge; 742 cc = ge;
736 nan = tlabel; 743 nan = tlabel;
737 break; 744 break;
738 case kUnorderedLessThanOrEqual: 745 case kUnsignedLessThanOrEqual:
739 cc = le; 746 cc = le;
740 break; 747 break;
741 case kUnorderedGreaterThan: 748 case kUnsignedGreaterThan:
742 cc = gt; 749 cc = gt;
743 nan = tlabel; 750 nan = tlabel;
744 break; 751 break;
745 default: 752 default:
746 UNSUPPORTED_COND(kMipsCmpD, branch->condition); 753 UNSUPPORTED_COND(kMipsCmpD, branch->condition);
747 break; 754 break;
748 } 755 }
749 __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0), 756 __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0),
750 i.InputDoubleRegister(1)); 757 i.InputDoubleRegister(1));
751 758
(...skipping 29 matching lines...) Expand all
781 // implemented differently than on the other arch's. The compare operations 788 // implemented differently than on the other arch's. The compare operations
782 // emit mips psuedo-instructions, which are checked and handled here. 789 // emit mips psuedo-instructions, which are checked and handled here.
783 790
784 // For materializations, we use delay slot to set the result true, and 791 // For materializations, we use delay slot to set the result true, and
785 // in the false case, where we fall thru the branch, we reset the result 792 // in the false case, where we fall thru the branch, we reset the result
786 // false. 793 // false.
787 794
788 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were 795 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
789 // not separated by other instructions. 796 // not separated by other instructions.
790 if (instr->arch_opcode() == kMipsTst) { 797 if (instr->arch_opcode() == kMipsTst) {
791 switch (condition) { 798 cc = FlagsConditionToConditionTst(condition);
792 case kNotEqual:
793 cc = ne;
794 break;
795 case kEqual:
796 cc = eq;
797 break;
798 default:
799 UNSUPPORTED_COND(kMipsTst, condition);
800 break;
801 }
802 __ And(at, i.InputRegister(0), i.InputOperand(1)); 799 __ And(at, i.InputRegister(0), i.InputOperand(1));
803 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); 800 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
804 __ li(result, Operand(1)); // In delay slot. 801 __ li(result, Operand(1)); // In delay slot.
805 802
806 } else if (instr->arch_opcode() == kMipsAddOvf || 803 } else if (instr->arch_opcode() == kMipsAddOvf ||
807 instr->arch_opcode() == kMipsSubOvf) { 804 instr->arch_opcode() == kMipsSubOvf) {
808 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. 805 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow.
809 switch (condition) { 806 cc = FlagsConditionToConditionOvf(condition);
810 case kOverflow:
811 cc = lt;
812 break;
813 case kNotOverflow:
814 cc = ge;
815 break;
816 default:
817 UNSUPPORTED_COND(kMipsAddOvf, condition);
818 break;
819 }
820 __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg)); 807 __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg));
821 __ li(result, Operand(1)); // In delay slot. 808 __ li(result, Operand(1)); // In delay slot.
822 809
823 810
824 } else if (instr->arch_opcode() == kMipsCmp) { 811 } else if (instr->arch_opcode() == kMipsCmp) {
825 Register left = i.InputRegister(0); 812 Register left = i.InputRegister(0);
826 Operand right = i.InputOperand(1); 813 Operand right = i.InputOperand(1);
827 switch (condition) { 814 cc = FlagsConditionToConditionCmp(condition);
828 case kEqual:
829 cc = eq;
830 break;
831 case kNotEqual:
832 cc = ne;
833 break;
834 case kSignedLessThan:
835 cc = lt;
836 break;
837 case kSignedGreaterThanOrEqual:
838 cc = ge;
839 break;
840 case kSignedLessThanOrEqual:
841 cc = le;
842 break;
843 case kSignedGreaterThan:
844 cc = gt;
845 break;
846 case kUnsignedLessThan:
847 cc = lo;
848 break;
849 case kUnsignedGreaterThanOrEqual:
850 cc = hs;
851 break;
852 case kUnsignedLessThanOrEqual:
853 cc = ls;
854 break;
855 case kUnsignedGreaterThan:
856 cc = hi;
857 break;
858 default:
859 UNSUPPORTED_COND(kMipsCmp, condition);
860 break;
861 }
862 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); 815 __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
863 __ li(result, Operand(1)); // In delay slot. 816 __ li(result, Operand(1)); // In delay slot.
864 817
865 } else if (instr->arch_opcode() == kMipsCmpD) { 818 } else if (instr->arch_opcode() == kMipsCmpD) {
866 FPURegister left = i.InputDoubleRegister(0); 819 FPURegister left = i.InputDoubleRegister(0);
867 FPURegister right = i.InputDoubleRegister(1); 820 FPURegister right = i.InputDoubleRegister(1);
868 // TODO(plind): Provide NaN-testing macro-asm function without need for 821 // TODO(plind): Provide NaN-testing macro-asm function without need for
869 // BranchF. 822 // BranchF.
870 FPURegister dummy1 = f0; 823 FPURegister dummy1 = f0;
871 FPURegister dummy2 = f2; 824 FPURegister dummy2 = f2;
872 switch (condition) { 825 switch (condition) {
873 case kUnorderedEqual: 826 case kEqual:
874 // TODO(plind): improve the NaN testing throughout this function. 827 // TODO(plind): improve the NaN testing throughout this function.
875 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); 828 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
876 cc = eq; 829 cc = eq;
877 break; 830 break;
878 case kUnorderedNotEqual: 831 case kNotEqual:
879 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); 832 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
880 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. 833 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
881 cc = ne; 834 cc = ne;
882 break; 835 break;
883 case kUnorderedLessThan: 836 case kUnsignedLessThan:
884 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); 837 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
885 cc = lt; 838 cc = lt;
886 break; 839 break;
887 case kUnorderedGreaterThanOrEqual: 840 case kUnsignedGreaterThanOrEqual:
888 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); 841 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
889 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. 842 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
890 cc = ge; 843 cc = ge;
891 break; 844 break;
892 case kUnorderedLessThanOrEqual: 845 case kUnsignedLessThanOrEqual:
893 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); 846 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
894 cc = le; 847 cc = le;
895 break; 848 break;
896 case kUnorderedGreaterThan: 849 case kUnsignedGreaterThan:
897 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); 850 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
898 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. 851 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
899 cc = gt; 852 cc = gt;
900 break; 853 break;
901 default: 854 default:
902 UNSUPPORTED_COND(kMipsCmp, condition); 855 UNSUPPORTED_COND(kMipsCmp, condition);
903 break; 856 break;
904 } 857 }
905 __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right); 858 __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right);
906 __ li(result, Operand(1)); // In delay slot - branch taken returns 1. 859 __ li(result, Operand(1)); // In delay slot - branch taken returns 1.
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 } 1147 }
1195 } 1148 }
1196 MarkLazyDeoptSite(); 1149 MarkLazyDeoptSite();
1197 } 1150 }
1198 1151
1199 #undef __ 1152 #undef __
1200 1153
1201 } // namespace compiler 1154 } // namespace compiler
1202 } // namespace internal 1155 } // namespace internal
1203 } // namespace v8 1156 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/mips/instruction-selector-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698