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 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 // 32 bits anyway. | 653 // 32 bits anyway. |
654 Emit(kArm64Lsl, g.DefineAsRegister(node), | 654 Emit(kArm64Lsl, g.DefineAsRegister(node), |
655 g.UseRegister(m.left().node()->InputAt(0)), | 655 g.UseRegister(m.left().node()->InputAt(0)), |
656 g.UseImmediate(m.right().node())); | 656 g.UseImmediate(m.right().node())); |
657 return; | 657 return; |
658 } | 658 } |
659 VisitRRO(this, kArm64Lsl, node, kShift64Imm); | 659 VisitRRO(this, kArm64Lsl, node, kShift64Imm); |
660 } | 660 } |
661 | 661 |
662 | 662 |
| 663 namespace { |
| 664 |
| 665 bool TryEmitBitfieldExtract32(InstructionSelector* selector, Node* node) { |
| 666 Arm64OperandGenerator g(selector); |
| 667 Int32BinopMatcher m(node); |
| 668 if (selector->CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { |
| 669 // Select Ubfx or Sbfx for (x << (K & 0x1f)) OP (K & 0x1f), where |
| 670 // OP is >>> or >> and (K & 0x1f) != 0. |
| 671 Int32BinopMatcher mleft(m.left().node()); |
| 672 if (mleft.right().HasValue() && m.right().HasValue() && |
| 673 (mleft.right().Value() & 0x1f) == (m.right().Value() & 0x1f)) { |
| 674 DCHECK(m.IsWord32Shr() || m.IsWord32Sar()); |
| 675 ArchOpcode opcode = m.IsWord32Sar() ? kArm64Sbfx32 : kArm64Ubfx32; |
| 676 |
| 677 int right_val = m.right().Value() & 0x1f; |
| 678 DCHECK_NE(right_val, 0); |
| 679 |
| 680 selector->Emit(opcode, g.DefineAsRegister(node), |
| 681 g.UseRegister(mleft.left().node()), g.TempImmediate(0), |
| 682 g.TempImmediate(32 - right_val)); |
| 683 return true; |
| 684 } |
| 685 } |
| 686 return false; |
| 687 } |
| 688 |
| 689 } // namespace |
| 690 |
| 691 |
663 void InstructionSelector::VisitWord32Shr(Node* node) { | 692 void InstructionSelector::VisitWord32Shr(Node* node) { |
664 Arm64OperandGenerator g(this); | |
665 Int32BinopMatcher m(node); | 693 Int32BinopMatcher m(node); |
666 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { | 694 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { |
667 uint32_t lsb = m.right().Value(); | 695 uint32_t lsb = m.right().Value(); |
668 Int32BinopMatcher mleft(m.left().node()); | 696 Int32BinopMatcher mleft(m.left().node()); |
669 if (mleft.right().HasValue()) { | 697 if (mleft.right().HasValue()) { |
670 uint32_t mask = (mleft.right().Value() >> lsb) << lsb; | 698 uint32_t mask = (mleft.right().Value() >> lsb) << lsb; |
671 uint32_t mask_width = base::bits::CountPopulation32(mask); | 699 uint32_t mask_width = base::bits::CountPopulation32(mask); |
672 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask); | 700 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask); |
673 // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is | 701 // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is |
674 // shifted into the least-significant bits. | 702 // shifted into the least-significant bits. |
675 if ((mask_msb + mask_width + lsb) == 32) { | 703 if ((mask_msb + mask_width + lsb) == 32) { |
| 704 Arm64OperandGenerator g(this); |
676 DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask)); | 705 DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask)); |
677 Emit(kArm64Ubfx32, g.DefineAsRegister(node), | 706 Emit(kArm64Ubfx32, g.DefineAsRegister(node), |
678 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), | 707 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), |
679 g.TempImmediate(mask_width)); | 708 g.TempImmediate(mask_width)); |
680 return; | 709 return; |
681 } | 710 } |
682 } | 711 } |
| 712 } else if (TryEmitBitfieldExtract32(this, node)) { |
| 713 return; |
683 } | 714 } |
684 VisitRRO(this, kArm64Lsr32, node, kShift32Imm); | 715 VisitRRO(this, kArm64Lsr32, node, kShift32Imm); |
685 } | 716 } |
686 | 717 |
687 | 718 |
688 void InstructionSelector::VisitWord64Shr(Node* node) { | 719 void InstructionSelector::VisitWord64Shr(Node* node) { |
689 Arm64OperandGenerator g(this); | 720 Arm64OperandGenerator g(this); |
690 Int64BinopMatcher m(node); | 721 Int64BinopMatcher m(node); |
691 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { | 722 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { |
692 uint64_t lsb = m.right().Value(); | 723 uint64_t lsb = m.right().Value(); |
(...skipping 11 matching lines...) Expand all Loading... |
704 g.TempImmediate(mask_width)); | 735 g.TempImmediate(mask_width)); |
705 return; | 736 return; |
706 } | 737 } |
707 } | 738 } |
708 } | 739 } |
709 VisitRRO(this, kArm64Lsr, node, kShift64Imm); | 740 VisitRRO(this, kArm64Lsr, node, kShift64Imm); |
710 } | 741 } |
711 | 742 |
712 | 743 |
713 void InstructionSelector::VisitWord32Sar(Node* node) { | 744 void InstructionSelector::VisitWord32Sar(Node* node) { |
714 Arm64OperandGenerator g(this); | 745 if (TryEmitBitfieldExtract32(this, node)) { |
715 Int32BinopMatcher m(node); | 746 return; |
716 // Select Sxth/Sxtb for (x << K) >> K where K is 16 or 24. | |
717 if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { | |
718 Int32BinopMatcher mleft(m.left().node()); | |
719 if (mleft.right().Is(16) && m.right().Is(16)) { | |
720 Emit(kArm64Sxth32, g.DefineAsRegister(node), | |
721 g.UseRegister(mleft.left().node())); | |
722 return; | |
723 } else if (mleft.right().Is(24) && m.right().Is(24)) { | |
724 Emit(kArm64Sxtb32, g.DefineAsRegister(node), | |
725 g.UseRegister(mleft.left().node())); | |
726 return; | |
727 } | |
728 } | 747 } |
729 VisitRRO(this, kArm64Asr32, node, kShift32Imm); | 748 VisitRRO(this, kArm64Asr32, node, kShift32Imm); |
730 } | 749 } |
731 | 750 |
732 | 751 |
733 void InstructionSelector::VisitWord64Sar(Node* node) { | 752 void InstructionSelector::VisitWord64Sar(Node* node) { |
734 VisitRRO(this, kArm64Asr, node, kShift64Imm); | 753 VisitRRO(this, kArm64Asr, node, kShift64Imm); |
735 } | 754 } |
736 | 755 |
737 | 756 |
(...skipping 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1879 MachineOperatorBuilder::kFloat64RoundTruncate | | 1898 MachineOperatorBuilder::kFloat64RoundTruncate | |
1880 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1899 MachineOperatorBuilder::kFloat64RoundTiesAway | |
1881 MachineOperatorBuilder::kWord32ShiftIsSafe | | 1900 MachineOperatorBuilder::kWord32ShiftIsSafe | |
1882 MachineOperatorBuilder::kInt32DivIsSafe | | 1901 MachineOperatorBuilder::kInt32DivIsSafe | |
1883 MachineOperatorBuilder::kUint32DivIsSafe; | 1902 MachineOperatorBuilder::kUint32DivIsSafe; |
1884 } | 1903 } |
1885 | 1904 |
1886 } // namespace compiler | 1905 } // namespace compiler |
1887 } // namespace internal | 1906 } // namespace internal |
1888 } // namespace v8 | 1907 } // namespace v8 |
OLD | NEW |