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/compiler/osr.h" | 9 #include "src/compiler/osr.h" |
10 #include "src/mips/macro-assembler-mips.h" | 10 #include "src/mips/macro-assembler-mips.h" |
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 DCHECK_NE(0u, instr->OutputCount()); | 961 DCHECK_NE(0u, instr->OutputCount()); |
962 Register result = i.OutputRegister(instr->OutputCount() - 1); | 962 Register result = i.OutputRegister(instr->OutputCount() - 1); |
963 Condition cc = kNoCondition; | 963 Condition cc = kNoCondition; |
964 // MIPS does not have condition code flags, so compare and branch are | 964 // MIPS does not have condition code flags, so compare and branch are |
965 // implemented differently than on the other arch's. The compare operations | 965 // implemented differently than on the other arch's. The compare operations |
966 // emit mips psuedo-instructions, which are checked and handled here. | 966 // emit mips psuedo-instructions, which are checked and handled here. |
967 | 967 |
968 if (instr->arch_opcode() == kMipsTst) { | 968 if (instr->arch_opcode() == kMipsTst) { |
969 cc = FlagsConditionToConditionTst(condition); | 969 cc = FlagsConditionToConditionTst(condition); |
970 __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1)); | 970 __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1)); |
971 __ xori(result, zero_reg, 1); // Create 1 for true. | 971 __ Sltu(result, zero_reg, kScratchReg); |
972 if (IsMipsArchVariant(kMips32r6)) { | 972 if (cc == eq) { |
973 if (cc == eq) { | 973 // Sltu produces 0 for equality, invert the result. |
974 __ seleqz(result, result, kScratchReg); | 974 __ xori(result, result, 1); |
975 } else { | |
976 __ selnez(result, result, kScratchReg); | |
977 } | |
978 } else { | |
979 if (cc == eq) { | |
980 __ Movn(result, zero_reg, kScratchReg); | |
981 } else { | |
982 __ Movz(result, zero_reg, kScratchReg); | |
983 } | |
984 } | 975 } |
985 return; | 976 return; |
986 } else if (instr->arch_opcode() == kMipsAddOvf || | 977 } else if (instr->arch_opcode() == kMipsAddOvf || |
987 instr->arch_opcode() == kMipsSubOvf) { | 978 instr->arch_opcode() == kMipsSubOvf) { |
988 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. | 979 // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow. |
989 cc = FlagsConditionToConditionOvf(condition); | 980 cc = FlagsConditionToConditionOvf(condition); |
990 // Return 1 on overflow. | 981 // Return 1 on overflow. |
991 __ Slt(result, kCompareReg, Operand(zero_reg)); | 982 __ Slt(result, kCompareReg, Operand(zero_reg)); |
992 if (cc == ge) // Invert result on not overflow. | 983 if (cc == ge) // Invert result on not overflow. |
993 __ xori(result, result, 1); | 984 __ xori(result, result, 1); |
994 return; | 985 return; |
995 } else if (instr->arch_opcode() == kMipsCmp) { | 986 } else if (instr->arch_opcode() == kMipsCmp) { |
996 cc = FlagsConditionToConditionCmp(condition); | 987 cc = FlagsConditionToConditionCmp(condition); |
997 switch (cc) { | 988 switch (cc) { |
998 case eq: | 989 case eq: |
999 case ne: { | 990 case ne: { |
1000 Register left = i.InputRegister(0); | 991 Register left = i.InputRegister(0); |
1001 Operand right = i.InputOperand(1); | 992 Operand right = i.InputOperand(1); |
1002 __ Subu(kScratchReg, left, right); | 993 Register select; |
1003 __ xori(result, zero_reg, 1); | 994 if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) { |
1004 if (IsMipsArchVariant(kMips32r6)) { | 995 // Pass left operand if right is zero. |
1005 if (cc == eq) { | 996 select = left; |
1006 __ seleqz(result, result, kScratchReg); | |
1007 } else { | |
1008 __ selnez(result, result, kScratchReg); | |
1009 } | |
1010 } else { | 997 } else { |
1011 if (cc == eq) { | 998 __ Subu(kScratchReg, left, right); |
1012 __ Movn(result, zero_reg, kScratchReg); | 999 select = kScratchReg; |
1013 } else { | 1000 } |
1014 __ Movz(result, zero_reg, kScratchReg); | 1001 __ Sltu(result, zero_reg, select); |
1015 } | 1002 if (cc == eq) { |
| 1003 // Sltu produces 0 for equality, invert the result. |
| 1004 __ xori(result, result, 1); |
1016 } | 1005 } |
1017 } break; | 1006 } break; |
1018 case lt: | 1007 case lt: |
1019 case ge: { | 1008 case ge: { |
1020 Register left = i.InputRegister(0); | 1009 Register left = i.InputRegister(0); |
1021 Operand right = i.InputOperand(1); | 1010 Operand right = i.InputOperand(1); |
1022 __ Slt(result, left, right); | 1011 __ Slt(result, left, right); |
1023 if (cc == ge) { | 1012 if (cc == ge) { |
1024 __ xori(result, result, 1); | 1013 __ xori(result, result, 1); |
1025 } | 1014 } |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 padding_size -= v8::internal::Assembler::kInstrSize; | 1429 padding_size -= v8::internal::Assembler::kInstrSize; |
1441 } | 1430 } |
1442 } | 1431 } |
1443 } | 1432 } |
1444 | 1433 |
1445 #undef __ | 1434 #undef __ |
1446 | 1435 |
1447 } // namespace compiler | 1436 } // namespace compiler |
1448 } // namespace internal | 1437 } // namespace internal |
1449 } // namespace v8 | 1438 } // namespace v8 |
OLD | NEW |