| Index: src/compiler/mips64/instruction-selector-mips64.cc
|
| diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc
|
| index 6f72c6451d1fb920c0aae444f7cf1dbeb3ff6182..56bb80ec98c817495a5b8d397e01f2fa0b4a2165 100644
|
| --- a/src/compiler/mips64/instruction-selector-mips64.cc
|
| +++ b/src/compiler/mips64/instruction-selector-mips64.cc
|
| @@ -59,6 +59,12 @@ class Mips64OperandGenerator final : public OperandGenerator {
|
| case kMips64Dsar:
|
| case kMips64Dshr:
|
| return is_uint6(value);
|
| + case kMips64Add:
|
| + case kMips64And32:
|
| + case kMips64And:
|
| + case kMips64Dadd:
|
| + case kMips64Or32:
|
| + case kMips64Or:
|
| case kMips64Xor:
|
| return is_uint16(value);
|
| case kMips64Ldc1:
|
| @@ -173,8 +179,23 @@ bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node) {
|
| return false;
|
| }
|
|
|
| +bool TryMatchImmediate(InstructionSelector* selector,
|
| + InstructionCode* opcode_return, Node* node,
|
| + size_t* input_count_return, InstructionOperand* inputs) {
|
| + Mips64OperandGenerator 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) {
|
| Mips64OperandGenerator g(selector);
|
| Int32BinopMatcher m(node);
|
| InstructionOperand inputs[4];
|
| @@ -182,8 +203,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());
|
| @@ -216,11 +250,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);
|
| }
|
|
|
| void EmitLoad(InstructionSelector* selector, Node* node, InstructionCode opcode,
|
| @@ -415,7 +459,7 @@ void InstructionSelector::VisitWord32And(Node* node) {
|
| return;
|
| }
|
| }
|
| - VisitBinop(this, node, kMips64And32);
|
| + VisitBinop(this, node, kMips64And32, true, kMips64And32);
|
| }
|
|
|
|
|
| @@ -466,17 +510,17 @@ void InstructionSelector::VisitWord64And(Node* node) {
|
| return;
|
| }
|
| }
|
| - VisitBinop(this, node, kMips64And);
|
| + VisitBinop(this, node, kMips64And, true, kMips64And);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitWord32Or(Node* node) {
|
| - VisitBinop(this, node, kMips64Or32);
|
| + VisitBinop(this, node, kMips64Or32, true, kMips64Or32);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitWord64Or(Node* node) {
|
| - VisitBinop(this, node, kMips64Or);
|
| + VisitBinop(this, node, kMips64Or, true, kMips64Or);
|
| }
|
|
|
|
|
| @@ -500,7 +544,7 @@ void InstructionSelector::VisitWord32Xor(Node* node) {
|
| g.TempImmediate(0));
|
| return;
|
| }
|
| - VisitBinop(this, node, kMips64Xor32);
|
| + VisitBinop(this, node, kMips64Xor32, true, kMips64Xor32);
|
| }
|
|
|
|
|
| @@ -524,7 +568,7 @@ void InstructionSelector::VisitWord64Xor(Node* node) {
|
| g.TempImmediate(0));
|
| return;
|
| }
|
| - VisitBinop(this, node, kMips64Xor);
|
| + VisitBinop(this, node, kMips64Xor, true, kMips64Xor);
|
| }
|
|
|
|
|
| @@ -774,7 +818,7 @@ void InstructionSelector::VisitInt32Add(Node* node) {
|
| return;
|
| }
|
| }
|
| - VisitBinop(this, node, kMips64Add);
|
| + VisitBinop(this, node, kMips64Add, true, kMips64Add);
|
| }
|
|
|
|
|
| @@ -808,7 +852,7 @@ void InstructionSelector::VisitInt64Add(Node* node) {
|
| }
|
| }
|
|
|
| - VisitBinop(this, node, kMips64Dadd);
|
| + VisitBinop(this, node, kMips64Dadd, true, kMips64Dadd);
|
| }
|
|
|
|
|
|
|