OLD | NEW |
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/mips/macro-assembler-mips.h" | 9 #include "src/mips/macro-assembler-mips.h" |
10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 break; | 780 break; |
781 } | 781 } |
782 } | 782 } |
783 | 783 |
784 | 784 |
785 #define UNSUPPORTED_COND(opcode, condition) \ | 785 #define UNSUPPORTED_COND(opcode, condition) \ |
786 OFStream out(stdout); \ | 786 OFStream out(stdout); \ |
787 out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \ | 787 out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \ |
788 UNIMPLEMENTED(); | 788 UNIMPLEMENTED(); |
789 | 789 |
| 790 static bool convertCondition(FlagsCondition condition, Condition& cc, |
| 791 bool& acceptNaN) { |
| 792 acceptNaN = false; |
| 793 switch (condition) { |
| 794 case kEqual: |
| 795 cc = eq; |
| 796 return true; |
| 797 case kNotEqual: |
| 798 cc = ne; |
| 799 acceptNaN = true; |
| 800 return true; |
| 801 case kUnsignedLessThan: |
| 802 cc = lt; |
| 803 return true; |
| 804 case kUnsignedGreaterThanOrEqual: |
| 805 cc = ge; |
| 806 acceptNaN = true; |
| 807 return true; |
| 808 case kUnsignedLessThanOrEqual: |
| 809 cc = le; |
| 810 return true; |
| 811 case kUnsignedGreaterThan: |
| 812 cc = gt; |
| 813 acceptNaN = true; |
| 814 return true; |
| 815 default: |
| 816 break; |
| 817 } |
| 818 return false; |
| 819 } |
| 820 |
| 821 |
790 // Assembles branches after an instruction. | 822 // Assembles branches after an instruction. |
791 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 823 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
792 MipsOperandConverter i(this, instr); | 824 MipsOperandConverter i(this, instr); |
793 Label* tlabel = branch->true_label; | 825 Label* tlabel = branch->true_label; |
794 Label* flabel = branch->false_label; | 826 Label* flabel = branch->false_label; |
795 Condition cc = kNoCondition; | 827 Condition cc = kNoCondition; |
796 | 828 |
797 // MIPS does not have condition code flags, so compare and branch are | 829 // MIPS does not have condition code flags, so compare and branch are |
798 // implemented differently than on the other arch's. The compare operations | 830 // implemented differently than on the other arch's. The compare operations |
799 // emit mips pseudo-instructions, which are handled here by branch | 831 // emit mips pseudo-instructions, which are handled here by branch |
(...skipping 16 matching lines...) Expand all Loading... |
816 | 848 |
817 } else if (instr->arch_opcode() == kMipsCmp) { | 849 } else if (instr->arch_opcode() == kMipsCmp) { |
818 cc = FlagsConditionToConditionCmp(branch->condition); | 850 cc = FlagsConditionToConditionCmp(branch->condition); |
819 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); | 851 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); |
820 | 852 |
821 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. | 853 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. |
822 | 854 |
823 } else if (instr->arch_opcode() == kMipsCmpS) { | 855 } else if (instr->arch_opcode() == kMipsCmpS) { |
824 // TODO(dusmil) optimize unordered checks to use fewer instructions | 856 // TODO(dusmil) optimize unordered checks to use fewer instructions |
825 // even if we have to unfold BranchF macro. | 857 // even if we have to unfold BranchF macro. |
826 Label* nan = flabel; | 858 bool acceptNaN = false; |
827 switch (branch->condition) { | 859 if (!convertCondition(branch->condition, cc, acceptNaN)) { |
828 case kEqual: | 860 UNSUPPORTED_COND(kMips64CmpS, branch->condition); |
829 cc = eq; | |
830 break; | |
831 case kNotEqual: | |
832 cc = ne; | |
833 nan = tlabel; | |
834 break; | |
835 case kUnsignedLessThan: | |
836 cc = lt; | |
837 break; | |
838 case kUnsignedGreaterThanOrEqual: | |
839 cc = ge; | |
840 nan = tlabel; | |
841 break; | |
842 case kUnsignedLessThanOrEqual: | |
843 cc = le; | |
844 break; | |
845 case kUnsignedGreaterThan: | |
846 cc = gt; | |
847 nan = tlabel; | |
848 break; | |
849 default: | |
850 UNSUPPORTED_COND(kMipsCmpS, branch->condition); | |
851 break; | |
852 } | 861 } |
853 __ BranchFS(tlabel, nan, cc, i.InputDoubleRegister(0), | 862 Label* nan = acceptNaN ? tlabel : flabel; |
854 i.InputDoubleRegister(1)); | 863 __ BranchFS(tlabel, nan, cc, i.InputSingleRegister(0), |
| 864 i.InputSingleRegister(1)); |
855 | 865 |
856 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. | 866 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. |
857 | 867 |
858 } else if (instr->arch_opcode() == kMipsCmpD) { | 868 } else if (instr->arch_opcode() == kMipsCmpD) { |
859 // TODO(dusmil) optimize unordered checks to use fewer instructions | 869 // TODO(dusmil) optimize unordered checks to use fewer instructions |
860 // even if we have to unfold BranchF macro. | 870 // even if we have to unfold BranchF macro. |
861 Label* nan = flabel; | 871 bool acceptNaN = false; |
862 switch (branch->condition) { | 872 if (!convertCondition(branch->condition, cc, acceptNaN)) { |
863 case kEqual: | 873 UNSUPPORTED_COND(kMips64CmpD, branch->condition); |
864 cc = eq; | |
865 break; | |
866 case kNotEqual: | |
867 cc = ne; | |
868 nan = tlabel; | |
869 break; | |
870 case kUnsignedLessThan: | |
871 cc = lt; | |
872 break; | |
873 case kUnsignedGreaterThanOrEqual: | |
874 cc = ge; | |
875 nan = tlabel; | |
876 break; | |
877 case kUnsignedLessThanOrEqual: | |
878 cc = le; | |
879 break; | |
880 case kUnsignedGreaterThan: | |
881 cc = gt; | |
882 nan = tlabel; | |
883 break; | |
884 default: | |
885 UNSUPPORTED_COND(kMipsCmpD, branch->condition); | |
886 break; | |
887 } | 874 } |
| 875 Label* nan = acceptNaN ? tlabel : flabel; |
888 __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0), | 876 __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0), |
889 i.InputDoubleRegister(1)); | 877 i.InputDoubleRegister(1)); |
890 | 878 |
891 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. | 879 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. |
892 | 880 |
893 } else { | 881 } else { |
894 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n", | 882 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n", |
895 instr->arch_opcode()); | 883 instr->arch_opcode()); |
896 UNIMPLEMENTED(); | 884 UNIMPLEMENTED(); |
897 } | 885 } |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1296 } | 1284 } |
1297 } | 1285 } |
1298 MarkLazyDeoptSite(); | 1286 MarkLazyDeoptSite(); |
1299 } | 1287 } |
1300 | 1288 |
1301 #undef __ | 1289 #undef __ |
1302 | 1290 |
1303 } // namespace compiler | 1291 } // namespace compiler |
1304 } // namespace internal | 1292 } // namespace internal |
1305 } // namespace v8 | 1293 } // namespace v8 |
OLD | NEW |