| 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
| 8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 EmitLea(this, kX64Lea32, node, index, m.scale(), base, nullptr, | 588 EmitLea(this, kX64Lea32, node, index, m.scale(), base, nullptr, |
| 589 kPositiveDisplacement); | 589 kPositiveDisplacement); |
| 590 return; | 590 return; |
| 591 } | 591 } |
| 592 VisitWord32Shift(this, node, kX64Shl32); | 592 VisitWord32Shift(this, node, kX64Shl32); |
| 593 } | 593 } |
| 594 | 594 |
| 595 | 595 |
| 596 void InstructionSelector::VisitWord64Shl(Node* node) { | 596 void InstructionSelector::VisitWord64Shl(Node* node) { |
| 597 X64OperandGenerator g(this); | 597 X64OperandGenerator g(this); |
| 598 Int64BinopMatcher m(node); | 598 Int64ScaleMatcher m(node, true); |
| 599 if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) && | 599 if (m.matches()) { |
| 600 m.right().IsInRange(32, 63)) { | 600 Node* index = node->InputAt(0); |
| 601 // There's no need to sign/zero-extend to 64-bit if we shift out the upper | 601 Node* base = m.power_of_two_plus_one() ? index : nullptr; |
| 602 // 32 bits anyway. | 602 EmitLea(this, kX64Lea, node, index, m.scale(), base, nullptr, |
| 603 Emit(kX64Shl, g.DefineSameAsFirst(node), | 603 kPositiveDisplacement); |
| 604 g.UseRegister(m.left().node()->InputAt(0)), | |
| 605 g.UseImmediate(m.right().node())); | |
| 606 return; | 604 return; |
| 605 } else { |
| 606 Int64BinopMatcher m(node); |
| 607 if ((m.left().IsChangeInt32ToInt64() || |
| 608 m.left().IsChangeUint32ToUint64()) && |
| 609 m.right().IsInRange(32, 63)) { |
| 610 // There's no need to sign/zero-extend to 64-bit if we shift out the upper |
| 611 // 32 bits anyway. |
| 612 Emit(kX64Shl, g.DefineSameAsFirst(node), |
| 613 g.UseRegister(m.left().node()->InputAt(0)), |
| 614 g.UseImmediate(m.right().node())); |
| 615 return; |
| 616 } |
| 607 } | 617 } |
| 608 VisitWord64Shift(this, node, kX64Shl); | 618 VisitWord64Shift(this, node, kX64Shl); |
| 609 } | 619 } |
| 610 | 620 |
| 611 | 621 |
| 612 void InstructionSelector::VisitWord32Shr(Node* node) { | 622 void InstructionSelector::VisitWord32Shr(Node* node) { |
| 613 VisitWord32Shift(this, node, kX64Shr32); | 623 VisitWord32Shift(this, node, kX64Shr32); |
| 614 } | 624 } |
| 615 | 625 |
| 616 | 626 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 m.displacement(), m.displacement_mode()); | 783 m.displacement(), m.displacement_mode()); |
| 774 return; | 784 return; |
| 775 } | 785 } |
| 776 | 786 |
| 777 // No leal pattern match, use addl | 787 // No leal pattern match, use addl |
| 778 VisitBinop(this, node, kX64Add32); | 788 VisitBinop(this, node, kX64Add32); |
| 779 } | 789 } |
| 780 | 790 |
| 781 | 791 |
| 782 void InstructionSelector::VisitInt64Add(Node* node) { | 792 void InstructionSelector::VisitInt64Add(Node* node) { |
| 793 X64OperandGenerator g(this); |
| 794 |
| 795 // Try to match the Add to a leaq pattern |
| 796 BaseWithIndexAndDisplacement64Matcher m(node); |
| 797 if (m.matches() && |
| 798 (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) { |
| 799 EmitLea(this, kX64Lea, node, m.index(), m.scale(), m.base(), |
| 800 m.displacement(), m.displacement_mode()); |
| 801 return; |
| 802 } |
| 803 |
| 804 // No leal pattern match, use addq |
| 783 VisitBinop(this, node, kX64Add); | 805 VisitBinop(this, node, kX64Add); |
| 784 } | 806 } |
| 785 | 807 |
| 786 | 808 |
| 787 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { | 809 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { |
| 788 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 810 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 789 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); | 811 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
| 790 return VisitBinop(this, node, kX64Add, &cont); | 812 return VisitBinop(this, node, kX64Add, &cont); |
| 791 } | 813 } |
| 792 FlagsContinuation cont; | 814 FlagsContinuation cont; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 812 } | 834 } |
| 813 } | 835 } |
| 814 | 836 |
| 815 | 837 |
| 816 void InstructionSelector::VisitInt64Sub(Node* node) { | 838 void InstructionSelector::VisitInt64Sub(Node* node) { |
| 817 X64OperandGenerator g(this); | 839 X64OperandGenerator g(this); |
| 818 Int64BinopMatcher m(node); | 840 Int64BinopMatcher m(node); |
| 819 if (m.left().Is(0)) { | 841 if (m.left().Is(0)) { |
| 820 Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); | 842 Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); |
| 821 } else { | 843 } else { |
| 844 if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) { |
| 845 // Turn subtractions of constant values into immediate "leaq" instructions |
| 846 // by negating the value. |
| 847 Emit(kX64Lea | AddressingModeField::encode(kMode_MRI), |
| 848 g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
| 849 g.TempImmediate(-static_cast<int32_t>(m.right().Value()))); |
| 850 return; |
| 851 } |
| 822 VisitBinop(this, node, kX64Sub); | 852 VisitBinop(this, node, kX64Sub); |
| 823 } | 853 } |
| 824 } | 854 } |
| 825 | 855 |
| 826 | 856 |
| 827 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { | 857 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { |
| 828 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 858 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 829 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); | 859 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
| 830 return VisitBinop(this, node, kX64Sub, &cont); | 860 return VisitBinop(this, node, kX64Sub, &cont); |
| 831 } | 861 } |
| (...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2153 // static | 2183 // static |
| 2154 MachineOperatorBuilder::AlignmentRequirements | 2184 MachineOperatorBuilder::AlignmentRequirements |
| 2155 InstructionSelector::AlignmentRequirements() { | 2185 InstructionSelector::AlignmentRequirements() { |
| 2156 return MachineOperatorBuilder::AlignmentRequirements:: | 2186 return MachineOperatorBuilder::AlignmentRequirements:: |
| 2157 FullUnalignedAccessSupport(); | 2187 FullUnalignedAccessSupport(); |
| 2158 } | 2188 } |
| 2159 | 2189 |
| 2160 } // namespace compiler | 2190 } // namespace compiler |
| 2161 } // namespace internal | 2191 } // namespace internal |
| 2162 } // namespace v8 | 2192 } // namespace v8 |
| OLD | NEW |