Commit 7df3477a authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS: [turbofan] use Lsa/Dlsa in some Multiplication cases.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#35309}
parent ceb14f8c
......@@ -899,7 +899,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ li(i.OutputRegister(), i.InputOperand(0));
}
break;
case kMipsLsa:
DCHECK(instr->InputAt(2)->IsImmediate());
__ Lsa(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
i.InputInt8(2));
break;
case kMipsCmpS:
// Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
break;
......
......@@ -30,6 +30,7 @@ namespace compiler {
V(MipsClz) \
V(MipsCtz) \
V(MipsPopcnt) \
V(MipsLsa) \
V(MipsShl) \
V(MipsShr) \
V(MipsSar) \
......
......@@ -488,8 +488,32 @@ void InstructionSelector::VisitWord32Popcnt(Node* node) {
void InstructionSelector::VisitInt32Add(Node* node) {
MipsOperandGenerator g(this);
Int32BinopMatcher m(node);
// Select Lsa for (left + (left_of_right << imm)).
if (m.right().opcode() == IrOpcode::kWord32Shl &&
CanCover(node, m.left().node()) && CanCover(node, m.right().node())) {
Int32BinopMatcher mright(m.right().node());
if (mright.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mright.right().Value());
Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
g.UseRegister(mright.left().node()), g.TempImmediate(shift_value));
return;
}
}
// Select Lsa for ((left_of_left << imm) + right).
if (m.left().opcode() == IrOpcode::kWord32Shl &&
CanCover(node, m.right().node()) && CanCover(node, m.left().node())) {
Int32BinopMatcher mleft(m.left().node());
if (mleft.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.right().node()),
g.UseRegister(mleft.left().node()), g.TempImmediate(shift_value));
return;
}
}
// TODO(plind): Consider multiply & add optimization from arm port.
VisitBinop(this, node, kMipsAdd);
}
......@@ -511,12 +535,9 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand temp = g.TempRegister();
Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
Emit(kMipsAdd | AddressingModeField::encode(kMode_None),
g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
return;
}
if (base::bits::IsPowerOfTwo32(value + 1)) {
......
......@@ -775,6 +775,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kMips64DmodU:
__ Dmodu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
case kMips64Dlsa:
DCHECK(instr->InputAt(2)->IsImmediate());
__ Dlsa(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
i.InputInt8(2));
break;
case kMips64Lsa:
DCHECK(instr->InputAt(2)->IsImmediate());
__ Lsa(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
i.InputInt8(2));
break;
case kMips64And:
__ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
......
......@@ -36,6 +36,8 @@ namespace compiler {
V(Mips64Nor) \
V(Mips64Xor) \
V(Mips64Clz) \
V(Mips64Lsa) \
V(Mips64Dlsa) \
V(Mips64Shl) \
V(Mips64Shr) \
V(Mips64Sar) \
......
......@@ -611,14 +611,66 @@ void InstructionSelector::VisitWord64Clz(Node* node) {
void InstructionSelector::VisitInt32Add(Node* node) {
Mips64OperandGenerator g(this);
// TODO(plind): Consider multiply & add optimization from arm port.
Int32BinopMatcher m(node);
// Select Lsa for (left + (left_of_right << imm)).
if (m.right().opcode() == IrOpcode::kWord32Shl &&
CanCover(node, m.left().node()) && CanCover(node, m.right().node())) {
Int32BinopMatcher mright(m.right().node());
if (mright.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mright.right().Value());
Emit(kMips64Lsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
g.UseRegister(mright.left().node()), g.TempImmediate(shift_value));
return;
}
}
// Select Lsa for ((left_of_left << imm) + right).
if (m.left().opcode() == IrOpcode::kWord32Shl &&
CanCover(node, m.right().node()) && CanCover(node, m.left().node())) {
Int32BinopMatcher mleft(m.left().node());
if (mleft.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
Emit(kMips64Lsa, g.DefineAsRegister(node),
g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
g.TempImmediate(shift_value));
return;
}
}
VisitBinop(this, node, kMips64Add);
}
void InstructionSelector::VisitInt64Add(Node* node) {
Mips64OperandGenerator g(this);
// TODO(plind): Consider multiply & add optimization from arm port.
Int64BinopMatcher m(node);
// Select Dlsa for (left + (left_of_right << imm)).
if (m.right().opcode() == IrOpcode::kWord64Shl &&
CanCover(node, m.left().node()) && CanCover(node, m.right().node())) {
Int64BinopMatcher mright(m.right().node());
if (mright.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mright.right().Value());
Emit(kMips64Dlsa, g.DefineAsRegister(node),
g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()),
g.TempImmediate(shift_value));
return;
}
}
// Select Dlsa for ((left_of_left << imm) + right).
if (m.left().opcode() == IrOpcode::kWord64Shl &&
CanCover(node, m.right().node()) && CanCover(node, m.left().node())) {
Int64BinopMatcher mleft(m.left().node());
if (mleft.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
Emit(kMips64Dlsa, g.DefineAsRegister(node),
g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
g.TempImmediate(shift_value));
return;
}
}
VisitBinop(this, node, kMips64Dadd);
}
......@@ -645,12 +697,9 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand temp = g.TempRegister();
Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
Emit(kMips64Lsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
Emit(kMips64Add | AddressingModeField::encode(kMode_None),
g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
return;
}
if (base::bits::IsPowerOfTwo32(value + 1)) {
......@@ -705,12 +754,10 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand temp = g.TempRegister();
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()),
// Dlsa macro will handle the shifting value out of bound cases.
Emit(kMips64Dlsa, g.DefineAsRegister(node),
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
Emit(kMips64Dadd | AddressingModeField::encode(kMode_None),
g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
return;
}
if (base::bits::IsPowerOfTwo32(value + 1)) {
......
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