Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: src/compiler/ia32/instruction-selector-ia32.cc

Issue 2137323003: [turbofan] Support subtraction displacements in BaseWithIndexAndDisplacementMatcher (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review feedback Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/instruction-selector-impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/compiler/instruction-selector-impl.h" 6 #include "src/compiler/instruction-selector-impl.h"
7 #include "src/compiler/node-matchers.h" 7 #include "src/compiler/node-matchers.h"
8 #include "src/compiler/node-properties.h" 8 #include "src/compiler/node-properties.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 return !isolate->heap()->InNewSpace(*value); 75 return !isolate->heap()->InNewSpace(*value);
76 #endif 76 #endif
77 } 77 }
78 default: 78 default:
79 return false; 79 return false;
80 } 80 }
81 } 81 }
82 82
83 AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base, 83 AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base,
84 Node* displacement_node, 84 Node* displacement_node,
85 DisplacementMode displacement_mode,
85 InstructionOperand inputs[], 86 InstructionOperand inputs[],
86 size_t* input_count) { 87 size_t* input_count) {
87 AddressingMode mode = kMode_MRI; 88 AddressingMode mode = kMode_MRI;
88 int32_t displacement = (displacement_node == nullptr) 89 int32_t displacement = (displacement_node == nullptr)
89 ? 0 90 ? 0
90 : OpParameter<int32_t>(displacement_node); 91 : OpParameter<int32_t>(displacement_node);
92 if (displacement_mode == kNegativeDisplacement) {
93 displacement = -displacement;
94 }
91 if (base != nullptr) { 95 if (base != nullptr) {
92 if (base->opcode() == IrOpcode::kInt32Constant) { 96 if (base->opcode() == IrOpcode::kInt32Constant) {
93 displacement += OpParameter<int32_t>(base); 97 displacement += OpParameter<int32_t>(base);
94 base = nullptr; 98 base = nullptr;
95 } 99 }
96 } 100 }
97 if (base != nullptr) { 101 if (base != nullptr) {
98 inputs[(*input_count)++] = UseRegister(base); 102 inputs[(*input_count)++] = UseRegister(base);
99 if (index != nullptr) { 103 if (index != nullptr) {
100 DCHECK(scale >= 0 && scale <= 3); 104 DCHECK(scale >= 0 && scale <= 3);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 } 142 }
139 return mode; 143 return mode;
140 } 144 }
141 145
142 AddressingMode GetEffectiveAddressMemoryOperand(Node* node, 146 AddressingMode GetEffectiveAddressMemoryOperand(Node* node,
143 InstructionOperand inputs[], 147 InstructionOperand inputs[],
144 size_t* input_count) { 148 size_t* input_count) {
145 BaseWithIndexAndDisplacement32Matcher m(node, true); 149 BaseWithIndexAndDisplacement32Matcher m(node, true);
146 DCHECK(m.matches()); 150 DCHECK(m.matches());
147 if ((m.displacement() == nullptr || CanBeImmediate(m.displacement()))) { 151 if ((m.displacement() == nullptr || CanBeImmediate(m.displacement()))) {
148 return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(), 152 return GenerateMemoryOperandInputs(
149 m.displacement(), inputs, input_count); 153 m.index(), m.scale(), m.base(), m.displacement(),
154 m.displacement_mode(), inputs, input_count);
150 } else { 155 } else {
151 inputs[(*input_count)++] = UseRegister(node->InputAt(0)); 156 inputs[(*input_count)++] = UseRegister(node->InputAt(0));
152 inputs[(*input_count)++] = UseRegister(node->InputAt(1)); 157 inputs[(*input_count)++] = UseRegister(node->InputAt(1));
153 return kMode_MR1; 158 return kMode_MR1;
154 } 159 }
155 } 160 }
156 161
157 bool CanBeBetterLeftOperand(Node* node) const { 162 bool CanBeBetterLeftOperand(Node* node) const {
158 return !selector()->IsLive(node); 163 return !selector()->IsLive(node);
159 } 164 }
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 575
571 void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { 576 void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
572 IA32OperandGenerator g(selector); 577 IA32OperandGenerator g(selector);
573 InstructionOperand temps[] = {g.TempRegister(eax)}; 578 InstructionOperand temps[] = {g.TempRegister(eax)};
574 selector->Emit(opcode, g.DefineAsFixed(node, edx), 579 selector->Emit(opcode, g.DefineAsFixed(node, edx),
575 g.UseFixed(node->InputAt(0), eax), 580 g.UseFixed(node->InputAt(0), eax),
576 g.UseUnique(node->InputAt(1)), arraysize(temps), temps); 581 g.UseUnique(node->InputAt(1)), arraysize(temps), temps);
577 } 582 }
578 583
579 void EmitLea(InstructionSelector* selector, Node* result, Node* index, 584 void EmitLea(InstructionSelector* selector, Node* result, Node* index,
580 int scale, Node* base, Node* displacement) { 585 int scale, Node* base, Node* displacement,
586 DisplacementMode displacement_mode) {
581 IA32OperandGenerator g(selector); 587 IA32OperandGenerator g(selector);
582 InstructionOperand inputs[4]; 588 InstructionOperand inputs[4];
583 size_t input_count = 0; 589 size_t input_count = 0;
584 AddressingMode mode = g.GenerateMemoryOperandInputs( 590 AddressingMode mode =
585 index, scale, base, displacement, inputs, &input_count); 591 g.GenerateMemoryOperandInputs(index, scale, base, displacement,
592 displacement_mode, inputs, &input_count);
586 593
587 DCHECK_NE(0u, input_count); 594 DCHECK_NE(0u, input_count);
588 DCHECK_GE(arraysize(inputs), input_count); 595 DCHECK_GE(arraysize(inputs), input_count);
589 596
590 InstructionOperand outputs[1]; 597 InstructionOperand outputs[1];
591 outputs[0] = g.DefineAsRegister(result); 598 outputs[0] = g.DefineAsRegister(result);
592 599
593 InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea; 600 InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
594 601
595 selector->Emit(opcode, 1, outputs, input_count, inputs); 602 selector->Emit(opcode, 1, outputs, input_count, inputs);
596 } 603 }
597 604
598 } // namespace 605 } // namespace
599 606
600 607
601 void InstructionSelector::VisitWord32Shl(Node* node) { 608 void InstructionSelector::VisitWord32Shl(Node* node) {
602 Int32ScaleMatcher m(node, true); 609 Int32ScaleMatcher m(node, true);
603 if (m.matches()) { 610 if (m.matches()) {
604 Node* index = node->InputAt(0); 611 Node* index = node->InputAt(0);
605 Node* base = m.power_of_two_plus_one() ? index : nullptr; 612 Node* base = m.power_of_two_plus_one() ? index : nullptr;
606 EmitLea(this, node, index, m.scale(), base, nullptr); 613 EmitLea(this, node, index, m.scale(), base, nullptr, kPositiveDisplacement);
607 return; 614 return;
608 } 615 }
609 VisitShift(this, node, kIA32Shl); 616 VisitShift(this, node, kIA32Shl);
610 } 617 }
611 618
612 619
613 void InstructionSelector::VisitWord32Shr(Node* node) { 620 void InstructionSelector::VisitWord32Shr(Node* node) {
614 VisitShift(this, node, kIA32Shr); 621 VisitShift(this, node, kIA32Shr);
615 } 622 }
616 623
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 void InstructionSelector::VisitInt32Add(Node* node) { 743 void InstructionSelector::VisitInt32Add(Node* node) {
737 IA32OperandGenerator g(this); 744 IA32OperandGenerator g(this);
738 745
739 // Try to match the Add to a lea pattern 746 // Try to match the Add to a lea pattern
740 BaseWithIndexAndDisplacement32Matcher m(node); 747 BaseWithIndexAndDisplacement32Matcher m(node);
741 if (m.matches() && 748 if (m.matches() &&
742 (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) { 749 (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) {
743 InstructionOperand inputs[4]; 750 InstructionOperand inputs[4];
744 size_t input_count = 0; 751 size_t input_count = 0;
745 AddressingMode mode = g.GenerateMemoryOperandInputs( 752 AddressingMode mode = g.GenerateMemoryOperandInputs(
746 m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count); 753 m.index(), m.scale(), m.base(), m.displacement(), m.displacement_mode(),
754 inputs, &input_count);
747 755
748 DCHECK_NE(0u, input_count); 756 DCHECK_NE(0u, input_count);
749 DCHECK_GE(arraysize(inputs), input_count); 757 DCHECK_GE(arraysize(inputs), input_count);
750 758
751 InstructionOperand outputs[1]; 759 InstructionOperand outputs[1];
752 outputs[0] = g.DefineAsRegister(node); 760 outputs[0] = g.DefineAsRegister(node);
753 761
754 InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea; 762 InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
755 Emit(opcode, 1, outputs, input_count, inputs); 763 Emit(opcode, 1, outputs, input_count, inputs);
756 return; 764 return;
(...skipping 13 matching lines...) Expand all
770 VisitBinop(this, node, kIA32Sub); 778 VisitBinop(this, node, kIA32Sub);
771 } 779 }
772 } 780 }
773 781
774 782
775 void InstructionSelector::VisitInt32Mul(Node* node) { 783 void InstructionSelector::VisitInt32Mul(Node* node) {
776 Int32ScaleMatcher m(node, true); 784 Int32ScaleMatcher m(node, true);
777 if (m.matches()) { 785 if (m.matches()) {
778 Node* index = node->InputAt(0); 786 Node* index = node->InputAt(0);
779 Node* base = m.power_of_two_plus_one() ? index : nullptr; 787 Node* base = m.power_of_two_plus_one() ? index : nullptr;
780 EmitLea(this, node, index, m.scale(), base, nullptr); 788 EmitLea(this, node, index, m.scale(), base, nullptr, kPositiveDisplacement);
781 return; 789 return;
782 } 790 }
783 IA32OperandGenerator g(this); 791 IA32OperandGenerator g(this);
784 Node* left = node->InputAt(0); 792 Node* left = node->InputAt(0);
785 Node* right = node->InputAt(1); 793 Node* right = node->InputAt(1);
786 if (g.CanBeImmediate(right)) { 794 if (g.CanBeImmediate(right)) {
787 Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left), 795 Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left),
788 g.UseImmediate(right)); 796 g.UseImmediate(right));
789 } else { 797 } else {
790 if (g.CanBeBetterLeftOperand(right)) { 798 if (g.CanBeBetterLeftOperand(right)) {
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 // static 1690 // static
1683 MachineOperatorBuilder::AlignmentRequirements 1691 MachineOperatorBuilder::AlignmentRequirements
1684 InstructionSelector::AlignmentRequirements() { 1692 InstructionSelector::AlignmentRequirements() {
1685 return MachineOperatorBuilder::AlignmentRequirements:: 1693 return MachineOperatorBuilder::AlignmentRequirements::
1686 FullUnalignedAccessSupport(); 1694 FullUnalignedAccessSupport();
1687 } 1695 }
1688 1696
1689 } // namespace compiler 1697 } // namespace compiler
1690 } // namespace internal 1698 } // namespace internal
1691 } // namespace v8 1699 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/instruction-selector-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698