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

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: 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 break;
paul.l... 2015/01/13 17:34:57 Please remove the unnecessary break's after the re
balazs.kilvady 2015/01/13 18:23:40 Done.
212 case kNotEqual:
213 return ne;
214 break;
215 case kSignedLessThan:
216 return lt;
217 break;
218 case kSignedGreaterThanOrEqual:
219 return ge;
220 break;
221 case kSignedLessThanOrEqual:
222 return le;
223 break;
224 case kSignedGreaterThan:
225 return gt;
226 break;
227 case kUnsignedLessThan:
228 return lo;
229 break;
230 case kUnsignedGreaterThanOrEqual:
231 return hs;
232 break;
233 case kUnsignedLessThanOrEqual:
234 return ls;
235 break;
236 case kUnsignedGreaterThan:
237 return hi;
238 break;
239 default:
240 break;
241 }
242 UNREACHABLE();
243 return kNoCondition;
244 }
245
246
247 Condition FlagsConditionToConditionTst(FlagsCondition condition) {
248 switch (condition) {
249 case kNotEqual:
250 return ne;
251 break;
252 case kEqual:
253 return eq;
254 break;
255 default:
256 break;
257 }
258 UNREACHABLE();
259 return kNoCondition;
260 }
261
262
263 Condition FlagsConditionToConditionOvf(FlagsCondition condition) {
264 switch (condition) {
265 case kOverflow:
266 return lt;
267 break;
268 case kNotOverflow:
269 return ge;
270 break;
271 default:
272 break;
273 }
274 UNREACHABLE();
275 return kNoCondition;
276 }
277
206 } // namespace 278 } // namespace
207 279
208 280
209 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ 281 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \
210 do { \ 282 do { \
211 auto result = i.Output##width##Register(); \ 283 auto result = i.Output##width##Register(); \
212 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ 284 auto ool = new (zone()) OutOfLineLoad##width(this, result); \
213 if (instr->InputAt(0)->IsRegister()) { \ 285 if (instr->InputAt(0)->IsRegister()) { \
214 auto offset = i.InputRegister(0); \ 286 auto offset = i.InputRegister(0); \
215 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ 287 __ 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 711 // MIPS does not have condition code flags, so compare and branch are
640 // implemented differently than on the other arch's. The compare operations 712 // implemented differently than on the other arch's. The compare operations
641 // emit mips pseudo-instructions, which are handled here by branch 713 // emit mips pseudo-instructions, which are handled here by branch
642 // instructions that do the actual comparison. Essential that the input 714 // instructions that do the actual comparison. Essential that the input
643 // registers to compare pseudo-op are not modified before this branch op, as 715 // registers to compare pseudo-op are not modified before this branch op, as
644 // they are tested here. 716 // they are tested here.
645 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were 717 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
646 // not separated by other instructions. 718 // not separated by other instructions.
647 719
648 if (instr->arch_opcode() == kMipsTst) { 720 if (instr->arch_opcode() == kMipsTst) {
649 switch (branch->condition) { 721 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)); 722 __ And(at, i.InputRegister(0), i.InputOperand(1));
661 __ Branch(tlabel, cc, at, Operand(zero_reg)); 723 __ Branch(tlabel, cc, at, Operand(zero_reg));
662 724
663 } else if (instr->arch_opcode() == kMipsAddOvf || 725 } else if (instr->arch_opcode() == kMipsAddOvf ||
664 instr->arch_opcode() == kMipsSubOvf) { 726 instr->arch_opcode() == kMipsSubOvf) {
665 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow. 727 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow.
666 switch (branch->condition) { 728 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)); 729 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg));
678 730
679 } else if (instr->arch_opcode() == kMipsCmp) { 731 } else if (instr->arch_opcode() == kMipsCmp) {
680 switch (branch->condition) { 732 cc = FlagsConditionToConditionCmp(branch->condition);
681 case kEqual: 733 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
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));
716 734
717 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. 735 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel.
718 736
719 } else if (instr->arch_opcode() == kMipsCmpD) { 737 } else if (instr->arch_opcode() == kMipsCmpD) {
720 // TODO(dusmil) optimize unordered checks to use fewer instructions 738 // TODO(dusmil) optimize unordered checks to use fewer instructions
721 // even if we have to unfold BranchF macro. 739 // even if we have to unfold BranchF macro.
722 Label* nan = flabel; 740 Label* nan = flabel;
723 switch (branch->condition) { 741 switch (branch->condition) {
724 case kUnorderedEqual: 742 case kEqual:
725 cc = eq; 743 cc = eq;
726 break; 744 break;
727 case kUnorderedNotEqual: 745 case kNotEqual:
728 cc = ne; 746 cc = ne;
729 nan = tlabel; 747 nan = tlabel;
730 break; 748 break;
731 case kUnorderedLessThan: 749 case kUnsignedLessThan:
732 cc = lt; 750 cc = lt;
733 break; 751 break;
734 case kUnorderedGreaterThanOrEqual: 752 case kUnsignedGreaterThanOrEqual:
735 cc = ge; 753 cc = ge;
736 nan = tlabel; 754 nan = tlabel;
737 break; 755 break;
738 case kUnorderedLessThanOrEqual: 756 case kUnsignedLessThanOrEqual:
739 cc = le; 757 cc = le;
740 break; 758 break;
741 case kUnorderedGreaterThan: 759 case kUnsignedGreaterThan:
742 cc = gt; 760 cc = gt;
743 nan = tlabel; 761 nan = tlabel;
744 break; 762 break;
745 default: 763 default:
746 UNSUPPORTED_COND(kMipsCmpD, branch->condition); 764 UNSUPPORTED_COND(kMipsCmpD, branch->condition);
747 break; 765 break;
748 } 766 }
749 __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0), 767 __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0),
750 i.InputDoubleRegister(1)); 768 i.InputDoubleRegister(1));
751 769
(...skipping 29 matching lines...) Expand all
781 // implemented differently than on the other arch's. The compare operations 799 // implemented differently than on the other arch's. The compare operations
782 // emit mips psuedo-instructions, which are checked and handled here. 800 // emit mips psuedo-instructions, which are checked and handled here.
783 801
784 // For materializations, we use delay slot to set the result true, and 802 // 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 803 // in the false case, where we fall thru the branch, we reset the result
786 // false. 804 // false.
787 805
788 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were 806 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
789 // not separated by other instructions. 807 // not separated by other instructions.
790 if (instr->arch_opcode() == kMipsTst) { 808 if (instr->arch_opcode() == kMipsTst) {
791 switch (condition) { 809 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)); 810 __ And(at, i.InputRegister(0), i.InputOperand(1));
803 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); 811 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
804 __ li(result, Operand(1)); // In delay slot. 812 __ li(result, Operand(1)); // In delay slot.
805 813
806 } else if (instr->arch_opcode() == kMipsAddOvf || 814 } else if (instr->arch_opcode() == kMipsAddOvf ||
807 instr->arch_opcode() == kMipsSubOvf) { 815 instr->arch_opcode() == kMipsSubOvf) {
808 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. 816 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow.
809 switch (condition) { 817 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)); 818 __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg));
821 __ li(result, Operand(1)); // In delay slot. 819 __ li(result, Operand(1)); // In delay slot.
822 820
823 821
824 } else if (instr->arch_opcode() == kMipsCmp) { 822 } else if (instr->arch_opcode() == kMipsCmp) {
825 Register left = i.InputRegister(0); 823 Register left = i.InputRegister(0);
826 Operand right = i.InputOperand(1); 824 Operand right = i.InputOperand(1);
827 switch (condition) { 825 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); 826 __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
863 __ li(result, Operand(1)); // In delay slot. 827 __ li(result, Operand(1)); // In delay slot.
864 828
865 } else if (instr->arch_opcode() == kMipsCmpD) { 829 } else if (instr->arch_opcode() == kMipsCmpD) {
866 FPURegister left = i.InputDoubleRegister(0); 830 FPURegister left = i.InputDoubleRegister(0);
867 FPURegister right = i.InputDoubleRegister(1); 831 FPURegister right = i.InputDoubleRegister(1);
868 // TODO(plind): Provide NaN-testing macro-asm function without need for 832 // TODO(plind): Provide NaN-testing macro-asm function without need for
869 // BranchF. 833 // BranchF.
870 FPURegister dummy1 = f0; 834 FPURegister dummy1 = f0;
871 FPURegister dummy2 = f2; 835 FPURegister dummy2 = f2;
872 switch (condition) { 836 switch (condition) {
873 case kUnorderedEqual: 837 case kEqual:
874 // TODO(plind): improve the NaN testing throughout this function. 838 // TODO(plind): improve the NaN testing throughout this function.
875 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); 839 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
876 cc = eq; 840 cc = eq;
877 break; 841 break;
878 case kUnorderedNotEqual: 842 case kNotEqual:
879 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); 843 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
880 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. 844 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
881 cc = ne; 845 cc = ne;
882 break; 846 break;
883 case kUnorderedLessThan: 847 case kUnsignedLessThan:
884 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); 848 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
885 cc = lt; 849 cc = lt;
886 break; 850 break;
887 case kUnorderedGreaterThanOrEqual: 851 case kUnsignedGreaterThanOrEqual:
888 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); 852 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
889 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. 853 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
890 cc = ge; 854 cc = ge;
891 break; 855 break;
892 case kUnorderedLessThanOrEqual: 856 case kUnsignedLessThanOrEqual:
893 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2); 857 __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
894 cc = le; 858 cc = le;
895 break; 859 break;
896 case kUnorderedGreaterThan: 860 case kUnsignedGreaterThan:
897 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2); 861 __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
898 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN. 862 __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
899 cc = gt; 863 cc = gt;
900 break; 864 break;
901 default: 865 default:
902 UNSUPPORTED_COND(kMipsCmp, condition); 866 UNSUPPORTED_COND(kMipsCmp, condition);
903 break; 867 break;
904 } 868 }
905 __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right); 869 __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right);
906 __ li(result, Operand(1)); // In delay slot - branch taken returns 1. 870 __ li(result, Operand(1)); // In delay slot - branch taken returns 1.
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 } 1158 }
1195 } 1159 }
1196 MarkLazyDeoptSite(); 1160 MarkLazyDeoptSite();
1197 } 1161 }
1198 1162
1199 #undef __ 1163 #undef __
1200 1164
1201 } // namespace compiler 1165 } // namespace compiler
1202 } // namespace internal 1166 } // namespace internal
1203 } // namespace v8 1167 } // 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