| 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 60790b51b220e6fafa7821fd2bcb2097a62aa2fb..6d2b4d30b8cd9db29ca99d3698c07731f673c0aa 100644
|
| --- a/src/compiler/mips64/instruction-selector-mips64.cc
|
| +++ b/src/compiler/mips64/instruction-selector-mips64.cc
|
| @@ -142,12 +142,29 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
|
| VisitBinop(selector, node, opcode, &cont);
|
| }
|
|
|
| +void EmitLoad(InstructionSelector* selector, Node* node, InstructionCode opcode,
|
| + Node* output = nullptr) {
|
| + Mips64OperandGenerator g(selector);
|
| + Node* base = node->InputAt(0);
|
| + Node* index = node->InputAt(1);
|
| +
|
| + if (g.CanBeImmediate(index, opcode)) {
|
| + selector->Emit(opcode | AddressingModeField::encode(kMode_MRI),
|
| + g.DefineAsRegister(output == nullptr ? node : output),
|
| + g.UseRegister(base), g.UseImmediate(index));
|
| + } else {
|
| + InstructionOperand addr_reg = g.TempRegister();
|
| + selector->Emit(kMips64Dadd | AddressingModeField::encode(kMode_None),
|
| + addr_reg, g.UseRegister(index), g.UseRegister(base));
|
| + // Emit desired load opcode, using temp addr_reg.
|
| + selector->Emit(opcode | AddressingModeField::encode(kMode_MRI),
|
| + g.DefineAsRegister(output == nullptr ? node : output),
|
| + addr_reg, g.TempImmediate(0));
|
| + }
|
| +}
|
|
|
| void InstructionSelector::VisitLoad(Node* node) {
|
| LoadRepresentation load_rep = LoadRepresentationOf(node->op());
|
| - Mips64OperandGenerator g(this);
|
| - Node* base = node->InputAt(0);
|
| - Node* index = node->InputAt(1);
|
|
|
| ArchOpcode opcode = kArchNop;
|
| switch (load_rep.representation()) {
|
| @@ -179,17 +196,7 @@ void InstructionSelector::VisitLoad(Node* node) {
|
| return;
|
| }
|
|
|
| - if (g.CanBeImmediate(index, opcode)) {
|
| - Emit(opcode | AddressingModeField::encode(kMode_MRI),
|
| - g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
|
| - } else {
|
| - InstructionOperand addr_reg = g.TempRegister();
|
| - Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
|
| - g.UseRegister(index), g.UseRegister(base));
|
| - // Emit desired load opcode, using temp addr_reg.
|
| - Emit(opcode | AddressingModeField::encode(kMode_MRI),
|
| - g.DefineAsRegister(node), addr_reg, g.TempImmediate(0));
|
| - }
|
| + EmitLoad(this, node, opcode);
|
| }
|
|
|
|
|
| @@ -501,7 +508,7 @@ void InstructionSelector::VisitWord64Shl(Node* node) {
|
| Mips64OperandGenerator g(this);
|
| Int64BinopMatcher m(node);
|
| if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) &&
|
| - m.right().IsInRange(32, 63)) {
|
| + m.right().IsInRange(32, 63) && CanCover(node, m.left().node())) {
|
| // There's no need to sign/zero-extend to 64-bit if we shift out the upper
|
| // 32 bits anyway.
|
| Emit(kMips64Dshl, g.DefineSameAsFirst(node),
|
| @@ -1064,9 +1071,32 @@ void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
|
|
|
|
|
| void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
|
| - Mips64OperandGenerator g(this);
|
| - Emit(kMips64Shl, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
|
| - g.TempImmediate(0));
|
| + Node* value = node->InputAt(0);
|
| + if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) {
|
| + // Generate sign-extending load.
|
| + LoadRepresentation load_rep = LoadRepresentationOf(value->op());
|
| + InstructionCode opcode = kArchNop;
|
| + switch (load_rep.representation()) {
|
| + case MachineRepresentation::kBit: // Fall through.
|
| + case MachineRepresentation::kWord8:
|
| + opcode = load_rep.IsUnsigned() ? kMips64Lbu : kMips64Lb;
|
| + break;
|
| + case MachineRepresentation::kWord16:
|
| + opcode = load_rep.IsUnsigned() ? kMips64Lhu : kMips64Lh;
|
| + break;
|
| + case MachineRepresentation::kWord32:
|
| + opcode = kMips64Lw;
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + return;
|
| + }
|
| + EmitLoad(this, value, opcode, node);
|
| + } else {
|
| + Mips64OperandGenerator g(this);
|
| + Emit(kMips64Shl, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
|
| + g.TempImmediate(0));
|
| + }
|
| }
|
|
|
|
|
|
|