From 1514287a28e9c62a1faf1821c5804e9d51738e44 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Fri, 14 Nov 2014 08:43:40 +0100 Subject: [PATCH] [arm] Fix UBFX detection. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/725063002 Cr-Commit-Position: refs/heads/master@{#25344} --- src/compiler/arm/instruction-selector-arm.cc | 30 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc index 8fa6f24..24168cc 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); } } } -- 2.7.4