| 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 |