Chromium Code Reviews| Index: src/compiler/mips64/code-generator-mips64.cc |
| diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc |
| index c95522b4a98b7d6e71a8e5671e25e1e8f11ccd9b..9a2098746de5d51173b8b661426aa98befab4f1c 100644 |
| --- a/src/compiler/mips64/code-generator-mips64.cc |
| +++ b/src/compiler/mips64/code-generator-mips64.cc |
| @@ -200,27 +200,38 @@ class OutOfLineCeil final : public OutOfLineRound { |
| }; |
| -Condition FlagsConditionToConditionCmp(FlagsCondition condition) { |
| +Condition FlagsConditionToConditionCmp(bool& predicate, |
| + FlagsCondition condition) { |
| switch (condition) { |
| case kEqual: |
| + predicate = true; |
| return eq; |
| case kNotEqual: |
| + predicate = false; |
| return ne; |
| case kSignedLessThan: |
| + predicate = true; |
| return lt; |
| case kSignedGreaterThanOrEqual: |
| + predicate = false; |
| return ge; |
| case kSignedLessThanOrEqual: |
| + predicate = false; |
| return le; |
| case kSignedGreaterThan: |
| + predicate = true; |
| return gt; |
| case kUnsignedLessThan: |
| + predicate = true; |
| return lo; |
| case kUnsignedGreaterThanOrEqual: |
| + predicate = false; |
| return hs; |
| case kUnsignedLessThanOrEqual: |
| + predicate = false; |
| return ls; |
| case kUnsignedGreaterThan: |
| + predicate = true; |
| return hi; |
| case kUnorderedEqual: |
| case kUnorderedNotEqual: |
| @@ -233,11 +244,14 @@ Condition FlagsConditionToConditionCmp(FlagsCondition condition) { |
| } |
| -Condition FlagsConditionToConditionTst(FlagsCondition condition) { |
| +Condition FlagsConditionToConditionTst(bool& predicate, |
| + FlagsCondition condition) { |
| switch (condition) { |
| case kNotEqual: |
| + predicate = false; |
| return ne; |
| case kEqual: |
| + predicate = true; |
| return eq; |
| default: |
| break; |
| @@ -247,11 +261,14 @@ Condition FlagsConditionToConditionTst(FlagsCondition condition) { |
| } |
| -Condition FlagsConditionToConditionOvf(FlagsCondition condition) { |
| +Condition FlagsConditionToConditionOvf(bool& predicate, |
| + FlagsCondition condition) { |
| switch (condition) { |
| case kOverflow: |
| + predicate = true; |
| return ne; |
| case kNotOverflow: |
| + predicate = false; |
| return eq; |
| default: |
| break; |
| @@ -965,7 +982,7 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
| Label* tlabel = branch->true_label; |
| Label* flabel = branch->false_label; |
| Condition cc = kNoCondition; |
| - |
| + bool predicate; |
| // MIPS does not have condition code flags, so compare and branch are |
| // implemented differently than on the other arch's. The compare operations |
| // emit mips psuedo-instructions, which are handled here by branch |
| @@ -974,17 +991,17 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
| // they are tested here. |
| if (instr->arch_opcode() == kMips64Tst) { |
| - cc = FlagsConditionToConditionTst(branch->condition); |
| + cc = FlagsConditionToConditionTst(predicate, branch->condition); |
| __ And(at, i.InputRegister(0), i.InputOperand(1)); |
| __ Branch(tlabel, cc, at, Operand(zero_reg)); |
| } else if (instr->arch_opcode() == kMips64Dadd || |
| instr->arch_opcode() == kMips64Dsub) { |
| - cc = FlagsConditionToConditionOvf(branch->condition); |
| + cc = FlagsConditionToConditionOvf(predicate, branch->condition); |
| __ dsra32(kScratchReg, i.OutputRegister(), 0); |
| __ sra(at, i.OutputRegister(), 31); |
| __ Branch(tlabel, cc, at, Operand(kScratchReg)); |
| } else if (instr->arch_opcode() == kMips64Cmp) { |
| - cc = FlagsConditionToConditionCmp(branch->condition); |
| + cc = FlagsConditionToConditionCmp(predicate, branch->condition); |
| __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); |
| } else if (instr->arch_opcode() == kMips64CmpS) { |
| if (!convertCondition(branch->condition, cc)) { |
| @@ -1024,7 +1041,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
| DCHECK_NE(0u, instr->OutputCount()); |
| Register result = i.OutputRegister(instr->OutputCount() - 1); |
| Condition cc = kNoCondition; |
| - |
| + bool predicate; |
| // MIPS does not have condition code flags, so compare and branch are |
| // implemented differently than on the other arch's. The compare operations |
| // emit mips pseudo-instructions, which are checked and handled here. |
| @@ -1034,29 +1051,87 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
| // false. |
|
paul.l...
2015/08/15 00:22:31
With your change, the above comment should be dele
|
| if (instr->arch_opcode() == kMips64Tst) { |
| - cc = FlagsConditionToConditionTst(condition); |
| - __ And(at, i.InputRegister(0), i.InputOperand(1)); |
| - __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); |
| - __ li(result, Operand(1)); // In delay slot. |
| + cc = FlagsConditionToConditionTst(predicate, condition); |
| + __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1)); |
| + __ xori(kScratchReg2, zero_reg, 1); |
| + if (predicate) { |
| + __ Movn(result, zero_reg, kScratchReg); |
| + __ Movz(result, kScratchReg2, kScratchReg); |
|
paul.l...
2015/08/15 00:22:31
I'm not sure this is a good idea anymore, due to t
|
| + } else { |
| + __ Movz(result, zero_reg, kScratchReg); |
| + __ Movn(result, kScratchReg2, kScratchReg); |
| + } |
| + return; |
| } else if (instr->arch_opcode() == kMips64Dadd || |
| instr->arch_opcode() == kMips64Dsub) { |
| - cc = FlagsConditionToConditionOvf(condition); |
| - __ dsra32(kScratchReg, i.OutputRegister(), 0); |
| - __ sra(at, i.OutputRegister(), 31); |
| - __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(kScratchReg)); |
| - __ li(result, Operand(1)); // In delay slot. |
| + FlagsConditionToConditionOvf(predicate, condition); |
| + __ dsrl32(kScratchReg, i.OutputRegister(), 31); |
| + __ srl(at, i.OutputRegister(), 31); |
| + __ xor_(result, kScratchReg, at); |
| + if (!predicate) __ xori(result, result, 1); |
|
paul.l...
2015/08/15 00:22:31
OK, it must be too late on Friday night, but I am
|
| + return; |
| } else if (instr->arch_opcode() == kMips64Cmp) { |
| - Register left = i.InputRegister(0); |
| - Operand right = i.InputOperand(1); |
| - cc = FlagsConditionToConditionCmp(condition); |
| - __ Branch(USE_DELAY_SLOT, &done, cc, left, right); |
| - __ li(result, Operand(1)); // In delay slot. |
| + cc = FlagsConditionToConditionCmp(predicate, condition); |
| + switch (cc) { |
| + case eq: |
| + case ne: { |
| + Register left = i.InputRegister(0); |
| + Operand right = i.InputOperand(1); |
| + __ Dsubu(kScratchReg, left, right); |
| + __ xori(kScratchReg2, zero_reg, 1); |
| + if (predicate) { |
| + __ Movn(result, zero_reg, kScratchReg); |
| + __ Movz(result, kScratchReg2, kScratchReg); |
| + } else { |
| + __ Movz(result, zero_reg, kScratchReg); |
| + __ Movn(result, kScratchReg2, kScratchReg); |
| + } |
| + } break; |
| + case lt: |
| + case ge: { |
| + Register left = i.InputRegister(0); |
| + Operand right = i.InputOperand(1); |
| + __ Slt(result, left, right); |
| + if (!predicate) { |
| + __ xori(result, result, 1); |
| + } |
| + } break; |
| + case gt: |
| + case le: { |
| + Register left = i.InputRegister(1); |
| + Operand right = i.InputOperand(0); |
| + __ Slt(result, left, right); |
| + if (!predicate) { |
| + __ xori(result, result, 1); |
| + } |
| + } break; |
| + case lo: |
| + case hs: { |
| + Register left = i.InputRegister(0); |
| + Operand right = i.InputOperand(1); |
| + __ Sltu(result, left, right); |
| + if (!predicate) { |
| + __ xori(result, result, 1); |
| + } |
| + } break; |
| + case hi: |
| + case ls: { |
| + Register left = i.InputRegister(1); |
| + Operand right = i.InputOperand(0); |
| + __ Sltu(result, left, right); |
| + if (!predicate) { |
| + __ xori(result, result, 1); |
| + } |
| + } break; |
| + default: |
| + UNREACHABLE(); |
| + } |
| + return; |
| } else if (instr->arch_opcode() == kMips64CmpD || |
| instr->arch_opcode() == kMips64CmpS) { |
| FPURegister left = i.InputDoubleRegister(0); |
| FPURegister right = i.InputDoubleRegister(1); |
| - bool predicate; |
| FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition); |
| if (kArchVariant != kMips64r6) { |
| __ li(result, Operand(1)); |
| @@ -1090,10 +1165,6 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
| TRACE_UNIMPL(); |
| UNIMPLEMENTED(); |
| } |
| - // Fallthru case is the false materialization. |
| - __ bind(&false_value); |
| - __ li(result, Operand(static_cast<int64_t>(0))); |
| - __ bind(&done); |
| } |