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 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
579 } | 579 } |
580 } | 580 } |
581 break; | 581 break; |
582 case kMips64Ror: | 582 case kMips64Ror: |
583 __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 583 __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
584 break; | 584 break; |
585 case kMips64Dror: | 585 case kMips64Dror: |
586 __ Dror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 586 __ Dror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
587 break; | 587 break; |
588 case kMips64Tst: | 588 case kMips64Tst: |
589 case kMips64Tst32: | |
590 // Pseudo-instruction used for cmp/branch. No opcode emitted here. | 589 // Pseudo-instruction used for cmp/branch. No opcode emitted here. |
591 break; | 590 break; |
592 case kMips64Cmp: | 591 case kMips64Cmp: |
593 case kMips64Cmp32: | |
594 // Pseudo-instruction used for cmp/branch. No opcode emitted here. | 592 // Pseudo-instruction used for cmp/branch. No opcode emitted here. |
595 break; | 593 break; |
596 case kMips64Mov: | 594 case kMips64Mov: |
597 // TODO(plind): Should we combine mov/li like this, or use separate instr? | 595 // TODO(plind): Should we combine mov/li like this, or use separate instr? |
598 // - Also see x64 ASSEMBLE_BINOP & RegisterOrOperandType | 596 // - Also see x64 ASSEMBLE_BINOP & RegisterOrOperandType |
599 if (HasRegisterInput(instr, 0)) { | 597 if (HasRegisterInput(instr, 0)) { |
600 __ mov(i.OutputRegister(), i.InputRegister(0)); | 598 __ mov(i.OutputRegister(), i.InputRegister(0)); |
601 } else { | 599 } else { |
602 __ li(i.OutputRegister(), i.InputOperand(0)); | 600 __ li(i.OutputRegister(), i.InputOperand(0)); |
603 } | 601 } |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
817 | 815 |
818 // Assembles branches after an instruction. | 816 // Assembles branches after an instruction. |
819 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 817 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
820 MipsOperandConverter i(this, instr); | 818 MipsOperandConverter i(this, instr); |
821 Label* tlabel = branch->true_label; | 819 Label* tlabel = branch->true_label; |
822 Label* flabel = branch->false_label; | 820 Label* flabel = branch->false_label; |
823 Condition cc = kNoCondition; | 821 Condition cc = kNoCondition; |
824 | 822 |
825 // MIPS does not have condition code flags, so compare and branch are | 823 // MIPS does not have condition code flags, so compare and branch are |
826 // implemented differently than on the other arch's. The compare operations | 824 // implemented differently than on the other arch's. The compare operations |
827 // emit mips psuedo-instructions, which are handled here by branch | 825 // emit mips psuedo-instructions, which are handled here by branch |
paul.l...
2015/03/13 17:05:31
nit: Here is another place I misspelled pseudo, pl
| |
828 // instructions that do the actual comparison. Essential that the input | 826 // instructions that do the actual comparison. Essential that the input |
829 // registers to compare psuedo-op are not modified before this branch op, as | 827 // registers to compare pseudo-op are not modified before this branch op, as |
830 // they are tested here. | 828 // they are tested here. |
831 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were | |
832 // not separated by other instructions. | |
833 | 829 |
834 if (instr->arch_opcode() == kMips64Tst) { | 830 if (instr->arch_opcode() == kMips64Tst) { |
835 cc = FlagsConditionToConditionTst(branch->condition); | 831 cc = FlagsConditionToConditionTst(branch->condition); |
836 __ And(at, i.InputRegister(0), i.InputOperand(1)); | 832 __ And(at, i.InputRegister(0), i.InputOperand(1)); |
837 __ Branch(tlabel, cc, at, Operand(zero_reg)); | 833 __ Branch(tlabel, cc, at, Operand(zero_reg)); |
838 } else if (instr->arch_opcode() == kMips64Tst32) { | |
839 cc = FlagsConditionToConditionTst(branch->condition); | |
840 // Zero-extend registers on MIPS64 only 64-bit operand | |
841 // branch and compare op. is available. | |
842 // This is a disadvantage to perform 32-bit operation on MIPS64. | |
843 // Try to force globally in front-end Word64 representation to be preferred | |
844 // for MIPS64 even for Word32. | |
845 __ And(at, i.InputRegister(0), i.InputOperand(1)); | |
846 __ Dext(at, at, 0, 32); | |
847 __ Branch(tlabel, cc, at, Operand(zero_reg)); | |
848 } else if (instr->arch_opcode() == kMips64Dadd || | 834 } else if (instr->arch_opcode() == kMips64Dadd || |
849 instr->arch_opcode() == kMips64Dsub) { | 835 instr->arch_opcode() == kMips64Dsub) { |
850 cc = FlagsConditionToConditionOvf(branch->condition); | 836 cc = FlagsConditionToConditionOvf(branch->condition); |
851 | 837 |
852 __ dsra32(kScratchReg, i.OutputRegister(), 0); | 838 __ dsra32(kScratchReg, i.OutputRegister(), 0); |
853 __ sra(at, i.OutputRegister(), 31); | 839 __ sra(at, i.OutputRegister(), 31); |
854 __ Branch(tlabel, cc, at, Operand(kScratchReg)); | 840 __ Branch(tlabel, cc, at, Operand(kScratchReg)); |
855 } else if (instr->arch_opcode() == kMips64Cmp) { | 841 } else if (instr->arch_opcode() == kMips64Cmp) { |
856 cc = FlagsConditionToConditionCmp(branch->condition); | 842 cc = FlagsConditionToConditionCmp(branch->condition); |
857 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); | 843 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); |
858 | 844 |
859 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. | 845 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. |
860 | |
861 } else if (instr->arch_opcode() == kMips64Cmp32) { | |
862 cc = FlagsConditionToConditionCmp(branch->condition); | |
863 | |
864 switch (branch->condition) { | |
865 case kEqual: | |
866 case kNotEqual: | |
867 case kSignedLessThan: | |
868 case kSignedGreaterThanOrEqual: | |
869 case kSignedLessThanOrEqual: | |
870 case kSignedGreaterThan: | |
871 // Sign-extend registers on MIPS64 only 64-bit operand | |
872 // branch and compare op. is available. | |
873 __ sll(i.InputRegister(0), i.InputRegister(0), 0); | |
874 if (instr->InputAt(1)->IsRegister()) { | |
875 __ sll(i.InputRegister(1), i.InputRegister(1), 0); | |
876 } | |
877 break; | |
878 case kUnsignedLessThan: | |
879 case kUnsignedGreaterThanOrEqual: | |
880 case kUnsignedLessThanOrEqual: | |
881 case kUnsignedGreaterThan: | |
882 // Zero-extend registers on MIPS64 only 64-bit operand | |
883 // branch and compare op. is available. | |
884 __ Dext(i.InputRegister(0), i.InputRegister(0), 0, 32); | |
885 if (instr->InputAt(1)->IsRegister()) { | |
886 __ Dext(i.InputRegister(1), i.InputRegister(1), 0, 32); | |
887 } | |
888 break; | |
889 default: | |
890 UNSUPPORTED_COND(kMips64Cmp, branch->condition); | |
891 break; | |
892 } | |
893 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); | |
894 | |
895 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. | |
896 } else if (instr->arch_opcode() == kMips64CmpD) { | 846 } else if (instr->arch_opcode() == kMips64CmpD) { |
897 // TODO(dusmil) optimize unordered checks to use less instructions | 847 // TODO(dusmil) optimize unordered checks to use less instructions |
898 // even if we have to unfold BranchF macro. | 848 // even if we have to unfold BranchF macro. |
899 Label* nan = flabel; | 849 Label* nan = flabel; |
900 switch (branch->condition) { | 850 switch (branch->condition) { |
901 case kEqual: | 851 case kEqual: |
902 cc = eq; | 852 cc = eq; |
903 break; | 853 break; |
904 case kNotEqual: | 854 case kNotEqual: |
905 cc = ne; | 855 cc = ne; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
959 | 909 |
960 // For materializations, we use delay slot to set the result true, and | 910 // For materializations, we use delay slot to set the result true, and |
961 // in the false case, where we fall through the branch, we reset the result | 911 // in the false case, where we fall through the branch, we reset the result |
962 // false. | 912 // false. |
963 | 913 |
964 if (instr->arch_opcode() == kMips64Tst) { | 914 if (instr->arch_opcode() == kMips64Tst) { |
965 cc = FlagsConditionToConditionTst(condition); | 915 cc = FlagsConditionToConditionTst(condition); |
966 __ And(at, i.InputRegister(0), i.InputOperand(1)); | 916 __ And(at, i.InputRegister(0), i.InputOperand(1)); |
967 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); | 917 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); |
968 __ li(result, Operand(1)); // In delay slot. | 918 __ li(result, Operand(1)); // In delay slot. |
969 } else if (instr->arch_opcode() == kMips64Tst32) { | |
970 cc = FlagsConditionToConditionTst(condition); | |
971 // Zero-extend register on MIPS64 only 64-bit operand | |
972 // branch and compare op. is available. | |
973 __ And(at, i.InputRegister(0), i.InputOperand(1)); | |
974 __ Dext(at, at, 0, 32); | |
975 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); | |
976 __ li(result, Operand(1)); // In delay slot. | |
977 } else if (instr->arch_opcode() == kMips64Dadd || | 919 } else if (instr->arch_opcode() == kMips64Dadd || |
978 instr->arch_opcode() == kMips64Dsub) { | 920 instr->arch_opcode() == kMips64Dsub) { |
979 cc = FlagsConditionToConditionOvf(condition); | 921 cc = FlagsConditionToConditionOvf(condition); |
980 __ dsra32(kScratchReg, i.OutputRegister(), 0); | 922 __ dsra32(kScratchReg, i.OutputRegister(), 0); |
981 __ sra(at, i.OutputRegister(), 31); | 923 __ sra(at, i.OutputRegister(), 31); |
982 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(kScratchReg)); | 924 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(kScratchReg)); |
983 __ li(result, Operand(1)); // In delay slot. | 925 __ li(result, Operand(1)); // In delay slot. |
984 } else if (instr->arch_opcode() == kMips64Cmp) { | 926 } else if (instr->arch_opcode() == kMips64Cmp) { |
985 Register left = i.InputRegister(0); | 927 Register left = i.InputRegister(0); |
986 Operand right = i.InputOperand(1); | 928 Operand right = i.InputOperand(1); |
987 cc = FlagsConditionToConditionCmp(condition); | 929 cc = FlagsConditionToConditionCmp(condition); |
988 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); | 930 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); |
989 __ li(result, Operand(1)); // In delay slot. | 931 __ li(result, Operand(1)); // In delay slot. |
990 } else if (instr->arch_opcode() == kMips64Cmp32) { | |
991 Register left = i.InputRegister(0); | |
992 Operand right = i.InputOperand(1); | |
993 cc = FlagsConditionToConditionCmp(condition); | |
994 | |
995 switch (condition) { | |
996 case kEqual: | |
997 case kNotEqual: | |
998 case kSignedLessThan: | |
999 case kSignedGreaterThanOrEqual: | |
1000 case kSignedLessThanOrEqual: | |
1001 case kSignedGreaterThan: | |
1002 // Sign-extend registers on MIPS64 only 64-bit operand | |
1003 // branch and compare op. is available. | |
1004 __ sll(left, left, 0); | |
1005 if (instr->InputAt(1)->IsRegister()) { | |
1006 __ sll(i.InputRegister(1), i.InputRegister(1), 0); | |
1007 } | |
1008 break; | |
1009 case kUnsignedLessThan: | |
1010 case kUnsignedGreaterThanOrEqual: | |
1011 case kUnsignedLessThanOrEqual: | |
1012 case kUnsignedGreaterThan: | |
1013 // Zero-extend registers on MIPS64 only 64-bit operand | |
1014 // branch and compare op. is available. | |
1015 __ Dext(left, left, 0, 32); | |
1016 if (instr->InputAt(1)->IsRegister()) { | |
1017 __ Dext(i.InputRegister(1), i.InputRegister(1), 0, 32); | |
1018 } | |
1019 break; | |
1020 default: | |
1021 UNSUPPORTED_COND(kMips64Cmp32, condition); | |
1022 break; | |
1023 } | |
1024 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); | |
1025 __ li(result, Operand(1)); // In delay slot. | |
1026 } else if (instr->arch_opcode() == kMips64CmpD) { | 932 } else if (instr->arch_opcode() == kMips64CmpD) { |
1027 FPURegister left = i.InputDoubleRegister(0); | 933 FPURegister left = i.InputDoubleRegister(0); |
1028 FPURegister right = i.InputDoubleRegister(1); | 934 FPURegister right = i.InputDoubleRegister(1); |
1029 | 935 |
1030 bool predicate; | 936 bool predicate; |
1031 FPUCondition cc = FlagsConditionToConditionCmpD(predicate, condition); | 937 FPUCondition cc = FlagsConditionToConditionCmpD(predicate, condition); |
1032 if (kArchVariant != kMips64r6) { | 938 if (kArchVariant != kMips64r6) { |
1033 __ li(result, Operand(1)); | 939 __ li(result, Operand(1)); |
1034 __ c(cc, D, left, right); | 940 __ c(cc, D, left, right); |
1035 if (predicate) { | 941 if (predicate) { |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1377 } | 1283 } |
1378 } | 1284 } |
1379 MarkLazyDeoptSite(); | 1285 MarkLazyDeoptSite(); |
1380 } | 1286 } |
1381 | 1287 |
1382 #undef __ | 1288 #undef __ |
1383 | 1289 |
1384 } // namespace compiler | 1290 } // namespace compiler |
1385 } // namespace internal | 1291 } // namespace internal |
1386 } // namespace v8 | 1292 } // namespace v8 |
OLD | NEW |