Index: src/compiler/arm/instruction-selector-arm.cc |
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc |
index 5880a31cc22a8ef67a9e687787623ed4d7b15cef..907d8679f8615b1f0fc4fbc67ca0a6d62722b5b3 100644 |
--- a/src/compiler/arm/instruction-selector-arm.cc |
+++ b/src/compiler/arm/instruction-selector-arm.cc |
@@ -551,67 +551,43 @@ |
if (m.right().HasValue()) { |
uint32_t const value = m.right().Value(); |
uint32_t width = base::bits::CountPopulation32(value); |
- uint32_t leading_zeros = base::bits::CountLeadingZeros32(value); |
- |
- // Try to merge SHR operations on the left hand input into this AND. |
- if (m.left().IsWord32Shr()) { |
- Int32BinopMatcher mshr(m.left().node()); |
- if (mshr.right().HasValue()) { |
- uint32_t const shift = mshr.right().Value(); |
- |
- if (((shift == 8) || (shift == 16) || (shift == 24)) && |
- ((value == 0xff) || (value == 0xffff))) { |
- // Merge SHR into AND by emitting a UXTB or UXTH instruction with a |
- // bytewise rotation. |
- Emit((value == 0xff) ? kArmUxtb : kArmUxth, |
- g.DefineAsRegister(m.node()), g.UseRegister(mshr.left().node()), |
- g.TempImmediate(mshr.right().Value())); |
- return; |
- } else if (IsSupported(ARMv7) && (width != 0) && |
- ((leading_zeros + width) == 32)) { |
- // Merge Shr into And by emitting a UBFX instruction. |
- DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value)); |
- if ((1 <= shift) && (shift <= 31)) { |
- // UBFX cannot extract bits past the register size, however since |
- // shifting the original value would have introduced some zeros we |
- // can still use UBFX with a smaller mask and the remaining bits |
- // will be zeros. |
- EmitUbfx(this, node, mshr.left().node(), shift, |
- std::min(width, 32 - shift)); |
- return; |
- } |
+ uint32_t msb = base::bits::CountLeadingZeros32(value); |
+ // Try to interpret this AND as UBFX. |
+ if (IsSupported(ARMv7) && width != 0 && msb + width == 32) { |
+ DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value)); |
+ if (m.left().IsWord32Shr()) { |
+ Int32BinopMatcher mleft(m.left().node()); |
+ if (mleft.right().IsInRange(0, 31)) { |
+ // UBFX cannot extract bits past the register size, however since |
+ // shifting the original value would have introduced some zeros we can |
+ // still use UBFX with a smaller mask and the remaining bits will be |
+ // zeros. |
+ uint32_t const lsb = mleft.right().Value(); |
+ return EmitUbfx(this, node, mleft.left().node(), lsb, |
+ std::min(width, 32 - lsb)); |
} |
} |
- } else if (value == 0xffff) { |
- // Emit UXTH for this AND. We don't bother testing for UXTB, as it's no |
- // better than AND 0xff for this operation. |
- Emit(kArmUxth, g.DefineAsRegister(m.node()), |
- g.UseRegister(m.left().node()), g.TempImmediate(0)); |
- return; |
- } |
+ return EmitUbfx(this, node, m.left().node(), 0, width); |
+ } |
+ // Try to interpret this AND as BIC. |
if (g.CanBeImmediate(~value)) { |
- // Emit BIC for this AND by inverting the immediate value first. |
Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I), |
g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
g.TempImmediate(~value)); |
return; |
} |
- if (!g.CanBeImmediate(value) && IsSupported(ARMv7)) { |
- // If value has 9 to 23 contiguous set bits, and has the lsb set, we can |
- // replace this AND with UBFX. Other contiguous bit patterns have already |
- // been handled by BIC or will be handled by AND. |
- if ((width != 0) && ((leading_zeros + width) == 32) && |
- (9 <= leading_zeros) && (leading_zeros <= 23)) { |
- DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value)); |
- EmitUbfx(this, node, m.left().node(), 0, width); |
- return; |
- } |
- |
+ // Try to interpret this AND as UXTH. |
+ if (value == 0xffff) { |
+ Emit(kArmUxth, g.DefineAsRegister(m.node()), |
+ g.UseRegister(m.left().node()), g.TempImmediate(0)); |
+ return; |
+ } |
+ // Try to interpret this AND as BFC. |
+ if (IsSupported(ARMv7)) { |
width = 32 - width; |
- leading_zeros = base::bits::CountLeadingZeros32(~value); |
+ msb = base::bits::CountLeadingZeros32(~value); |
uint32_t lsb = base::bits::CountTrailingZeros32(~value); |
- if ((leading_zeros + width + lsb) == 32) { |
- // This AND can be replaced with BFC. |
+ if (msb + width + lsb == 32) { |
Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), |
g.TempImmediate(lsb), g.TempImmediate(width)); |
return; |