| 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 8fa6f24300165e838ca895f08f543c56de54a8df..24168cc98e1225e71dbf14e19c94fb93f2ca322a 100644
|
| --- a/src/compiler/arm/instruction-selector-arm.cc
|
| +++ b/src/compiler/arm/instruction-selector-arm.cc
|
| @@ -368,6 +368,16 @@ void EmitBic(InstructionSelector* selector, Node* node, Node* left,
|
| g.UseRegister(right));
|
| }
|
|
|
| +
|
| +void EmitUbfx(InstructionSelector* selector, Node* node, Node* left,
|
| + uint32_t lsb, uint32_t width) {
|
| + DCHECK_LE(1, width);
|
| + DCHECK_LE(width, 32 - lsb);
|
| + ArmOperandGenerator g(selector);
|
| + selector->Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(left),
|
| + g.TempImmediate(lsb), g.TempImmediate(width));
|
| +}
|
| +
|
| } // namespace
|
|
|
|
|
| @@ -398,15 +408,16 @@ void InstructionSelector::VisitWord32And(Node* node) {
|
| if (m.left().IsWord32Shr()) {
|
| Int32BinopMatcher mleft(m.left().node());
|
| if (mleft.right().IsInRange(0, 31)) {
|
| - Emit(kArmUbfx, g.DefineAsRegister(node),
|
| - g.UseRegister(mleft.left().node()),
|
| - g.UseImmediate(mleft.right().node()), g.TempImmediate(width));
|
| - return;
|
| + // 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));
|
| }
|
| }
|
| - Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
| - g.TempImmediate(0), g.TempImmediate(width));
|
| - return;
|
| + return EmitUbfx(this, node, m.left().node(), 0, width);
|
| }
|
| // Try to interpret this AND as BIC.
|
| if (g.CanBeImmediate(~value)) {
|
| @@ -523,10 +534,7 @@ void InstructionSelector::VisitWord32Shr(Node* node) {
|
| uint32_t msb = base::bits::CountLeadingZeros32(value);
|
| if (msb + width + lsb == 32) {
|
| DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(value));
|
| - Emit(kArmUbfx, g.DefineAsRegister(node),
|
| - g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
|
| - g.TempImmediate(width));
|
| - return;
|
| + return EmitUbfx(this, node, mleft.left().node(), lsb, width);
|
| }
|
| }
|
| }
|
|
|