Commit f1d2400b authored by Predrag Rudic's avatar Predrag Rudic Committed by Commit Bot

MIPS[64]: Fix Dlsa/Lsa instructions emission.

Emit Dlsa/Lsa only on revision 6 or when MSA is supported. Since we
support MSA only on r6, it is the only thing that is checked.
Added check if shift of Dlsa/Lsa is in range 0<shift<=31

Change-Id: Ic3902fcccc1a2e3ecc5f550ea3b7980bd2bb4c27
Reviewed-on: https://chromium-review.googlesource.com/c/1337581Reviewed-by: 's avatarIvica Bogosavljevic <ibogosavljevic@wavecomp.com>
Commit-Queue: Ivica Bogosavljevic <ibogosavljevic@wavecomp.com>
Cr-Commit-Position: refs/heads/master@{#57549}
parent a6e7d781
...@@ -802,27 +802,37 @@ void InstructionSelector::VisitInt32Add(Node* node) { ...@@ -802,27 +802,37 @@ void InstructionSelector::VisitInt32Add(Node* node) {
MipsOperandGenerator g(this); MipsOperandGenerator g(this);
Int32BinopMatcher m(node); Int32BinopMatcher m(node);
// Select Lsa for (left + (left_of_right << imm)). if (IsMipsArchVariant(kMips32r6)) {
if (m.right().opcode() == IrOpcode::kWord32Shl && // Select Lsa for (left + (left_of_right << imm)).
CanCover(node, m.left().node()) && CanCover(node, m.right().node())) { if (m.right().opcode() == IrOpcode::kWord32Shl &&
Int32BinopMatcher mright(m.right().node()); CanCover(node, m.left().node()) && CanCover(node, m.right().node())) {
if (mright.right().HasValue() && !m.left().HasValue()) { Int32BinopMatcher mright(m.right().node());
int32_t shift_value = static_cast<int32_t>(mright.right().Value()); if (mright.right().HasValue() && !m.left().HasValue()) {
Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()), int32_t shift_value = static_cast<int32_t>(mright.right().Value());
g.UseRegister(mright.left().node()), g.TempImmediate(shift_value)); if (shift_value > 0 && shift_value <= 31) {
return; 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). // Select Lsa for ((left_of_left << imm) + right).
if (m.left().opcode() == IrOpcode::kWord32Shl && if (m.left().opcode() == IrOpcode::kWord32Shl &&
CanCover(node, m.right().node()) && CanCover(node, m.left().node())) { CanCover(node, m.right().node()) && CanCover(node, m.left().node())) {
Int32BinopMatcher mleft(m.left().node()); Int32BinopMatcher mleft(m.left().node());
if (mleft.right().HasValue() && !m.right().HasValue()) { if (mleft.right().HasValue() && !m.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value()); int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.right().node()), if (shift_value > 0 && shift_value <= 31) {
g.UseRegister(mleft.left().node()), g.TempImmediate(shift_value)); Emit(kMipsLsa, g.DefineAsRegister(node),
return; g.UseRegister(m.right().node()),
g.UseRegister(mleft.left().node()),
g.TempImmediate(shift_value));
return;
}
}
} }
} }
...@@ -844,7 +854,8 @@ void InstructionSelector::VisitInt32Mul(Node* node) { ...@@ -844,7 +854,8 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
g.TempImmediate(WhichPowerOf2(value))); g.TempImmediate(WhichPowerOf2(value)));
return; return;
} }
if (base::bits::IsPowerOfTwo(value - 1)) { if (base::bits::IsPowerOfTwo(value - 1) && IsMipsArchVariant(kMips32r6) &&
value - 1 > 0 && value - 1 <= 31) {
Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()), Emit(kMipsLsa, 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)));
......
...@@ -862,30 +862,40 @@ void InstructionSelector::VisitInt32Add(Node* node) { ...@@ -862,30 +862,40 @@ void InstructionSelector::VisitInt32Add(Node* node) {
Mips64OperandGenerator g(this); Mips64OperandGenerator g(this);
Int32BinopMatcher m(node); Int32BinopMatcher m(node);
// Select Lsa for (left + (left_of_right << imm)). if (kArchVariant == kMips64r6) {
if (m.right().opcode() == IrOpcode::kWord32Shl && // Select Lsa for (left + (left_of_right << imm)).
CanCover(node, m.left().node()) && CanCover(node, m.right().node())) { if (m.right().opcode() == IrOpcode::kWord32Shl &&
Int32BinopMatcher mright(m.right().node()); CanCover(node, m.left().node()) && CanCover(node, m.right().node())) {
if (mright.right().HasValue() && !m.left().HasValue()) { Int32BinopMatcher mright(m.right().node());
int32_t shift_value = static_cast<int32_t>(mright.right().Value()); if (mright.right().HasValue() && !m.left().HasValue()) {
Emit(kMips64Lsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()), int32_t shift_value = static_cast<int32_t>(mright.right().Value());
g.UseRegister(mright.left().node()), g.TempImmediate(shift_value)); if (shift_value > 0 && shift_value <= 31) {
return; 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). // Select Lsa for ((left_of_left << imm) + right).
if (m.left().opcode() == IrOpcode::kWord32Shl && if (m.left().opcode() == IrOpcode::kWord32Shl &&
CanCover(node, m.right().node()) && CanCover(node, m.left().node())) { CanCover(node, m.right().node()) && CanCover(node, m.left().node())) {
Int32BinopMatcher mleft(m.left().node()); Int32BinopMatcher mleft(m.left().node());
if (mleft.right().HasValue() && !m.right().HasValue()) { if (mleft.right().HasValue() && !m.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value()); int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
Emit(kMips64Lsa, g.DefineAsRegister(node), if (shift_value > 0 && shift_value <= 31) {
g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), Emit(kMips64Lsa, g.DefineAsRegister(node),
g.TempImmediate(shift_value)); g.UseRegister(m.right().node()),
return; g.UseRegister(mleft.left().node()),
g.TempImmediate(shift_value));
return;
}
}
} }
} }
VisitBinop(this, node, kMips64Add, true, kMips64Add); VisitBinop(this, node, kMips64Add, true, kMips64Add);
} }
...@@ -893,29 +903,37 @@ void InstructionSelector::VisitInt64Add(Node* node) { ...@@ -893,29 +903,37 @@ void InstructionSelector::VisitInt64Add(Node* node) {
Mips64OperandGenerator g(this); Mips64OperandGenerator g(this);
Int64BinopMatcher m(node); Int64BinopMatcher m(node);
// Select Dlsa for (left + (left_of_right << imm)). if (kArchVariant == kMips64r6) {
if (m.right().opcode() == IrOpcode::kWord64Shl && // Select Dlsa for (left + (left_of_right << imm)).
CanCover(node, m.left().node()) && CanCover(node, m.right().node())) { if (m.right().opcode() == IrOpcode::kWord64Shl &&
Int64BinopMatcher mright(m.right().node()); CanCover(node, m.left().node()) && CanCover(node, m.right().node())) {
if (mright.right().HasValue() && !m.left().HasValue()) { Int64BinopMatcher mright(m.right().node());
int32_t shift_value = static_cast<int32_t>(mright.right().Value()); if (mright.right().HasValue() && !m.left().HasValue()) {
Emit(kMips64Dlsa, g.DefineAsRegister(node), int32_t shift_value = static_cast<int32_t>(mright.right().Value());
g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), if (shift_value > 0 && shift_value <= 31) {
g.TempImmediate(shift_value)); Emit(kMips64Dlsa, g.DefineAsRegister(node),
return; g.UseRegister(m.left().node()),
g.UseRegister(mright.left().node()),
g.TempImmediate(shift_value));
return;
}
}
} }
}
// Select Dlsa for ((left_of_left << imm) + right). // Select Dlsa for ((left_of_left << imm) + right).
if (m.left().opcode() == IrOpcode::kWord64Shl && if (m.left().opcode() == IrOpcode::kWord64Shl &&
CanCover(node, m.right().node()) && CanCover(node, m.left().node())) { CanCover(node, m.right().node()) && CanCover(node, m.left().node())) {
Int64BinopMatcher mleft(m.left().node()); Int64BinopMatcher mleft(m.left().node());
if (mleft.right().HasValue() && !m.right().HasValue()) { if (mleft.right().HasValue() && !m.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value()); int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
Emit(kMips64Dlsa, g.DefineAsRegister(node), if (shift_value > 0 && shift_value <= 31) {
g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), Emit(kMips64Dlsa, g.DefineAsRegister(node),
g.TempImmediate(shift_value)); g.UseRegister(m.right().node()),
return; g.UseRegister(mleft.left().node()),
g.TempImmediate(shift_value));
return;
}
}
} }
} }
...@@ -941,7 +959,8 @@ void InstructionSelector::VisitInt32Mul(Node* node) { ...@@ -941,7 +959,8 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
g.TempImmediate(WhichPowerOf2(value))); g.TempImmediate(WhichPowerOf2(value)));
return; return;
} }
if (base::bits::IsPowerOfTwo(value - 1)) { if (base::bits::IsPowerOfTwo(value - 1) && kArchVariant == kMips64r6 &&
value - 1 > 0 && value - 1 <= 31) {
Emit(kMips64Lsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()), Emit(kMips64Lsa, 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)));
...@@ -995,7 +1014,8 @@ void InstructionSelector::VisitInt64Mul(Node* node) { ...@@ -995,7 +1014,8 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
g.TempImmediate(WhichPowerOf2(value))); g.TempImmediate(WhichPowerOf2(value)));
return; return;
} }
if (base::bits::IsPowerOfTwo(value - 1)) { if (base::bits::IsPowerOfTwo(value - 1) && kArchVariant == kMips64r6 &&
value - 1 > 0 && value - 1 <= 31) {
// Dlsa macro will handle the shifting value out of bound cases. // Dlsa macro will handle the shifting value out of bound cases.
Emit(kMips64Dlsa, g.DefineAsRegister(node), Emit(kMips64Dlsa, g.DefineAsRegister(node),
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()), g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
......
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