Index: src/compiler/x87/instruction-selector-x87.cc |
diff --git a/src/compiler/x87/instruction-selector-x87.cc b/src/compiler/x87/instruction-selector-x87.cc |
index a103957405ac65c0447ea26f1dd45908aaf49612..8807f6546f1b4594b466f7923b6917228924c933 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<int32_t>(displacement_node); |
+ if (displacement_mode == kNegativeDisplacement) { |
+ displacement = -displacement; |
+ } |
if (base != nullptr) { |
if (base->opcode() == IrOpcode::kInt32Constant) { |
displacement += OpParameter<int32_t>(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); |