| 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 d26b8a28c4bb880d7ecb52cb4a3d958baad10979..ac881b681c2abc640ec8e364b5b02b30886a83b4 100644
|
| --- a/src/compiler/mips/instruction-selector-mips.cc
|
| +++ b/src/compiler/mips/instruction-selector-mips.cc
|
| @@ -31,6 +31,39 @@ class MipsOperandGenerator final : public OperandGenerator {
|
| return UseRegister(node);
|
| }
|
|
|
| + // Use the zero register if the node has the immediate value zero, otherwise
|
| + // assign a register.
|
| + InstructionOperand UseRegisterOrImmediateZero(Node* node) {
|
| + if ((IsIntegerConstant(node) && (GetIntegerConstantValue(node) == 0)) ||
|
| + (IsFloatConstant(node) &&
|
| + (bit_cast<int64_t>(GetFloatConstantValue(node)) == V8_INT64_C(0)))) {
|
| + return UseImmediate(node);
|
| + }
|
| + return UseRegister(node);
|
| + }
|
| +
|
| + bool IsIntegerConstant(Node* node) {
|
| + return (node->opcode() == IrOpcode::kInt32Constant);
|
| + }
|
| +
|
| + int64_t GetIntegerConstantValue(Node* node) {
|
| + DCHECK(node->opcode() == IrOpcode::kInt32Constant);
|
| + return OpParameter<int32_t>(node);
|
| + }
|
| +
|
| + bool IsFloatConstant(Node* node) {
|
| + return (node->opcode() == IrOpcode::kFloat32Constant) ||
|
| + (node->opcode() == IrOpcode::kFloat64Constant);
|
| + }
|
| +
|
| + double GetFloatConstantValue(Node* node) {
|
| + if (node->opcode() == IrOpcode::kFloat32Constant) {
|
| + return OpParameter<float>(node);
|
| + }
|
| + DCHECK_EQ(IrOpcode::kFloat64Constant, node->opcode());
|
| + return OpParameter<double>(node);
|
| + }
|
| +
|
| bool CanBeImmediate(Node* node, InstructionCode opcode) {
|
| Int32Matcher m(node);
|
| if (!m.HasValue()) return false;
|
| @@ -300,14 +333,15 @@ void InstructionSelector::VisitStore(Node* node) {
|
|
|
| if (g.CanBeImmediate(index, opcode)) {
|
| Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
|
| - g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
|
| + g.UseRegister(base), g.UseImmediate(index),
|
| + g.UseRegisterOrImmediateZero(value));
|
| } else {
|
| InstructionOperand addr_reg = g.TempRegister();
|
| Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
|
| g.UseRegister(index), g.UseRegister(base));
|
| // Emit desired store opcode, using temp addr_reg.
|
| Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
|
| - addr_reg, g.TempImmediate(0), g.UseRegister(value));
|
| + addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
|
| }
|
| }
|
| }
|
| @@ -1232,14 +1266,15 @@ void InstructionSelector::VisitUnalignedStore(Node* node) {
|
|
|
| if (g.CanBeImmediate(index, opcode)) {
|
| Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
|
| - g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
|
| + g.UseRegister(base), g.UseImmediate(index),
|
| + g.UseRegisterOrImmediateZero(value));
|
| } else {
|
| InstructionOperand addr_reg = g.TempRegister();
|
| Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
|
| g.UseRegister(index), g.UseRegister(base));
|
| // Emit desired store opcode, using temp addr_reg.
|
| Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
|
| - addr_reg, g.TempImmediate(0), g.UseRegister(value));
|
| + addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
|
| }
|
| }
|
|
|
| @@ -1331,7 +1366,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
|
| : g.UseRegister(length);
|
|
|
| Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
|
| - offset_operand, length_operand, g.UseRegister(value),
|
| + offset_operand, length_operand, g.UseRegisterOrImmediateZero(value),
|
| g.UseRegister(buffer));
|
| }
|
|
|
| @@ -1802,14 +1837,15 @@ void InstructionSelector::VisitAtomicStore(Node* node) {
|
|
|
| if (g.CanBeImmediate(index, opcode)) {
|
| Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
|
| - g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
|
| + g.UseRegister(base), g.UseImmediate(index),
|
| + g.UseRegisterOrImmediateZero(value));
|
| } else {
|
| InstructionOperand addr_reg = g.TempRegister();
|
| Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
|
| g.UseRegister(index), g.UseRegister(base));
|
| // Emit desired store opcode, using temp addr_reg.
|
| Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
|
| - addr_reg, g.TempImmediate(0), g.UseRegister(value));
|
| + addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
|
| }
|
| }
|
|
|
|
|