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:
jyan 2016-07-15 11:45:59 -07:00 committed by Commit bot
parent 9c59539f27
commit a151ea9e7c
4 changed files with 55 additions and 0 deletions

View File

@ -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));

View File

@ -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) \

View File

@ -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:

View File

@ -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);