Commit e36eba88 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [wasm] Int64Lowering of I64Shl.

Port ddc626e1

Original commit message:
    I64Shl is lowered to a new turbofan operator, WasmWord64Shl. The new
    operator takes 3 inputs, the low-word input, the high-word input, and
    the shift, and produces 2 output, the low-word output and the high-word
    output.

R=ahaas@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1765383004

Cr-Commit-Position: refs/heads/master@{#34588}
parent 5c1c98e8
......@@ -928,6 +928,19 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kPPC_ShiftRightAlg64:
ASSEMBLE_BINOP_INT_RC(srad, sradi);
break;
#endif
#if !V8_TARGET_ARCH_PPC64
case kPPC_PairShiftLeft:
if (instr->InputAt(2)->IsImmediate()) {
__ PairShiftLeft(i.OutputRegister(0), i.OutputRegister(1),
i.InputRegister(0), i.InputRegister(1),
i.InputInt32(2));
} else {
__ PairShiftLeft(i.OutputRegister(0), i.OutputRegister(1),
i.InputRegister(0), i.InputRegister(1), kScratchReg,
i.InputRegister(2));
}
break;
#endif
case kPPC_RotRight32:
if (HasRegisterInput(instr, 1)) {
......
......@@ -23,6 +23,7 @@ namespace compiler {
V(PPC_ShiftRight64) \
V(PPC_ShiftRightAlg32) \
V(PPC_ShiftRightAlg64) \
V(PPC_PairShiftLeft) \
V(PPC_RotRight32) \
V(PPC_RotRight64) \
V(PPC_Not) \
......
......@@ -25,6 +25,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_ShiftRight64:
case kPPC_ShiftRightAlg32:
case kPPC_ShiftRightAlg64:
case kPPC_PairShiftLeft:
case kPPC_RotRight32:
case kPPC_RotRight64:
case kPPC_Not:
......
......@@ -787,6 +787,28 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm);
}
#if !V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitWord32PairShl(Node* node) {
PPCOperandGenerator g(this);
Int32Matcher m(node->InputAt(2));
InstructionOperand shift_operand;
if (m.HasValue()) {
shift_operand = g.UseImmediate(m.node());
} else {
shift_operand = g.UseUniqueRegister(m.node());
}
InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1)),
shift_operand};
InstructionOperand outputs[] = {
g.DefineSameAsFirst(node),
g.DefineAsRegister(NodeProperties::FindProjection(node, 1))};
Emit(kPPC_PairShiftLeft, 2, outputs, 3, inputs);
}
#endif
#if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitWord64Sar(Node* node) {
......
......@@ -803,6 +803,52 @@ void MacroAssembler::ConvertDoubleToUnsignedInt64(
}
#endif
#if !V8_TARGET_ARCH_PPC64
void MacroAssembler::PairShiftLeft(Register dst_low, Register dst_high,
Register src_low, Register src_high,
Register scratch, Register shift) {
DCHECK(!AreAliased(dst_low, src_high, shift));
DCHECK(!AreAliased(dst_high, src_low, shift));
Label less_than_32;
Label done;
cmpi(shift, Operand(32));
blt(&less_than_32);
// If shift >= 32
andi(scratch, shift, Operand(0x1f));
slw(dst_high, src_low, scratch);
li(dst_low, Operand::Zero());
b(&done);
bind(&less_than_32);
// If shift < 32
subfic(scratch, shift, Operand(32));
slw(dst_high, src_high, shift);
srw(scratch, src_low, scratch);
orx(dst_high, dst_high, scratch);
slw(dst_low, src_low, shift);
bind(&done);
}
void MacroAssembler::PairShiftLeft(Register dst_low, Register dst_high,
Register src_low, Register src_high,
uint32_t shift) {
DCHECK(!AreAliased(dst_low, src_high));
DCHECK(!AreAliased(dst_high, src_low));
Label less_than_32;
Label done;
if (shift >= 32) {
shift &= 0x1f;
slwi(dst_high, src_low, Operand(shift));
li(dst_low, Operand::Zero());
} else if (shift == 0) {
Move(dst_low, src_low);
Move(dst_high, src_high);
} else {
slwi(dst_high, src_high, Operand(shift));
rlwimi(dst_high, src_low, shift, 32 - shift, 31);
slwi(dst_low, src_low, Operand(shift));
}
}
#endif
void MacroAssembler::LoadConstantPoolPointerRegisterFromCodeTargetAddress(
Register code_target_address) {
......
......@@ -410,6 +410,13 @@ class MacroAssembler : public Assembler {
FPRoundingMode rounding_mode = kRoundToZero);
#endif
#if !V8_TARGET_ARCH_PPC64
void PairShiftLeft(Register dst_low, Register dst_high, Register src_low,
Register src_high, Register scratch, Register shift);
void PairShiftLeft(Register dst_low, Register dst_high, Register src_low,
Register src_high, uint32_t shift);
#endif
// Generates function and stub prologue code.
void StubPrologue(Register base = no_reg, int prologue_offset = 0);
void Prologue(bool code_pre_aging, Register base, int prologue_offset = 0);
......
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