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)); |
} |
} |