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 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
738 DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask)); | 738 DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask)); |
739 Emit(kArm64Ubfx32, g.DefineAsRegister(node), | 739 Emit(kArm64Ubfx32, g.DefineAsRegister(node), |
740 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), | 740 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), |
741 g.TempImmediate(mask_width)); | 741 g.TempImmediate(mask_width)); |
742 return; | 742 return; |
743 } | 743 } |
744 } | 744 } |
745 } else if (TryEmitBitfieldExtract32(this, node)) { | 745 } else if (TryEmitBitfieldExtract32(this, node)) { |
746 return; | 746 return; |
747 } | 747 } |
748 | |
749 if (m.left().IsUint32MulHigh() && m.right().HasValue() && | |
Benedikt Meurer
2015/06/11 04:25:52
Can we limit the values on the right to [1,31] her
martyn.capewell
2015/06/11 10:01:20
I can, but I thought this operation was defined as
| |
750 CanCover(node, node->InputAt(0))) { | |
751 // Combine this shift with the multiply and shift that would be generated | |
752 // by Uint32MulHigh. | |
753 Arm64OperandGenerator g(this); | |
754 Node* left = m.left().node(); | |
755 int shift = m.right().Value() & 0x1f; | |
756 InstructionOperand const smull_operand = g.TempRegister(); | |
757 Emit(kArm64Umull, smull_operand, g.UseRegister(left->InputAt(0)), | |
758 g.UseRegister(left->InputAt(1))); | |
759 Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, | |
760 g.TempImmediate(32 + shift)); | |
761 return; | |
762 } | |
763 | |
748 VisitRRO(this, kArm64Lsr32, node, kShift32Imm); | 764 VisitRRO(this, kArm64Lsr32, node, kShift32Imm); |
749 } | 765 } |
750 | 766 |
751 | 767 |
752 void InstructionSelector::VisitWord64Shr(Node* node) { | 768 void InstructionSelector::VisitWord64Shr(Node* node) { |
753 Arm64OperandGenerator g(this); | 769 Arm64OperandGenerator g(this); |
754 Int64BinopMatcher m(node); | 770 Int64BinopMatcher m(node); |
755 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { | 771 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { |
756 uint64_t lsb = m.right().Value(); | 772 uint64_t lsb = m.right().Value(); |
757 Int64BinopMatcher mleft(m.left().node()); | 773 Int64BinopMatcher mleft(m.left().node()); |
(...skipping 14 matching lines...) Expand all Loading... | |
772 } | 788 } |
773 } | 789 } |
774 VisitRRO(this, kArm64Lsr, node, kShift64Imm); | 790 VisitRRO(this, kArm64Lsr, node, kShift64Imm); |
775 } | 791 } |
776 | 792 |
777 | 793 |
778 void InstructionSelector::VisitWord32Sar(Node* node) { | 794 void InstructionSelector::VisitWord32Sar(Node* node) { |
779 if (TryEmitBitfieldExtract32(this, node)) { | 795 if (TryEmitBitfieldExtract32(this, node)) { |
780 return; | 796 return; |
781 } | 797 } |
798 | |
799 Int32BinopMatcher m(node); | |
800 if (m.left().IsInt32MulHigh() && m.right().HasValue() && | |
801 CanCover(node, node->InputAt(0))) { | |
802 // Combine this shift with the multiply and shift that would be generated | |
803 // by Int32MulHigh. | |
804 Arm64OperandGenerator g(this); | |
805 Node* left = m.left().node(); | |
806 int shift = m.right().Value() & 0x1f; | |
807 InstructionOperand const smull_operand = g.TempRegister(); | |
808 Emit(kArm64Smull, smull_operand, g.UseRegister(left->InputAt(0)), | |
809 g.UseRegister(left->InputAt(1))); | |
810 Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, | |
811 g.TempImmediate(32 + shift)); | |
812 return; | |
813 } | |
814 | |
782 VisitRRO(this, kArm64Asr32, node, kShift32Imm); | 815 VisitRRO(this, kArm64Asr32, node, kShift32Imm); |
783 } | 816 } |
784 | 817 |
785 | 818 |
786 void InstructionSelector::VisitWord64Sar(Node* node) { | 819 void InstructionSelector::VisitWord64Sar(Node* node) { |
787 VisitRRO(this, kArm64Asr, node, kShift64Imm); | 820 VisitRRO(this, kArm64Asr, node, kShift64Imm); |
788 } | 821 } |
789 | 822 |
790 | 823 |
791 void InstructionSelector::VisitWord32Ror(Node* node) { | 824 void InstructionSelector::VisitWord32Ror(Node* node) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
974 g.TempImmediate(WhichPowerOf2_64(value - 1))); | 1007 g.TempImmediate(WhichPowerOf2_64(value - 1))); |
975 return; | 1008 return; |
976 } | 1009 } |
977 } | 1010 } |
978 | 1011 |
979 VisitRRR(this, kArm64Mul, node); | 1012 VisitRRR(this, kArm64Mul, node); |
980 } | 1013 } |
981 | 1014 |
982 | 1015 |
983 void InstructionSelector::VisitInt32MulHigh(Node* node) { | 1016 void InstructionSelector::VisitInt32MulHigh(Node* node) { |
984 // TODO(arm64): Can we do better here? | |
985 Arm64OperandGenerator g(this); | 1017 Arm64OperandGenerator g(this); |
986 InstructionOperand const smull_operand = g.TempRegister(); | 1018 InstructionOperand const smull_operand = g.TempRegister(); |
987 Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)), | 1019 Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)), |
988 g.UseRegister(node->InputAt(1))); | 1020 g.UseRegister(node->InputAt(1))); |
989 Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); | 1021 Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); |
990 } | 1022 } |
991 | 1023 |
992 | 1024 |
993 void InstructionSelector::VisitUint32MulHigh(Node* node) { | 1025 void InstructionSelector::VisitUint32MulHigh(Node* node) { |
994 // TODO(arm64): Can we do better here? | |
995 Arm64OperandGenerator g(this); | 1026 Arm64OperandGenerator g(this); |
996 InstructionOperand const smull_operand = g.TempRegister(); | 1027 InstructionOperand const smull_operand = g.TempRegister(); |
997 Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)), | 1028 Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)), |
998 g.UseRegister(node->InputAt(1))); | 1029 g.UseRegister(node->InputAt(1))); |
999 Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); | 1030 Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); |
1000 } | 1031 } |
1001 | 1032 |
1002 | 1033 |
1003 void InstructionSelector::VisitInt32Div(Node* node) { | 1034 void InstructionSelector::VisitInt32Div(Node* node) { |
1004 VisitRRR(this, kArm64Idiv32, node); | 1035 VisitRRR(this, kArm64Idiv32, node); |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1937 MachineOperatorBuilder::kFloat64RoundTruncate | | 1968 MachineOperatorBuilder::kFloat64RoundTruncate | |
1938 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1969 MachineOperatorBuilder::kFloat64RoundTiesAway | |
1939 MachineOperatorBuilder::kWord32ShiftIsSafe | | 1970 MachineOperatorBuilder::kWord32ShiftIsSafe | |
1940 MachineOperatorBuilder::kInt32DivIsSafe | | 1971 MachineOperatorBuilder::kInt32DivIsSafe | |
1941 MachineOperatorBuilder::kUint32DivIsSafe; | 1972 MachineOperatorBuilder::kUint32DivIsSafe; |
1942 } | 1973 } |
1943 | 1974 |
1944 } // namespace compiler | 1975 } // namespace compiler |
1945 } // namespace internal | 1976 } // namespace internal |
1946 } // namespace v8 | 1977 } // namespace v8 |
OLD | NEW |