| 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 e9e070fcad9d57795fe3740c4127ed66322bf145..8c779f69bfeba4f6782547863e235d74214d7d62 100644
|
| --- a/src/compiler/mips64/instruction-selector-mips64.cc
|
| +++ b/src/compiler/mips64/instruction-selector-mips64.cc
|
| @@ -31,6 +31,17 @@ class Mips64OperandGenerator 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) ||
|
| (node->opcode() == IrOpcode::kInt64Constant);
|
| @@ -44,6 +55,19 @@ class Mips64OperandGenerator final : public OperandGenerator {
|
| return OpParameter<int64_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 mode) {
|
| return IsIntegerConstant(node) &&
|
| CanBeImmediate(GetIntegerConstantValue(node), mode);
|
| @@ -400,14 +424,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(kMips64Dadd | 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));
|
| }
|
| }
|
| }
|
| @@ -1739,14 +1764,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(kMips64Dadd | 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));
|
| }
|
| }
|
|
|
| @@ -1848,7 +1874,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));
|
| }
|
|
|
| @@ -2491,14 +2517,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(kMips64Dadd | 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));
|
| }
|
| }
|
|
|
|
|