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:
parent
2aa2b652af
commit
f6c45c5243
@ -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());
|
||||
|
@ -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) \
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user