Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 1135543002: [turbofan] Use sbfx in ARM64 instruction selector (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add anonymous namespace Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/arm64/instruction-codes-arm64.h ('k') | test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698