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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 return !isolate->heap()->InNewSpace(*value); | 79 return !isolate->heap()->InNewSpace(*value); |
80 #endif | 80 #endif |
81 } | 81 } |
82 default: | 82 default: |
83 return false; | 83 return false; |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
87 AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base, | 87 AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base, |
88 Node* displacement_node, | 88 Node* displacement_node, |
| 89 DisplacementMode displacement_mode, |
89 InstructionOperand inputs[], | 90 InstructionOperand inputs[], |
90 size_t* input_count) { | 91 size_t* input_count) { |
91 AddressingMode mode = kMode_MRI; | 92 AddressingMode mode = kMode_MRI; |
92 int32_t displacement = (displacement_node == nullptr) | 93 int32_t displacement = (displacement_node == nullptr) |
93 ? 0 | 94 ? 0 |
94 : OpParameter<int32_t>(displacement_node); | 95 : OpParameter<int32_t>(displacement_node); |
| 96 if (displacement_mode == kNegativeDisplacement) { |
| 97 displacement = -displacement; |
| 98 } |
95 if (base != nullptr) { | 99 if (base != nullptr) { |
96 if (base->opcode() == IrOpcode::kInt32Constant) { | 100 if (base->opcode() == IrOpcode::kInt32Constant) { |
97 displacement += OpParameter<int32_t>(base); | 101 displacement += OpParameter<int32_t>(base); |
98 base = nullptr; | 102 base = nullptr; |
99 } | 103 } |
100 } | 104 } |
101 if (base != nullptr) { | 105 if (base != nullptr) { |
102 inputs[(*input_count)++] = UseRegister(base); | 106 inputs[(*input_count)++] = UseRegister(base); |
103 if (index != nullptr) { | 107 if (index != nullptr) { |
104 DCHECK(scale >= 0 && scale <= 3); | 108 DCHECK(scale >= 0 && scale <= 3); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } | 146 } |
143 return mode; | 147 return mode; |
144 } | 148 } |
145 | 149 |
146 AddressingMode GetEffectiveAddressMemoryOperand(Node* node, | 150 AddressingMode GetEffectiveAddressMemoryOperand(Node* node, |
147 InstructionOperand inputs[], | 151 InstructionOperand inputs[], |
148 size_t* input_count) { | 152 size_t* input_count) { |
149 BaseWithIndexAndDisplacement32Matcher m(node, true); | 153 BaseWithIndexAndDisplacement32Matcher m(node, true); |
150 DCHECK(m.matches()); | 154 DCHECK(m.matches()); |
151 if ((m.displacement() == nullptr || CanBeImmediate(m.displacement()))) { | 155 if ((m.displacement() == nullptr || CanBeImmediate(m.displacement()))) { |
152 return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(), | 156 return GenerateMemoryOperandInputs( |
153 m.displacement(), inputs, input_count); | 157 m.index(), m.scale(), m.base(), m.displacement(), |
| 158 m.displacement_mode(), inputs, input_count); |
154 } else { | 159 } else { |
155 inputs[(*input_count)++] = UseRegister(node->InputAt(0)); | 160 inputs[(*input_count)++] = UseRegister(node->InputAt(0)); |
156 inputs[(*input_count)++] = UseRegister(node->InputAt(1)); | 161 inputs[(*input_count)++] = UseRegister(node->InputAt(1)); |
157 return kMode_MR1; | 162 return kMode_MR1; |
158 } | 163 } |
159 } | 164 } |
160 | 165 |
161 bool CanBeBetterLeftOperand(Node* node) const { | 166 bool CanBeBetterLeftOperand(Node* node) const { |
162 return !selector()->IsLive(node); | 167 return !selector()->IsLive(node); |
163 } | 168 } |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 | 536 |
532 void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { | 537 void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { |
533 X87OperandGenerator g(selector); | 538 X87OperandGenerator g(selector); |
534 InstructionOperand temps[] = {g.TempRegister(eax)}; | 539 InstructionOperand temps[] = {g.TempRegister(eax)}; |
535 selector->Emit(opcode, g.DefineAsFixed(node, edx), | 540 selector->Emit(opcode, g.DefineAsFixed(node, edx), |
536 g.UseFixed(node->InputAt(0), eax), | 541 g.UseFixed(node->InputAt(0), eax), |
537 g.UseUnique(node->InputAt(1)), arraysize(temps), temps); | 542 g.UseUnique(node->InputAt(1)), arraysize(temps), temps); |
538 } | 543 } |
539 | 544 |
540 void EmitLea(InstructionSelector* selector, Node* result, Node* index, | 545 void EmitLea(InstructionSelector* selector, Node* result, Node* index, |
541 int scale, Node* base, Node* displacement) { | 546 int scale, Node* base, Node* displacement, |
| 547 DisplacementMode displacement_mode) { |
542 X87OperandGenerator g(selector); | 548 X87OperandGenerator g(selector); |
543 InstructionOperand inputs[4]; | 549 InstructionOperand inputs[4]; |
544 size_t input_count = 0; | 550 size_t input_count = 0; |
545 AddressingMode mode = g.GenerateMemoryOperandInputs( | 551 AddressingMode mode = |
546 index, scale, base, displacement, inputs, &input_count); | 552 g.GenerateMemoryOperandInputs(index, scale, base, displacement, |
| 553 displacement_mode, inputs, &input_count); |
547 | 554 |
548 DCHECK_NE(0u, input_count); | 555 DCHECK_NE(0u, input_count); |
549 DCHECK_GE(arraysize(inputs), input_count); | 556 DCHECK_GE(arraysize(inputs), input_count); |
550 | 557 |
551 InstructionOperand outputs[1]; | 558 InstructionOperand outputs[1]; |
552 outputs[0] = g.DefineAsRegister(result); | 559 outputs[0] = g.DefineAsRegister(result); |
553 | 560 |
554 InstructionCode opcode = AddressingModeField::encode(mode) | kX87Lea; | 561 InstructionCode opcode = AddressingModeField::encode(mode) | kX87Lea; |
555 | 562 |
556 selector->Emit(opcode, 1, outputs, input_count, inputs); | 563 selector->Emit(opcode, 1, outputs, input_count, inputs); |
557 } | 564 } |
558 | 565 |
559 } // namespace | 566 } // namespace |
560 | 567 |
561 | 568 |
562 void InstructionSelector::VisitWord32Shl(Node* node) { | 569 void InstructionSelector::VisitWord32Shl(Node* node) { |
563 Int32ScaleMatcher m(node, true); | 570 Int32ScaleMatcher m(node, true); |
564 if (m.matches()) { | 571 if (m.matches()) { |
565 Node* index = node->InputAt(0); | 572 Node* index = node->InputAt(0); |
566 Node* base = m.power_of_two_plus_one() ? index : nullptr; | 573 Node* base = m.power_of_two_plus_one() ? index : nullptr; |
567 EmitLea(this, node, index, m.scale(), base, nullptr); | 574 EmitLea(this, node, index, m.scale(), base, nullptr, kPositiveDisplacement); |
568 return; | 575 return; |
569 } | 576 } |
570 VisitShift(this, node, kX87Shl); | 577 VisitShift(this, node, kX87Shl); |
571 } | 578 } |
572 | 579 |
573 | 580 |
574 void InstructionSelector::VisitWord32Shr(Node* node) { | 581 void InstructionSelector::VisitWord32Shr(Node* node) { |
575 VisitShift(this, node, kX87Shr); | 582 VisitShift(this, node, kX87Shr); |
576 } | 583 } |
577 | 584 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 void InstructionSelector::VisitInt32Add(Node* node) { | 701 void InstructionSelector::VisitInt32Add(Node* node) { |
695 X87OperandGenerator g(this); | 702 X87OperandGenerator g(this); |
696 | 703 |
697 // Try to match the Add to a lea pattern | 704 // Try to match the Add to a lea pattern |
698 BaseWithIndexAndDisplacement32Matcher m(node); | 705 BaseWithIndexAndDisplacement32Matcher m(node); |
699 if (m.matches() && | 706 if (m.matches() && |
700 (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) { | 707 (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) { |
701 InstructionOperand inputs[4]; | 708 InstructionOperand inputs[4]; |
702 size_t input_count = 0; | 709 size_t input_count = 0; |
703 AddressingMode mode = g.GenerateMemoryOperandInputs( | 710 AddressingMode mode = g.GenerateMemoryOperandInputs( |
704 m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count); | 711 m.index(), m.scale(), m.base(), m.displacement(), m.displacement_mode(), |
| 712 inputs, &input_count); |
705 | 713 |
706 DCHECK_NE(0u, input_count); | 714 DCHECK_NE(0u, input_count); |
707 DCHECK_GE(arraysize(inputs), input_count); | 715 DCHECK_GE(arraysize(inputs), input_count); |
708 | 716 |
709 InstructionOperand outputs[1]; | 717 InstructionOperand outputs[1]; |
710 outputs[0] = g.DefineAsRegister(node); | 718 outputs[0] = g.DefineAsRegister(node); |
711 | 719 |
712 InstructionCode opcode = AddressingModeField::encode(mode) | kX87Lea; | 720 InstructionCode opcode = AddressingModeField::encode(mode) | kX87Lea; |
713 Emit(opcode, 1, outputs, input_count, inputs); | 721 Emit(opcode, 1, outputs, input_count, inputs); |
714 return; | 722 return; |
(...skipping 13 matching lines...) Expand all Loading... |
728 VisitBinop(this, node, kX87Sub); | 736 VisitBinop(this, node, kX87Sub); |
729 } | 737 } |
730 } | 738 } |
731 | 739 |
732 | 740 |
733 void InstructionSelector::VisitInt32Mul(Node* node) { | 741 void InstructionSelector::VisitInt32Mul(Node* node) { |
734 Int32ScaleMatcher m(node, true); | 742 Int32ScaleMatcher m(node, true); |
735 if (m.matches()) { | 743 if (m.matches()) { |
736 Node* index = node->InputAt(0); | 744 Node* index = node->InputAt(0); |
737 Node* base = m.power_of_two_plus_one() ? index : nullptr; | 745 Node* base = m.power_of_two_plus_one() ? index : nullptr; |
738 EmitLea(this, node, index, m.scale(), base, nullptr); | 746 EmitLea(this, node, index, m.scale(), base, nullptr, kPositiveDisplacement); |
739 return; | 747 return; |
740 } | 748 } |
741 X87OperandGenerator g(this); | 749 X87OperandGenerator g(this); |
742 Node* left = node->InputAt(0); | 750 Node* left = node->InputAt(0); |
743 Node* right = node->InputAt(1); | 751 Node* right = node->InputAt(1); |
744 if (g.CanBeImmediate(right)) { | 752 if (g.CanBeImmediate(right)) { |
745 Emit(kX87Imul, g.DefineAsRegister(node), g.Use(left), | 753 Emit(kX87Imul, g.DefineAsRegister(node), g.Use(left), |
746 g.UseImmediate(right)); | 754 g.UseImmediate(right)); |
747 } else { | 755 } else { |
748 if (g.CanBeBetterLeftOperand(right)) { | 756 if (g.CanBeBetterLeftOperand(right)) { |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1709 // static | 1717 // static |
1710 MachineOperatorBuilder::AlignmentRequirements | 1718 MachineOperatorBuilder::AlignmentRequirements |
1711 InstructionSelector::AlignmentRequirements() { | 1719 InstructionSelector::AlignmentRequirements() { |
1712 return MachineOperatorBuilder::AlignmentRequirements:: | 1720 return MachineOperatorBuilder::AlignmentRequirements:: |
1713 FullUnalignedAccessSupport(); | 1721 FullUnalignedAccessSupport(); |
1714 } | 1722 } |
1715 | 1723 |
1716 } // namespace compiler | 1724 } // namespace compiler |
1717 } // namespace internal | 1725 } // namespace internal |
1718 } // namespace v8 | 1726 } // namespace v8 |
OLD | NEW |