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

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

Issue 1681953003: Revert of [turbofan] ARM: Improve AND instruction selection (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « no previous file | test/unittests/compiler/arm/instruction-selector-arm-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/base/bits.h" 6 #include "src/base/bits.h"
7 #include "src/compiler/instruction-selector-impl.h" 7 #include "src/compiler/instruction-selector-impl.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 10
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) { 544 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) {
545 Int32BinopMatcher mright(m.right().node()); 545 Int32BinopMatcher mright(m.right().node());
546 if (mright.right().Is(-1)) { 546 if (mright.right().Is(-1)) {
547 EmitBic(this, node, m.left().node(), mright.left().node()); 547 EmitBic(this, node, m.left().node(), mright.left().node());
548 return; 548 return;
549 } 549 }
550 } 550 }
551 if (m.right().HasValue()) { 551 if (m.right().HasValue()) {
552 uint32_t const value = m.right().Value(); 552 uint32_t const value = m.right().Value();
553 uint32_t width = base::bits::CountPopulation32(value); 553 uint32_t width = base::bits::CountPopulation32(value);
554 uint32_t leading_zeros = base::bits::CountLeadingZeros32(value); 554 uint32_t msb = base::bits::CountLeadingZeros32(value);
555 555 // Try to interpret this AND as UBFX.
556 // Try to merge SHR operations on the left hand input into this AND. 556 if (IsSupported(ARMv7) && width != 0 && msb + width == 32) {
557 if (m.left().IsWord32Shr()) { 557 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value));
558 Int32BinopMatcher mshr(m.left().node()); 558 if (m.left().IsWord32Shr()) {
559 if (mshr.right().HasValue()) { 559 Int32BinopMatcher mleft(m.left().node());
560 uint32_t const shift = mshr.right().Value(); 560 if (mleft.right().IsInRange(0, 31)) {
561 561 // UBFX cannot extract bits past the register size, however since
562 if (((shift == 8) || (shift == 16) || (shift == 24)) && 562 // shifting the original value would have introduced some zeros we can
563 ((value == 0xff) || (value == 0xffff))) { 563 // still use UBFX with a smaller mask and the remaining bits will be
564 // Merge SHR into AND by emitting a UXTB or UXTH instruction with a 564 // zeros.
565 // bytewise rotation. 565 uint32_t const lsb = mleft.right().Value();
566 Emit((value == 0xff) ? kArmUxtb : kArmUxth, 566 return EmitUbfx(this, node, mleft.left().node(), lsb,
567 g.DefineAsRegister(m.node()), g.UseRegister(mshr.left().node()), 567 std::min(width, 32 - lsb));
568 g.TempImmediate(mshr.right().Value()));
569 return;
570 } else if (IsSupported(ARMv7) && (width != 0) &&
571 ((leading_zeros + width) == 32)) {
572 // Merge Shr into And by emitting a UBFX instruction.
573 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value));
574 if ((1 <= shift) && (shift <= 31)) {
575 // UBFX cannot extract bits past the register size, however since
576 // shifting the original value would have introduced some zeros we
577 // can still use UBFX with a smaller mask and the remaining bits
578 // will be zeros.
579 EmitUbfx(this, node, mshr.left().node(), shift,
580 std::min(width, 32 - shift));
581 return;
582 }
583 } 568 }
584 } 569 }
585 } else if (value == 0xffff) { 570 return EmitUbfx(this, node, m.left().node(), 0, width);
586 // Emit UXTH for this AND. We don't bother testing for UXTB, as it's no
587 // better than AND 0xff for this operation.
588 Emit(kArmUxth, g.DefineAsRegister(m.node()),
589 g.UseRegister(m.left().node()), g.TempImmediate(0));
590 return;
591 } 571 }
572 // Try to interpret this AND as BIC.
592 if (g.CanBeImmediate(~value)) { 573 if (g.CanBeImmediate(~value)) {
593 // Emit BIC for this AND by inverting the immediate value first.
594 Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I), 574 Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I),
595 g.DefineAsRegister(node), g.UseRegister(m.left().node()), 575 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
596 g.TempImmediate(~value)); 576 g.TempImmediate(~value));
597 return; 577 return;
598 } 578 }
599 if (!g.CanBeImmediate(value) && IsSupported(ARMv7)) { 579 // Try to interpret this AND as UXTH.
600 // If value has 9 to 23 contiguous set bits, and has the lsb set, we can 580 if (value == 0xffff) {
601 // replace this AND with UBFX. Other contiguous bit patterns have already 581 Emit(kArmUxth, g.DefineAsRegister(m.node()),
602 // been handled by BIC or will be handled by AND. 582 g.UseRegister(m.left().node()), g.TempImmediate(0));
603 if ((width != 0) && ((leading_zeros + width) == 32) && 583 return;
604 (9 <= leading_zeros) && (leading_zeros <= 23)) { 584 }
605 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value)); 585 // Try to interpret this AND as BFC.
606 EmitUbfx(this, node, m.left().node(), 0, width); 586 if (IsSupported(ARMv7)) {
607 return;
608 }
609
610 width = 32 - width; 587 width = 32 - width;
611 leading_zeros = base::bits::CountLeadingZeros32(~value); 588 msb = base::bits::CountLeadingZeros32(~value);
612 uint32_t lsb = base::bits::CountTrailingZeros32(~value); 589 uint32_t lsb = base::bits::CountTrailingZeros32(~value);
613 if ((leading_zeros + width + lsb) == 32) { 590 if (msb + width + lsb == 32) {
614 // This AND can be replaced with BFC.
615 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 591 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
616 g.TempImmediate(lsb), g.TempImmediate(width)); 592 g.TempImmediate(lsb), g.TempImmediate(width));
617 return; 593 return;
618 } 594 }
619 } 595 }
620 } 596 }
621 VisitBinop(this, node, kArmAnd, kArmAnd); 597 VisitBinop(this, node, kArmAnd, kArmAnd);
622 } 598 }
623 599
624 600
(...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 MachineOperatorBuilder::kFloat64RoundTiesAway | 1621 MachineOperatorBuilder::kFloat64RoundTiesAway |
1646 MachineOperatorBuilder::kFloat32RoundTiesEven | 1622 MachineOperatorBuilder::kFloat32RoundTiesEven |
1647 MachineOperatorBuilder::kFloat64RoundTiesEven; 1623 MachineOperatorBuilder::kFloat64RoundTiesEven;
1648 } 1624 }
1649 return flags; 1625 return flags;
1650 } 1626 }
1651 1627
1652 } // namespace compiler 1628 } // namespace compiler
1653 } // namespace internal 1629 } // namespace internal
1654 } // namespace v8 1630 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/compiler/arm/instruction-selector-arm-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698