Commit a71ebb88 authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: [turbofan] Support subtraction displacements in BaseWithIndexAndDisplacementMatcher.

  port 574f6fe1 (r37701)

  original commit message:
  Previously, the following schedule fragment:

   1: Parameter[0](0)
   2: Parameter[1](0)
   7: Int32Constant[1]
   8: Int32Sub(2, 7)
   9: Load[kRepTagged|kTypeAny](1, 8)

  would generate the following code (on ia32):

   mov eax,[ebp+0x8]
   mov ecx,[ebp+0xc]
   sub eax,0x1
   mov eax,[eax+ecx*1]

  Now it generates:

   mov eax,[ebp+0x8]
   mov ecx,[ebp+0xc]
   mov eax,[eax+ecx*1-1]

  Similar pattern matching also now works on x64.

BUG=

Review-Url: https://codereview.chromium.org/2151753002
Cr-Commit-Position: refs/heads/master@{#37738}
parent a3b38885
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment