PPC/s390: Support Int64MulWithOverflow
Port 78570f7826
Original Commit Message:
This CL implemented Int64MulWithOverflow on x64 and arm64
to support type feedback collection for BigInt64 multiplication.
R=panq@google.com, joransiu@ca.ibm.com, junyan@redhat.com, midawson@redhat.com
BUG=
LOG=N
Change-Id: Ieda7f5f3619c9280bc777f21bab1a66716d8e36e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3945132
Reviewed-by: Junliang Yan <junyan@redhat.com>
Commit-Queue: Milad Farazmand <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/main@{#83634}
This commit is contained in:
parent
45106e33d0
commit
2488755c4d
@ -1109,6 +1109,23 @@ void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node,
|
||||
VisitCompare(selector, kPPC_Cmp32, high32_operand, temp_operand, cont);
|
||||
}
|
||||
|
||||
void EmitInt64MulWithOverflow(InstructionSelector* selector, Node* node,
|
||||
FlagsContinuation* cont) {
|
||||
PPCOperandGenerator g(selector);
|
||||
Int64BinopMatcher m(node);
|
||||
InstructionOperand result = g.DefineAsRegister(node);
|
||||
InstructionOperand left = g.UseRegister(m.left().node());
|
||||
InstructionOperand high = g.TempRegister();
|
||||
InstructionOperand result_sign = g.TempRegister();
|
||||
InstructionOperand right = g.UseRegister(m.right().node());
|
||||
selector->Emit(kPPC_Mul64, result, left, right);
|
||||
selector->Emit(kPPC_MulHighS64, high, left, right);
|
||||
selector->Emit(kPPC_ShiftRightAlg64, result_sign, result,
|
||||
g.TempImmediate(63));
|
||||
// Test whether {high} is a sign-extension of {result}.
|
||||
selector->EmitWithContinuation(kPPC_Cmp64, high, result_sign, cont);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void InstructionSelector::VisitInt32Mul(Node* node) {
|
||||
@ -1554,6 +1571,15 @@ void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
|
||||
FlagsContinuation cont;
|
||||
VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate, &cont);
|
||||
}
|
||||
|
||||
void InstructionSelector::VisitInt64MulWithOverflow(Node* node) {
|
||||
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
|
||||
FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf);
|
||||
return EmitInt64MulWithOverflow(this, node, &cont);
|
||||
}
|
||||
FlagsContinuation cont;
|
||||
EmitInt64MulWithOverflow(this, node, &cont);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool CompareLogical(FlagsContinuation* cont) {
|
||||
@ -1734,6 +1760,9 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
|
||||
cont->OverwriteAndNegateIfEqual(kOverflow);
|
||||
return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub,
|
||||
kInt16Imm_Negate, cont);
|
||||
case IrOpcode::kInt64MulWithOverflow:
|
||||
cont->OverwriteAndNegateIfEqual(kNotEqual);
|
||||
return EmitInt64MulWithOverflow(this, node, cont);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
|
@ -306,6 +306,7 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
|
||||
case kS390_Abs64:
|
||||
case kS390_Abs32:
|
||||
case kS390_Mul32:
|
||||
case kS390_Mul64WithOverflow:
|
||||
return overflow;
|
||||
default:
|
||||
break;
|
||||
@ -1695,6 +1696,21 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
case kS390_Mul64:
|
||||
ASSEMBLE_BIN_OP(RRInstr(MulS64), RM64Instr(MulS64), RIInstr(MulS64));
|
||||
break;
|
||||
case kS390_Mul64WithOverflow: {
|
||||
Register dst = i.OutputRegister(), src1 = i.InputRegister(0),
|
||||
src2 = i.InputRegister(1);
|
||||
DCHECK(!AreAliased(dst, src1, src2));
|
||||
if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
|
||||
__ msgrkc(dst, src1, src2);
|
||||
} else {
|
||||
__ mgrk(r0, src1, src2); // r0 = high 64-bits, r1 = low 64-bits.
|
||||
__ lgr(dst, r1);
|
||||
__ ShiftRightS64(r1, r1, Operand(63));
|
||||
// Test whether {high} is a sign-extension of {result}.
|
||||
__ CmpU64(r0, r1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kS390_MulHigh32:
|
||||
// zero-ext
|
||||
ASSEMBLE_BIN_OP(RRRInstr(MulHighS32), RRM32Instr(MulHighS32),
|
||||
|
@ -47,6 +47,7 @@ namespace compiler {
|
||||
V(S390_Mul32) \
|
||||
V(S390_Mul32WithOverflow) \
|
||||
V(S390_Mul64) \
|
||||
V(S390_Mul64WithOverflow) \
|
||||
V(S390_MulHighS64) \
|
||||
V(S390_MulHighU64) \
|
||||
V(S390_MulHigh32) \
|
||||
|
@ -46,6 +46,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
|
||||
case kS390_Mul32:
|
||||
case kS390_Mul32WithOverflow:
|
||||
case kS390_Mul64:
|
||||
case kS390_Mul64WithOverflow:
|
||||
case kS390_MulHighS64:
|
||||
case kS390_MulHighU64:
|
||||
case kS390_MulHigh32:
|
||||
|
@ -1259,6 +1259,23 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector,
|
||||
return TryMatchInt64OpWithOverflow<kS390_Sub64>(selector, node,
|
||||
SubOperandMode);
|
||||
}
|
||||
|
||||
void EmitInt64MulWithOverflow(InstructionSelector* selector, Node* node,
|
||||
FlagsContinuation* cont) {
|
||||
S390OperandGenerator g(selector);
|
||||
Int64BinopMatcher m(node);
|
||||
InstructionOperand inputs[2];
|
||||
size_t input_count = 0;
|
||||
InstructionOperand outputs[1];
|
||||
size_t output_count = 0;
|
||||
|
||||
inputs[input_count++] = g.UseUniqueRegister(m.left().node());
|
||||
inputs[input_count++] = g.UseUniqueRegister(m.right().node());
|
||||
outputs[output_count++] = g.DefineAsRegister(node);
|
||||
selector->EmitWithContinuation(kS390_Mul64WithOverflow, output_count, outputs,
|
||||
input_count, inputs, cont);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline bool TryMatchDoubleConstructFromInsert(
|
||||
@ -1587,6 +1604,16 @@ void InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
|
||||
->MarkAsCall();
|
||||
}
|
||||
|
||||
void InstructionSelector::VisitInt64MulWithOverflow(Node* node) {
|
||||
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
|
||||
FlagsContinuation cont = FlagsContinuation::ForSet(
|
||||
CpuFeatures::IsSupported(MISC_INSTR_EXT2) ? kOverflow : kNotEqual, ovf);
|
||||
return EmitInt64MulWithOverflow(this, node, &cont);
|
||||
}
|
||||
FlagsContinuation cont;
|
||||
EmitInt64MulWithOverflow(this, node, &cont);
|
||||
}
|
||||
|
||||
static bool CompareLogical(FlagsContinuation* cont) {
|
||||
switch (cont->condition()) {
|
||||
case kUnsignedLessThan:
|
||||
@ -1904,6 +1931,11 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
|
||||
cont->OverwriteAndNegateIfEqual(kOverflow);
|
||||
return VisitWord64BinOp(this, node, kS390_Sub64, SubOperandMode,
|
||||
cont);
|
||||
case IrOpcode::kInt64MulWithOverflow:
|
||||
cont->OverwriteAndNegateIfEqual(
|
||||
CpuFeatures::IsSupported(MISC_INSTR_EXT2) ? kOverflow
|
||||
: kNotEqual);
|
||||
return EmitInt64MulWithOverflow(this, node, cont);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user