OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |