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) {
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() && !m.left().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;
if (IsMipsArchVariant(kMips32r6)) {
// 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() && !m.left().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mright.right().Value());
if (shift_value > 0 && shift_value <= 31) {
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() && !m.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;
// 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() && !m.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
if (shift_value > 0 && shift_value <= 31) {
Emit(kMipsLsa, g.DefineAsRegister(node),
g.UseRegister(m.right().node()),
g.UseRegister(mleft.left().node()),
g.TempImmediate(shift_value));
return;
}
}
}
}
......@@ -844,7 +854,8 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
g.TempImmediate(WhichPowerOf2(value)));
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()),
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
......
......@@ -862,30 +862,40 @@ void InstructionSelector::VisitInt32Add(Node* node) {
Mips64OperandGenerator 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() && !m.left().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;
if (kArchVariant == kMips64r6) {
// 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() && !m.left().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mright.right().Value());
if (shift_value > 0 && shift_value <= 31) {
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() && !m.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;
// 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() && !m.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
if (shift_value > 0 && shift_value <= 31) {
Emit(kMips64Lsa, g.DefineAsRegister(node),
g.UseRegister(m.right().node()),
g.UseRegister(mleft.left().node()),
g.TempImmediate(shift_value));
return;
}
}
}
}
VisitBinop(this, node, kMips64Add, true, kMips64Add);
}
......@@ -893,29 +903,37 @@ void InstructionSelector::VisitInt64Add(Node* node) {
Mips64OperandGenerator g(this);
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() && !m.left().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;
if (kArchVariant == kMips64r6) {
// 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() && !m.left().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mright.right().Value());
if (shift_value > 0 && shift_value <= 31) {
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() && !m.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;
// 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() && !m.right().HasValue()) {
int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
if (shift_value > 0 && shift_value <= 31) {
Emit(kMips64Dlsa, g.DefineAsRegister(node),
g.UseRegister(m.right().node()),
g.UseRegister(mleft.left().node()),
g.TempImmediate(shift_value));
return;
}
}
}
}
......@@ -941,7 +959,8 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
g.TempImmediate(WhichPowerOf2(value)));
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()),
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
......@@ -995,7 +1014,8 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
g.TempImmediate(WhichPowerOf2(value)));
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.
Emit(kMips64Dlsa, g.DefineAsRegister(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