From f6c45c5243646a2a2da7bc113971c3b439323ac3 Mon Sep 17 00:00:00 2001 From: bjaideep Date: Sun, 17 Jul 2016 20:40:08 -0700 Subject: [PATCH] PPC: [turbofan] Introduce integer multiplication with overflow. Port 8e18a5f2a0357c6899cd32f5ab66b73d72fdd996 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} --- src/compiler/ppc/code-generator-ppc.cc | 23 ++++++++++ src/compiler/ppc/instruction-codes-ppc.h | 1 + src/compiler/ppc/instruction-scheduler-ppc.cc | 1 + src/compiler/ppc/instruction-selector-ppc.cc | 42 +++++++++++++++++++ 4 files changed, 67 insertions(+) diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/ppc/code-generator-ppc.cc index 6da65c3485..2f70dd28da 100644 --- a/src/compiler/ppc/code-generator-ppc.cc +++ b/src/compiler/ppc/code-generator-ppc.cc @@ -975,6 +975,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArchPrepareTailCall: AssemblePrepareTailCall(); break; + case kArchComment: { + Address comment_string = i.InputExternalReference(0).address(); + __ RecordComment(reinterpret_cast(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()); diff --git a/src/compiler/ppc/instruction-codes-ppc.h b/src/compiler/ppc/instruction-codes-ppc.h index d697da328b..9198bcb00c 100644 --- a/src/compiler/ppc/instruction-codes-ppc.h +++ b/src/compiler/ppc/instruction-codes-ppc.h @@ -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) \ diff --git a/src/compiler/ppc/instruction-scheduler-ppc.cc b/src/compiler/ppc/instruction-scheduler-ppc.cc index f41900d443..dee84943fa 100644 --- a/src/compiler/ppc/instruction-scheduler-ppc.cc +++ b/src/compiler/ppc/instruction-scheduler-ppc.cc @@ -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: diff --git a/src/compiler/ppc/instruction-selector-ppc.cc b/src/compiler/ppc/instruction-selector-ppc.cc index 85eeb2c2a1..65e36aa7e4 100644 --- a/src/compiler/ppc/instruction-selector-ppc.cc +++ b/src/compiler/ppc/instruction-selector-ppc.cc @@ -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(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);