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