Index: src/compiler/s390/instruction-selector-s390.cc |
diff --git a/src/compiler/s390/instruction-selector-s390.cc b/src/compiler/s390/instruction-selector-s390.cc |
index e8da557d80ea0afab87910672e51d41673a022f2..c2c35b01276b92f776e1fbec8a8e4752a3e412a5 100644 |
--- a/src/compiler/s390/instruction-selector-s390.cc |
+++ b/src/compiler/s390/instruction-selector-s390.cc |
@@ -919,6 +919,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) { |
+ S390OperandGenerator 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(kS390_Mul32WithHigh32, 2, outputs, 2, inputs); |
+ } |
+ { |
+ InstructionOperand shift_31 = g.UseImmediate(31); |
+ InstructionOperand outputs[] = {temp_operand}; |
+ InstructionOperand inputs[] = {result_operand, shift_31}; |
+ selector->Emit(kS390_ShiftRightArith32, 1, outputs, 2, inputs); |
+ } |
+ |
+ VisitCompare(selector, kS390_Cmp32, high32_operand, temp_operand, cont); |
+} |
+ |
+} // namespace |
+ |
void InstructionSelector::VisitInt32Mul(Node* node) { |
VisitRRR(this, kS390_Mul32, node); |
} |
@@ -1487,6 +1517,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
return VisitBinop<Int32BinopMatcher>(selector, node, |
kS390_SubWithOverflow32, |
kInt16Imm_Negate, cont); |
+ case IrOpcode::kInt32MulWithOverflow: |
+ cont->OverwriteAndNegateIfEqual(kNotEqual); |
+ return EmitInt32MulWithOverflow(selector, node, cont); |
#if V8_TARGET_ARCH_S390X |
case IrOpcode::kInt64AddWithOverflow: |
cont->OverwriteAndNegateIfEqual(kOverflow); |
@@ -1666,6 +1699,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); |
VisitFloat32Compare(this, node, &cont); |