Chromium Code Reviews| 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 |