Commit 0c5c4795 authored by dusan.m.milosavljevic's avatar dusan.m.milosavljevic Committed by Commit bot

MIPS: [turbofan] Improve test and equality compare with zero and constants.

TEST=
BUG=

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

Cr-Commit-Position: refs/heads/master@{#31222}
parent 32f13dfb
...@@ -968,19 +968,10 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, ...@@ -968,19 +968,10 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
if (instr->arch_opcode() == kMipsTst) { if (instr->arch_opcode() == kMipsTst) {
cc = FlagsConditionToConditionTst(condition); cc = FlagsConditionToConditionTst(condition);
__ And(kScratchReg, i.InputRegister(0), i.InputOperand(1)); __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1));
__ xori(result, zero_reg, 1); // Create 1 for true. __ Sltu(result, zero_reg, kScratchReg);
if (IsMipsArchVariant(kMips32r6)) { if (cc == eq) {
if (cc == eq) { // Sltu produces 0 for equality, invert the result.
__ seleqz(result, result, kScratchReg); __ xori(result, result, 1);
} else {
__ selnez(result, result, kScratchReg);
}
} else {
if (cc == eq) {
__ Movn(result, zero_reg, kScratchReg);
} else {
__ Movz(result, zero_reg, kScratchReg);
}
} }
return; return;
} else if (instr->arch_opcode() == kMipsAddOvf || } else if (instr->arch_opcode() == kMipsAddOvf ||
...@@ -999,20 +990,18 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, ...@@ -999,20 +990,18 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
case ne: { case ne: {
Register left = i.InputRegister(0); Register left = i.InputRegister(0);
Operand right = i.InputOperand(1); Operand right = i.InputOperand(1);
__ Subu(kScratchReg, left, right); Register select;
__ xori(result, zero_reg, 1); if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) {
if (IsMipsArchVariant(kMips32r6)) { // Pass left operand if right is zero.
if (cc == eq) { select = left;
__ seleqz(result, result, kScratchReg);
} else {
__ selnez(result, result, kScratchReg);
}
} else { } else {
if (cc == eq) { __ Subu(kScratchReg, left, right);
__ Movn(result, zero_reg, kScratchReg); select = kScratchReg;
} else { }
__ Movz(result, zero_reg, kScratchReg); __ Sltu(result, zero_reg, select);
} if (cc == eq) {
// Sltu produces 0 for equality, invert the result.
__ xori(result, result, 1);
} }
} break; } break;
case lt: case lt:
......
...@@ -44,11 +44,10 @@ class MipsOperandGenerator final : public OperandGenerator { ...@@ -44,11 +44,10 @@ class MipsOperandGenerator final : public OperandGenerator {
return is_uint16(value); return is_uint16(value);
case kMipsLdc1: case kMipsLdc1:
case kMipsSdc1: case kMipsSdc1:
case kCheckedLoadFloat32:
case kCheckedLoadFloat64: case kCheckedLoadFloat64:
case kCheckedStoreFloat32:
case kCheckedStoreFloat64: case kCheckedStoreFloat64:
return is_int16(value + kIntSize); return std::numeric_limits<int16_t>::min() <= (value + kIntSize) &&
std::numeric_limits<int16_t>::max() >= (value + kIntSize);
default: default:
return is_int16(value); return is_int16(value);
} }
...@@ -826,6 +825,16 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -826,6 +825,16 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
// Match immediates on left or right side of comparison. // Match immediates on left or right side of comparison.
if (g.CanBeImmediate(right, opcode)) { if (g.CanBeImmediate(right, opcode)) {
switch (cont->condition()) { switch (cont->condition()) {
case kEqual:
case kNotEqual:
if (cont->IsSet()) {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseImmediate(right), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
}
break;
case kSignedLessThan: case kSignedLessThan:
case kSignedGreaterThanOrEqual: case kSignedGreaterThanOrEqual:
case kUnsignedLessThan: case kUnsignedLessThan:
...@@ -840,6 +849,16 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -840,6 +849,16 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
} else if (g.CanBeImmediate(left, opcode)) { } else if (g.CanBeImmediate(left, opcode)) {
if (!commutative) cont->Commute(); if (!commutative) cont->Commute();
switch (cont->condition()) { switch (cont->condition()) {
case kEqual:
case kNotEqual:
if (cont->IsSet()) {
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseImmediate(left), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseRegister(left), cont);
}
break;
case kSignedLessThan: case kSignedLessThan:
case kSignedGreaterThanOrEqual: case kSignedGreaterThanOrEqual:
case kUnsignedLessThan: case kUnsignedLessThan:
......
...@@ -1046,19 +1046,10 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, ...@@ -1046,19 +1046,10 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
if (instr->arch_opcode() == kMips64Tst) { if (instr->arch_opcode() == kMips64Tst) {
cc = FlagsConditionToConditionTst(condition); cc = FlagsConditionToConditionTst(condition);
__ And(kScratchReg, i.InputRegister(0), i.InputOperand(1)); __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1));
__ xori(result, zero_reg, 1); // Create 1 for true. __ Sltu(result, zero_reg, kScratchReg);
if (kArchVariant == kMips64r6) { if (cc == eq) {
if (cc == eq) { // Sltu produces 0 for equality, invert the result.
__ seleqz(result, result, kScratchReg); __ xori(result, result, 1);
} else {
__ selnez(result, result, kScratchReg);
}
} else {
if (cc == eq) {
__ Movn(result, zero_reg, kScratchReg);
} else {
__ Movz(result, zero_reg, kScratchReg);
}
} }
return; return;
} else if (instr->arch_opcode() == kMips64Dadd || } else if (instr->arch_opcode() == kMips64Dadd ||
...@@ -1078,20 +1069,18 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, ...@@ -1078,20 +1069,18 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
case ne: { case ne: {
Register left = i.InputRegister(0); Register left = i.InputRegister(0);
Operand right = i.InputOperand(1); Operand right = i.InputOperand(1);
__ Dsubu(kScratchReg, left, right); Register select;
__ xori(result, zero_reg, 1); if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) {
if (kArchVariant == kMips64r6) { // Pass left operand if right is zero.
if (cc == eq) { select = left;
__ seleqz(result, result, kScratchReg);
} else {
__ selnez(result, result, kScratchReg);
}
} else { } else {
if (cc == eq) { __ Dsubu(kScratchReg, left, right);
__ Movn(result, zero_reg, kScratchReg); select = kScratchReg;
} else { }
__ Movz(result, zero_reg, kScratchReg); __ Sltu(result, zero_reg, select);
} if (cc == eq) {
// Sltu produces 0 for equality, invert the result.
__ xori(result, result, 1);
} }
} break; } break;
case lt: case lt:
......
...@@ -1019,6 +1019,16 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -1019,6 +1019,16 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
// Match immediates on left or right side of comparison. // Match immediates on left or right side of comparison.
if (g.CanBeImmediate(right, opcode)) { if (g.CanBeImmediate(right, opcode)) {
switch (cont->condition()) { switch (cont->condition()) {
case kEqual:
case kNotEqual:
if (cont->IsSet()) {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseImmediate(right), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(left),
g.UseRegister(right), cont);
}
break;
case kSignedLessThan: case kSignedLessThan:
case kSignedGreaterThanOrEqual: case kSignedGreaterThanOrEqual:
case kUnsignedLessThan: case kUnsignedLessThan:
...@@ -1033,6 +1043,16 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, ...@@ -1033,6 +1043,16 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
} else if (g.CanBeImmediate(left, opcode)) { } else if (g.CanBeImmediate(left, opcode)) {
if (!commutative) cont->Commute(); if (!commutative) cont->Commute();
switch (cont->condition()) { switch (cont->condition()) {
case kEqual:
case kNotEqual:
if (cont->IsSet()) {
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseImmediate(left), cont);
} else {
VisitCompare(selector, opcode, g.UseRegister(right),
g.UseRegister(left), cont);
}
break;
case kSignedLessThan: case kSignedLessThan:
case kSignedGreaterThanOrEqual: case kSignedGreaterThanOrEqual:
case kUnsignedLessThan: case kUnsignedLessThan:
......
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