Index: src/compiler/mips/instruction-selector-mips.cc |
diff --git a/src/compiler/mips/instruction-selector-mips.cc b/src/compiler/mips/instruction-selector-mips.cc |
index b3e69eb5a13e6caab2a80a22067aaaab9a1bafa1..e8e6db8a53add4c8eac78f1938a3453541fe1708 100644 |
--- a/src/compiler/mips/instruction-selector-mips.cc |
+++ b/src/compiler/mips/instruction-selector-mips.cc |
@@ -40,6 +40,10 @@ class MipsOperandGenerator final : public OperandGenerator { |
case kMipsSar: |
case kMipsShr: |
return is_uint5(value); |
+ case kMipsAdd: |
+ case kMipsAnd: |
+ case kMipsOr: |
+ case kMipsSub: |
case kMipsXor: |
return is_uint16(value); |
case kMipsLdc1: |
@@ -86,9 +90,23 @@ static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, |
g.UseOperand(node->InputAt(1), opcode)); |
} |
+bool TryMatchImmediate(InstructionSelector* selector, |
+ InstructionCode* opcode_return, Node* node, |
+ size_t* input_count_return, InstructionOperand* inputs) { |
+ MipsOperandGenerator g(selector); |
+ if (g.CanBeImmediate(node, *opcode_return)) { |
+ *opcode_return |= AddressingModeField::encode(kMode_MRI); |
+ inputs[0] = g.UseImmediate(node); |
+ *input_count_return = 1; |
+ return true; |
+ } |
+ return false; |
+} |
static void VisitBinop(InstructionSelector* selector, Node* node, |
- InstructionCode opcode, FlagsContinuation* cont) { |
+ InstructionCode opcode, bool has_reverse_opcode, |
+ InstructionCode reverse_opcode, |
+ FlagsContinuation* cont) { |
MipsOperandGenerator g(selector); |
Int32BinopMatcher m(node); |
InstructionOperand inputs[4]; |
@@ -96,8 +114,21 @@ static void VisitBinop(InstructionSelector* selector, Node* node, |
InstructionOperand outputs[2]; |
size_t output_count = 0; |
- inputs[input_count++] = g.UseRegister(m.left().node()); |
- inputs[input_count++] = g.UseOperand(m.right().node(), opcode); |
+ if (TryMatchImmediate(selector, &opcode, m.right().node(), &input_count, |
+ &inputs[1])) { |
+ inputs[0] = g.UseRegister(m.left().node()); |
+ input_count++; |
+ } |
+ if (has_reverse_opcode && |
+ TryMatchImmediate(selector, &reverse_opcode, m.left().node(), |
+ &input_count, &inputs[1])) { |
+ inputs[0] = g.UseRegister(m.right().node()); |
+ opcode = reverse_opcode; |
+ input_count++; |
+ } else { |
+ inputs[input_count++] = g.UseRegister(m.left().node()); |
+ inputs[input_count++] = g.UseOperand(m.right().node(), opcode); |
+ } |
if (cont->IsBranch()) { |
inputs[input_count++] = g.Label(cont->true_block()); |
@@ -130,11 +161,21 @@ static void VisitBinop(InstructionSelector* selector, Node* node, |
} |
} |
+static void VisitBinop(InstructionSelector* selector, Node* node, |
+ InstructionCode opcode, bool has_reverse_opcode, |
+ InstructionCode reverse_opcode) { |
+ FlagsContinuation cont; |
+ VisitBinop(selector, node, opcode, has_reverse_opcode, reverse_opcode, &cont); |
+} |
+ |
+static void VisitBinop(InstructionSelector* selector, Node* node, |
+ InstructionCode opcode, FlagsContinuation* cont) { |
+ VisitBinop(selector, node, opcode, false, kArchNop, cont); |
+} |
static void VisitBinop(InstructionSelector* selector, Node* node, |
InstructionCode opcode) { |
- FlagsContinuation cont; |
- VisitBinop(selector, node, opcode, &cont); |
+ VisitBinop(selector, node, opcode, false, kArchNop); |
} |
@@ -317,12 +358,12 @@ void InstructionSelector::VisitWord32And(Node* node) { |
return; |
} |
} |
- VisitBinop(this, node, kMipsAnd); |
+ VisitBinop(this, node, kMipsAnd, true, kMipsAnd); |
} |
void InstructionSelector::VisitWord32Or(Node* node) { |
- VisitBinop(this, node, kMipsOr); |
+ VisitBinop(this, node, kMipsOr, true, kMipsOr); |
} |
@@ -346,7 +387,7 @@ void InstructionSelector::VisitWord32Xor(Node* node) { |
g.TempImmediate(0)); |
return; |
} |
- VisitBinop(this, node, kMipsXor); |
+ VisitBinop(this, node, kMipsXor, true, kMipsXor); |
} |
@@ -575,7 +616,7 @@ void InstructionSelector::VisitInt32Add(Node* node) { |
} |
} |
- VisitBinop(this, node, kMipsAdd); |
+ VisitBinop(this, node, kMipsAdd, true, kMipsAdd); |
} |