diff --git a/src/compiler/x87/instruction-selector-x87.cc b/src/compiler/x87/instruction-selector-x87.cc index a103957405..8807f6546f 100644 --- a/src/compiler/x87/instruction-selector-x87.cc +++ b/src/compiler/x87/instruction-selector-x87.cc @@ -86,12 +86,16 @@ class X87OperandGenerator final : public OperandGenerator { AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base, Node* displacement_node, + DisplacementMode displacement_mode, InstructionOperand inputs[], size_t* input_count) { AddressingMode mode = kMode_MRI; int32_t displacement = (displacement_node == nullptr) ? 0 : OpParameter(displacement_node); + if (displacement_mode == kNegativeDisplacement) { + displacement = -displacement; + } if (base != nullptr) { if (base->opcode() == IrOpcode::kInt32Constant) { displacement += OpParameter(base); @@ -149,8 +153,9 @@ class X87OperandGenerator final : public OperandGenerator { BaseWithIndexAndDisplacement32Matcher m(node, true); DCHECK(m.matches()); if ((m.displacement() == nullptr || CanBeImmediate(m.displacement()))) { - return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(), - m.displacement(), inputs, input_count); + return GenerateMemoryOperandInputs( + m.index(), m.scale(), m.base(), m.displacement(), + m.displacement_mode(), inputs, input_count); } else { inputs[(*input_count)++] = UseRegister(node->InputAt(0)); inputs[(*input_count)++] = UseRegister(node->InputAt(1)); @@ -538,12 +543,14 @@ void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { } void EmitLea(InstructionSelector* selector, Node* result, Node* index, - int scale, Node* base, Node* displacement) { + int scale, Node* base, Node* displacement, + DisplacementMode displacement_mode) { X87OperandGenerator g(selector); InstructionOperand inputs[4]; size_t input_count = 0; - AddressingMode mode = g.GenerateMemoryOperandInputs( - index, scale, base, displacement, inputs, &input_count); + AddressingMode mode = + g.GenerateMemoryOperandInputs(index, scale, base, displacement, + displacement_mode, inputs, &input_count); DCHECK_NE(0u, input_count); DCHECK_GE(arraysize(inputs), input_count); @@ -564,7 +571,7 @@ void InstructionSelector::VisitWord32Shl(Node* node) { if (m.matches()) { Node* index = node->InputAt(0); Node* base = m.power_of_two_plus_one() ? index : nullptr; - EmitLea(this, node, index, m.scale(), base, nullptr); + EmitLea(this, node, index, m.scale(), base, nullptr, kPositiveDisplacement); return; } VisitShift(this, node, kX87Shl); @@ -701,7 +708,8 @@ void InstructionSelector::VisitInt32Add(Node* node) { InstructionOperand inputs[4]; size_t input_count = 0; AddressingMode mode = g.GenerateMemoryOperandInputs( - m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count); + m.index(), m.scale(), m.base(), m.displacement(), m.displacement_mode(), + inputs, &input_count); DCHECK_NE(0u, input_count); DCHECK_GE(arraysize(inputs), input_count); @@ -735,7 +743,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { if (m.matches()) { Node* index = node->InputAt(0); Node* base = m.power_of_two_plus_one() ? index : nullptr; - EmitLea(this, node, index, m.scale(), base, nullptr); + EmitLea(this, node, index, m.scale(), base, nullptr, kPositiveDisplacement); return; } X87OperandGenerator g(this);