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) { ...@@ -899,7 +899,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ li(i.OutputRegister(), i.InputOperand(0)); __ li(i.OutputRegister(), i.InputOperand(0));
} }
break; break;
case kMipsLsa:
DCHECK(instr->InputAt(2)->IsImmediate());
__ Lsa(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
i.InputInt8(2));
break;
case kMipsCmpS: case kMipsCmpS:
// Psuedo-instruction used for FP cmp/branch. No opcode emitted here. // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
break; break;
......
...@@ -30,6 +30,7 @@ namespace compiler { ...@@ -30,6 +30,7 @@ namespace compiler {
V(MipsClz) \ V(MipsClz) \
V(MipsCtz) \ V(MipsCtz) \
V(MipsPopcnt) \ V(MipsPopcnt) \
V(MipsLsa) \
V(MipsShl) \ V(MipsShl) \
V(MipsShr) \ V(MipsShr) \
V(MipsSar) \ V(MipsSar) \
......
...@@ -488,8 +488,32 @@ void InstructionSelector::VisitWord32Popcnt(Node* node) { ...@@ -488,8 +488,32 @@ void InstructionSelector::VisitWord32Popcnt(Node* node) {
void InstructionSelector::VisitInt32Add(Node* node) { void InstructionSelector::VisitInt32Add(Node* node) {
MipsOperandGenerator g(this); 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); VisitBinop(this, node, kMipsAdd);
} }
...@@ -511,12 +535,9 @@ void InstructionSelector::VisitInt32Mul(Node* node) { ...@@ -511,12 +535,9 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value - 1)) { if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand temp = g.TempRegister(); Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1))); g.TempImmediate(WhichPowerOf2(value - 1)));
Emit(kMipsAdd | AddressingModeField::encode(kMode_None),
g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
return; return;
} }
if (base::bits::IsPowerOfTwo32(value + 1)) { if (base::bits::IsPowerOfTwo32(value + 1)) {
......
...@@ -775,6 +775,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -775,6 +775,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kMips64DmodU: case kMips64DmodU:
__ Dmodu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); __ Dmodu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break; 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: case kMips64And:
__ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break; break;
......
...@@ -36,6 +36,8 @@ namespace compiler { ...@@ -36,6 +36,8 @@ namespace compiler {
V(Mips64Nor) \ V(Mips64Nor) \
V(Mips64Xor) \ V(Mips64Xor) \
V(Mips64Clz) \ V(Mips64Clz) \
V(Mips64Lsa) \
V(Mips64Dlsa) \
V(Mips64Shl) \ V(Mips64Shl) \
V(Mips64Shr) \ V(Mips64Shr) \
V(Mips64Sar) \ V(Mips64Sar) \
......
...@@ -611,14 +611,66 @@ void InstructionSelector::VisitWord64Clz(Node* node) { ...@@ -611,14 +611,66 @@ void InstructionSelector::VisitWord64Clz(Node* node) {
void InstructionSelector::VisitInt32Add(Node* node) { void InstructionSelector::VisitInt32Add(Node* node) {
Mips64OperandGenerator g(this); 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); VisitBinop(this, node, kMips64Add);
} }
void InstructionSelector::VisitInt64Add(Node* node) { void InstructionSelector::VisitInt64Add(Node* node) {
Mips64OperandGenerator g(this); 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); VisitBinop(this, node, kMips64Dadd);
} }
...@@ -645,12 +697,9 @@ void InstructionSelector::VisitInt32Mul(Node* node) { ...@@ -645,12 +697,9 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value - 1)) { if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand temp = g.TempRegister(); Emit(kMips64Lsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1))); g.TempImmediate(WhichPowerOf2(value - 1)));
Emit(kMips64Add | AddressingModeField::encode(kMode_None),
g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
return; return;
} }
if (base::bits::IsPowerOfTwo32(value + 1)) { if (base::bits::IsPowerOfTwo32(value + 1)) {
...@@ -705,12 +754,10 @@ void InstructionSelector::VisitInt64Mul(Node* node) { ...@@ -705,12 +754,10 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value - 1)) { if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand temp = g.TempRegister(); // Dlsa macro will handle the shifting value out of bound cases.
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp, Emit(kMips64Dlsa, g.DefineAsRegister(node),
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1))); g.TempImmediate(WhichPowerOf2(value - 1)));
Emit(kMips64Dadd | AddressingModeField::encode(kMode_None),
g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
return; return;
} }
if (base::bits::IsPowerOfTwo32(value + 1)) { 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