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 |