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 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 | 634 |
635 void InstructionSelector::VisitWord64Xor(Node* node) { | 635 void InstructionSelector::VisitWord64Xor(Node* node) { |
636 Int64BinopMatcher m(node); | 636 Int64BinopMatcher m(node); |
637 VisitLogical<Int64BinopMatcher>( | 637 VisitLogical<Int64BinopMatcher>( |
638 this, node, &m, kArm64Eor, CanCover(node, m.left().node()), | 638 this, node, &m, kArm64Eor, CanCover(node, m.left().node()), |
639 CanCover(node, m.right().node()), kLogical64Imm); | 639 CanCover(node, m.right().node()), kLogical64Imm); |
640 } | 640 } |
641 | 641 |
642 | 642 |
643 void InstructionSelector::VisitWord32Shl(Node* node) { | 643 void InstructionSelector::VisitWord32Shl(Node* node) { |
| 644 Int32BinopMatcher m(node); |
| 645 if (m.left().IsWord32And() && CanCover(node, m.left().node()) && |
| 646 m.right().IsInRange(1, 31)) { |
| 647 Arm64OperandGenerator g(this); |
| 648 Int32BinopMatcher mleft(m.left().node()); |
| 649 if (mleft.right().HasValue()) { |
| 650 uint32_t mask = mleft.right().Value(); |
| 651 uint32_t mask_width = base::bits::CountPopulation32(mask); |
| 652 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask); |
| 653 if ((mask_width != 0) && (mask_msb + mask_width == 32)) { |
| 654 uint32_t shift = m.right().Value(); |
| 655 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask)); |
| 656 DCHECK_NE(0u, shift); |
| 657 |
| 658 if ((shift + mask_width) >= 32) { |
| 659 // If the mask is contiguous and reaches or extends beyond the top |
| 660 // bit, only the shift is needed. |
| 661 Emit(kArm64Lsl32, g.DefineAsRegister(node), |
| 662 g.UseRegister(mleft.left().node()), |
| 663 g.UseImmediate(m.right().node())); |
| 664 return; |
| 665 } else { |
| 666 // Select Ubfiz for Shl(And(x, mask), imm) where the mask is |
| 667 // contiguous, and the shift immediate non-zero. |
| 668 Emit(kArm64Ubfiz32, g.DefineAsRegister(node), |
| 669 g.UseRegister(mleft.left().node()), |
| 670 g.UseImmediate(m.right().node()), g.TempImmediate(mask_width)); |
| 671 return; |
| 672 } |
| 673 } |
| 674 } |
| 675 } |
644 VisitRRO(this, kArm64Lsl32, node, kShift32Imm); | 676 VisitRRO(this, kArm64Lsl32, node, kShift32Imm); |
645 } | 677 } |
646 | 678 |
647 | 679 |
648 void InstructionSelector::VisitWord64Shl(Node* node) { | 680 void InstructionSelector::VisitWord64Shl(Node* node) { |
649 Arm64OperandGenerator g(this); | 681 Arm64OperandGenerator g(this); |
650 Int64BinopMatcher m(node); | 682 Int64BinopMatcher m(node); |
651 if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) && | 683 if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) && |
652 m.right().IsInRange(32, 63)) { | 684 m.right().IsInRange(32, 63)) { |
653 // There's no need to sign/zero-extend to 64-bit if we shift out the upper | 685 // There's no need to sign/zero-extend to 64-bit if we shift out the upper |
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1905 MachineOperatorBuilder::kFloat64RoundTruncate | | 1937 MachineOperatorBuilder::kFloat64RoundTruncate | |
1906 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1938 MachineOperatorBuilder::kFloat64RoundTiesAway | |
1907 MachineOperatorBuilder::kWord32ShiftIsSafe | | 1939 MachineOperatorBuilder::kWord32ShiftIsSafe | |
1908 MachineOperatorBuilder::kInt32DivIsSafe | | 1940 MachineOperatorBuilder::kInt32DivIsSafe | |
1909 MachineOperatorBuilder::kUint32DivIsSafe; | 1941 MachineOperatorBuilder::kUint32DivIsSafe; |
1910 } | 1942 } |
1911 | 1943 |
1912 } // namespace compiler | 1944 } // namespace compiler |
1913 } // namespace internal | 1945 } // namespace internal |
1914 } // namespace v8 | 1946 } // namespace v8 |
OLD | NEW |