Index: src/compiler/ppc/instruction-selector-ppc.cc |
diff --git a/src/compiler/ppc/instruction-selector-ppc.cc b/src/compiler/ppc/instruction-selector-ppc.cc |
index 85eeb2c2a1d33178fecff159eb80510fc55a8b3b..65e36aa7e48295cb727dd7e3d55342ceb9b6d06b 100644 |
--- a/src/compiler/ppc/instruction-selector-ppc.cc |
+++ b/src/compiler/ppc/instruction-selector-ppc.cc |
@@ -989,6 +989,36 @@ void InstructionSelector::VisitInt64Sub(Node* node) { |
} |
#endif |
+namespace { |
+ |
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
+ InstructionOperand left, InstructionOperand right, |
+ FlagsContinuation* cont); |
+void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node, |
+ FlagsContinuation* cont) { |
+ PPCOperandGenerator g(selector); |
+ Int32BinopMatcher m(node); |
+ InstructionOperand result_operand = g.DefineAsRegister(node); |
+ InstructionOperand high32_operand = g.TempRegister(); |
+ InstructionOperand temp_operand = g.TempRegister(); |
+ { |
+ InstructionOperand outputs[] = {result_operand, high32_operand}; |
+ InstructionOperand inputs[] = {g.UseRegister(m.left().node()), |
+ g.UseRegister(m.right().node())}; |
+ selector->Emit(kPPC_Mul32WithHigh32, 2, outputs, 2, inputs); |
+ } |
+ { |
+ InstructionOperand shift_31 = g.UseImmediate(31); |
+ InstructionOperand outputs[] = {temp_operand}; |
+ InstructionOperand inputs[] = {result_operand, shift_31}; |
+ selector->Emit(kPPC_ShiftRightAlg32, 1, outputs, 2, inputs); |
+ } |
+ |
+ VisitCompare(selector, kPPC_Cmp32, high32_operand, temp_operand, cont); |
+} |
+ |
+} // namespace |
+ |
void InstructionSelector::VisitInt32Mul(Node* node) { |
VisitRRR(this, kPPC_Mul32, node); |
@@ -1626,6 +1656,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
return VisitBinop<Int32BinopMatcher>(selector, node, |
kPPC_SubWithOverflow32, |
kInt16Imm_Negate, cont); |
+ case IrOpcode::kInt32MulWithOverflow: |
+ cont->OverwriteAndNegateIfEqual(kNotEqual); |
+ return EmitInt32MulWithOverflow(selector, node, cont); |
#if V8_TARGET_ARCH_PPC64 |
case IrOpcode::kInt64AddWithOverflow: |
cont->OverwriteAndNegateIfEqual(kOverflow); |
@@ -1820,6 +1853,15 @@ void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { |
} |
#endif |
+void InstructionSelector::VisitInt32MulWithOverflow(Node* node) { |
+ if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf); |
+ return EmitInt32MulWithOverflow(this, node, &cont); |
+ } |
+ FlagsContinuation cont; |
+ EmitInt32MulWithOverflow(this, node, &cont); |
+} |
+ |
void InstructionSelector::VisitFloat32Equal(Node* node) { |
FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); |