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/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 | 845 |
846 // Select Mneg(x, y) for Mul(x, Sub(0, y)). | 846 // Select Mneg(x, y) for Mul(x, Sub(0, y)). |
847 if (mright.left().Is(0)) { | 847 if (mright.left().Is(0)) { |
848 Emit(kArm64Mneg32, g.DefineAsRegister(node), | 848 Emit(kArm64Mneg32, g.DefineAsRegister(node), |
849 g.UseRegister(m.left().node()), | 849 g.UseRegister(m.left().node()), |
850 g.UseRegister(mright.right().node())); | 850 g.UseRegister(mright.right().node())); |
851 return; | 851 return; |
852 } | 852 } |
853 } | 853 } |
854 | 854 |
| 855 // x * (2^k + 1) -> x + (x << k) |
| 856 if (m.right().HasValue() && m.right().Value() > 0) { |
| 857 int32_t value = m.right().Value(); |
| 858 if (base::bits::IsPowerOfTwo32(value - 1)) { |
| 859 Emit(kArm64Add32 | AddressingModeField::encode(kMode_Operand2_R_LSL_I), |
| 860 g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
| 861 g.UseRegister(m.left().node()), |
| 862 g.TempImmediate(WhichPowerOf2(value - 1))); |
| 863 return; |
| 864 } |
| 865 } |
| 866 |
855 VisitRRR(this, kArm64Mul32, node); | 867 VisitRRR(this, kArm64Mul32, node); |
856 } | 868 } |
857 | 869 |
858 | 870 |
859 void InstructionSelector::VisitInt64Mul(Node* node) { | 871 void InstructionSelector::VisitInt64Mul(Node* node) { |
860 Arm64OperandGenerator g(this); | 872 Arm64OperandGenerator g(this); |
861 Int64BinopMatcher m(node); | 873 Int64BinopMatcher m(node); |
862 | 874 |
863 if (m.left().IsInt64Sub() && CanCover(node, m.left().node())) { | 875 if (m.left().IsInt64Sub() && CanCover(node, m.left().node())) { |
864 Int64BinopMatcher mleft(m.left().node()); | 876 Int64BinopMatcher mleft(m.left().node()); |
(...skipping 11 matching lines...) Expand all Loading... |
876 Int64BinopMatcher mright(m.right().node()); | 888 Int64BinopMatcher mright(m.right().node()); |
877 | 889 |
878 // Select Mneg(x, y) for Mul(x, Sub(0, y)). | 890 // Select Mneg(x, y) for Mul(x, Sub(0, y)). |
879 if (mright.left().Is(0)) { | 891 if (mright.left().Is(0)) { |
880 Emit(kArm64Mneg, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 892 Emit(kArm64Mneg, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
881 g.UseRegister(mright.right().node())); | 893 g.UseRegister(mright.right().node())); |
882 return; | 894 return; |
883 } | 895 } |
884 } | 896 } |
885 | 897 |
| 898 // x * (2^k + 1) -> x + (x << k) |
| 899 if (m.right().HasValue() && m.right().Value() > 0) { |
| 900 int64_t value = m.right().Value(); |
| 901 if (base::bits::IsPowerOfTwo64(value - 1)) { |
| 902 Emit(kArm64Add | AddressingModeField::encode(kMode_Operand2_R_LSL_I), |
| 903 g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
| 904 g.UseRegister(m.left().node()), |
| 905 g.TempImmediate(WhichPowerOf2_64(value - 1))); |
| 906 return; |
| 907 } |
| 908 } |
| 909 |
886 VisitRRR(this, kArm64Mul, node); | 910 VisitRRR(this, kArm64Mul, node); |
887 } | 911 } |
888 | 912 |
889 | 913 |
890 void InstructionSelector::VisitInt32MulHigh(Node* node) { | 914 void InstructionSelector::VisitInt32MulHigh(Node* node) { |
891 // TODO(arm64): Can we do better here? | 915 // TODO(arm64): Can we do better here? |
892 Arm64OperandGenerator g(this); | 916 Arm64OperandGenerator g(this); |
893 InstructionOperand const smull_operand = g.TempRegister(); | 917 InstructionOperand const smull_operand = g.TempRegister(); |
894 Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)), | 918 Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)), |
895 g.UseRegister(node->InputAt(1))); | 919 g.UseRegister(node->InputAt(1))); |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1721 MachineOperatorBuilder::kFloat64RoundTruncate | | 1745 MachineOperatorBuilder::kFloat64RoundTruncate | |
1722 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1746 MachineOperatorBuilder::kFloat64RoundTiesAway | |
1723 MachineOperatorBuilder::kWord32ShiftIsSafe | | 1747 MachineOperatorBuilder::kWord32ShiftIsSafe | |
1724 MachineOperatorBuilder::kInt32DivIsSafe | | 1748 MachineOperatorBuilder::kInt32DivIsSafe | |
1725 MachineOperatorBuilder::kUint32DivIsSafe; | 1749 MachineOperatorBuilder::kUint32DivIsSafe; |
1726 } | 1750 } |
1727 | 1751 |
1728 } // namespace compiler | 1752 } // namespace compiler |
1729 } // namespace internal | 1753 } // namespace internal |
1730 } // namespace v8 | 1754 } // namespace v8 |
OLD | NEW |