Chromium Code Reviews| Index: src/compiler/arm64/instruction-selector-arm64.cc |
| diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc |
| index f653520c36e95c6cd3524fd267af9affea43b26d..13fb90a36760ed638d4376ae15e82f00fcc39056 100644 |
| --- a/src/compiler/arm64/instruction-selector-arm64.cc |
| +++ b/src/compiler/arm64/instruction-selector-arm64.cc |
| @@ -660,8 +660,32 @@ void InstructionSelector::VisitWord64Shl(Node* node) { |
| } |
| +bool TryEmitBitfieldExtract32(InstructionSelector* selector, Node* node) { |
|
Benedikt Meurer
2015/05/08 04:04:59
Nit: put this function into an anonymous namespace
|
| + Arm64OperandGenerator g(selector); |
| + Int32BinopMatcher m(node); |
| + if (selector->CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { |
| + // Select Ubfx or Sbfx for (x << (K & 0x1f)) OP (K & 0x1f), where |
| + // OP is >>> or >> and (K & 0x1f) != 0. |
| + Int32BinopMatcher mleft(m.left().node()); |
| + if (mleft.right().HasValue() && m.right().HasValue() && |
| + (mleft.right().Value() & 0x1f) == (m.right().Value() & 0x1f)) { |
| + DCHECK(m.IsWord32Shr() || m.IsWord32Sar()); |
| + ArchOpcode opcode = m.IsWord32Sar() ? kArm64Sbfx32 : kArm64Ubfx32; |
| + |
| + int right_val = m.right().Value() & 0x1f; |
| + DCHECK_NE(right_val, 0); |
| + |
| + selector->Emit(opcode, g.DefineAsRegister(node), |
| + g.UseRegister(mleft.left().node()), g.TempImmediate(0), |
| + g.TempImmediate(32 - right_val)); |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| + |
| void InstructionSelector::VisitWord32Shr(Node* node) { |
| - Arm64OperandGenerator g(this); |
| Int32BinopMatcher m(node); |
| if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { |
| uint32_t lsb = m.right().Value(); |
| @@ -673,6 +697,7 @@ void InstructionSelector::VisitWord32Shr(Node* node) { |
| // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is |
| // shifted into the least-significant bits. |
| if ((mask_msb + mask_width + lsb) == 32) { |
| + Arm64OperandGenerator g(this); |
| DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask)); |
| Emit(kArm64Ubfx32, g.DefineAsRegister(node), |
| g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), |
| @@ -680,6 +705,8 @@ void InstructionSelector::VisitWord32Shr(Node* node) { |
| return; |
| } |
| } |
| + } else if (TryEmitBitfieldExtract32(this, node)) { |
| + return; |
| } |
| VisitRRO(this, kArm64Lsr32, node, kShift32Imm); |
| } |
| @@ -711,20 +738,8 @@ void InstructionSelector::VisitWord64Shr(Node* node) { |
| void InstructionSelector::VisitWord32Sar(Node* node) { |
| - Arm64OperandGenerator g(this); |
| - Int32BinopMatcher m(node); |
| - // Select Sxth/Sxtb for (x << K) >> K where K is 16 or 24. |
| - if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { |
| - Int32BinopMatcher mleft(m.left().node()); |
| - if (mleft.right().Is(16) && m.right().Is(16)) { |
| - Emit(kArm64Sxth32, g.DefineAsRegister(node), |
| - g.UseRegister(mleft.left().node())); |
| - return; |
| - } else if (mleft.right().Is(24) && m.right().Is(24)) { |
| - Emit(kArm64Sxtb32, g.DefineAsRegister(node), |
| - g.UseRegister(mleft.left().node())); |
| - return; |
| - } |
| + if (TryEmitBitfieldExtract32(this, node)) { |
| + return; |
| } |
| VisitRRO(this, kArm64Asr32, node, kShift32Imm); |
| } |