Commit f6c45c52 authored by bjaideep's avatar bjaideep Committed by Commit bot

PPC: [turbofan] Introduce integer multiplication with overflow.

Port 8e18a5f2

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}
parent 2aa2b652
...@@ -975,6 +975,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -975,6 +975,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchPrepareTailCall: case kArchPrepareTailCall:
AssemblePrepareTailCall(); AssemblePrepareTailCall();
break; break;
case kArchComment: {
Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string));
break;
}
case kArchCallCFunction: { case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode()); int const num_parameters = MiscField::decode(instr->opcode());
if (instr->InputAt(0)->IsImmediate()) { if (instr->InputAt(0)->IsImmediate()) {
...@@ -1300,6 +1305,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1300,6 +1305,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
LeaveOE, i.OutputRCBit()); LeaveOE, i.OutputRCBit());
break; break;
#endif #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: case kPPC_MulHigh32:
__ mulhw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), __ mulhw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
i.OutputRCBit()); i.OutputRCBit());
......
...@@ -42,6 +42,7 @@ namespace compiler { ...@@ -42,6 +42,7 @@ namespace compiler {
V(PPC_SubPair) \ V(PPC_SubPair) \
V(PPC_SubDouble) \ V(PPC_SubDouble) \
V(PPC_Mul32) \ V(PPC_Mul32) \
V(PPC_Mul32WithHigh32) \
V(PPC_Mul64) \ V(PPC_Mul64) \
V(PPC_MulHigh32) \ V(PPC_MulHigh32) \
V(PPC_MulHighU32) \ V(PPC_MulHighU32) \
......
...@@ -44,6 +44,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -44,6 +44,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_SubPair: case kPPC_SubPair:
case kPPC_SubDouble: case kPPC_SubDouble:
case kPPC_Mul32: case kPPC_Mul32:
case kPPC_Mul32WithHigh32:
case kPPC_Mul64: case kPPC_Mul64:
case kPPC_MulHigh32: case kPPC_MulHigh32:
case kPPC_MulHighU32: case kPPC_MulHighU32:
......
...@@ -989,6 +989,36 @@ void InstructionSelector::VisitInt64Sub(Node* node) { ...@@ -989,6 +989,36 @@ void InstructionSelector::VisitInt64Sub(Node* node) {
} }
#endif #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) { void InstructionSelector::VisitInt32Mul(Node* node) {
VisitRRR(this, kPPC_Mul32, node); VisitRRR(this, kPPC_Mul32, node);
...@@ -1626,6 +1656,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -1626,6 +1656,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
return VisitBinop<Int32BinopMatcher>(selector, node, return VisitBinop<Int32BinopMatcher>(selector, node,
kPPC_SubWithOverflow32, kPPC_SubWithOverflow32,
kInt16Imm_Negate, cont); kInt16Imm_Negate, cont);
case IrOpcode::kInt32MulWithOverflow:
cont->OverwriteAndNegateIfEqual(kNotEqual);
return EmitInt32MulWithOverflow(selector, node, cont);
#if V8_TARGET_ARCH_PPC64 #if V8_TARGET_ARCH_PPC64
case IrOpcode::kInt64AddWithOverflow: case IrOpcode::kInt64AddWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow); cont->OverwriteAndNegateIfEqual(kOverflow);
...@@ -1820,6 +1853,15 @@ void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { ...@@ -1820,6 +1853,15 @@ void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
} }
#endif #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) { void InstructionSelector::VisitFloat32Equal(Node* node) {
FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment