S390: [turbofan] Introduce integer multiplication with overflow.
port 8e18a5f2a0
R=bjaideep@ca.ibm.com, mvstanton@chromium.org, joransiu@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com
BUG=
Review-Url: https://codereview.chromium.org/2153913002
Cr-Commit-Position: refs/heads/master@{#37804}
This commit is contained in:
parent
9c59539f27
commit
a151ea9e7c
@ -727,6 +727,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode());
|
||||
|
||||
switch (opcode) {
|
||||
case kArchComment: {
|
||||
Address comment_string = i.InputExternalReference(0).address();
|
||||
__ RecordComment(reinterpret_cast<const char*>(comment_string));
|
||||
break;
|
||||
}
|
||||
case kArchCallCodeObject: {
|
||||
EnsureSpaceForLazyDeopt();
|
||||
if (HasRegisterInput(instr, 0)) {
|
||||
@ -1218,6 +1223,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
__ mr_z(r0, i.InputRegister(1));
|
||||
__ LoadW(i.OutputRegister(), r0);
|
||||
break;
|
||||
case kS390_Mul32WithHigh32:
|
||||
__ LoadRR(r1, i.InputRegister(0));
|
||||
__ mr_z(r0, i.InputRegister(1));
|
||||
__ LoadW(i.OutputRegister(0), r1); // low
|
||||
__ LoadW(i.OutputRegister(1), r0); // high
|
||||
break;
|
||||
case kS390_MulHighU32:
|
||||
__ LoadRR(r1, i.InputRegister(0));
|
||||
__ mlr(r0, i.InputRegister(1));
|
||||
|
@ -45,6 +45,7 @@ namespace compiler {
|
||||
V(S390_SubPair) \
|
||||
V(S390_MulPair) \
|
||||
V(S390_Mul32) \
|
||||
V(S390_Mul32WithHigh32) \
|
||||
V(S390_Mul64) \
|
||||
V(S390_MulHigh32) \
|
||||
V(S390_MulHighU32) \
|
||||
|
@ -46,6 +46,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
|
||||
case kS390_SubFloat:
|
||||
case kS390_SubDouble:
|
||||
case kS390_Mul32:
|
||||
case kS390_Mul32WithHigh32:
|
||||
case kS390_Mul64:
|
||||
case kS390_MulHigh32:
|
||||
case kS390_MulHighU32:
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user