PPC: [turbofan] Introduce integer multiplication with overflow.

Port 8e18a5f2a0

R=mvstanton@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com

BUG=

Review-Url: https://codereview.chromium.org/2152363002
Cr-Commit-Position: refs/heads/master@{#37812}
This commit is contained in:
bjaideep 2016-07-17 20:40:08 -07:00 committed by Commit bot
parent 2aa2b652af
commit f6c45c5243
4 changed files with 67 additions and 0 deletions

View File

@ -975,6 +975,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchPrepareTailCall:
AssemblePrepareTailCall();
break;
case kArchComment: {
Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string));
break;
}
case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode());
if (instr->InputAt(0)->IsImmediate()) {
@ -1300,6 +1305,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
LeaveOE, i.OutputRCBit());
break;
#endif
case kPPC_Mul32WithHigh32:
if (i.OutputRegister(0).is(i.InputRegister(0)) ||
i.OutputRegister(0).is(i.InputRegister(1)) ||
i.OutputRegister(1).is(i.InputRegister(0)) ||
i.OutputRegister(1).is(i.InputRegister(1))) {
__ mullw(kScratchReg,
i.InputRegister(0), i.InputRegister(1)); // low
__ mulhw(i.OutputRegister(1),
i.InputRegister(0), i.InputRegister(1)); // high
__ mr(i.OutputRegister(0), kScratchReg);
} else {
__ mullw(i.OutputRegister(0),
i.InputRegister(0), i.InputRegister(1)); // low
__ mulhw(i.OutputRegister(1),
i.InputRegister(0), i.InputRegister(1)); // high
}
break;
case kPPC_MulHigh32:
__ mulhw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
i.OutputRCBit());

View File

@ -42,6 +42,7 @@ namespace compiler {
V(PPC_SubPair) \
V(PPC_SubDouble) \
V(PPC_Mul32) \
V(PPC_Mul32WithHigh32) \
V(PPC_Mul64) \
V(PPC_MulHigh32) \
V(PPC_MulHighU32) \

View File

@ -44,6 +44,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_SubPair:
case kPPC_SubDouble:
case kPPC_Mul32:
case kPPC_Mul32WithHigh32:
case kPPC_Mul64:
case kPPC_MulHigh32:
case kPPC_MulHighU32:

View File

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