Commit 14a5c18c authored by martyn.capewell's avatar martyn.capewell Committed by Commit bot

[turbofan] ARM: Use SBFX in instruction selector.

Support SBFX in the instruction selector for sign-extension patterns like
Sar(Shl(x, a), b), where a and b are immediate values.

BUG=

Review URL: https://codereview.chromium.org/1695293002

Cr-Commit-Position: refs/heads/master@{#34029}
parent 0dfd7bcd
......@@ -672,6 +672,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
DCHECK_EQ(LeaveCC, i.OutputSBit());
break;
}
case kArmSbfx: {
CpuFeatureScope scope(masm(), ARMv7);
__ sbfx(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
i.InputInt8(2));
DCHECK_EQ(LeaveCC, i.OutputSBit());
break;
}
case kArmSxtb:
__ sxtb(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1));
DCHECK_EQ(LeaveCC, i.OutputSBit());
......
......@@ -36,6 +36,7 @@ namespace compiler {
V(ArmMvn) \
V(ArmBfc) \
V(ArmUbfx) \
V(ArmSbfx) \
V(ArmSxtb) \
V(ArmSxth) \
V(ArmSxtab) \
......
......@@ -38,6 +38,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmMvn:
case kArmBfc:
case kArmUbfx:
case kArmSbfx:
case kArmSxtb:
case kArmSxth:
case kArmSxtab:
......
......@@ -733,14 +733,23 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
Int32BinopMatcher m(node);
if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) {
Int32BinopMatcher mleft(m.left().node());
if (mleft.right().Is(16) && m.right().Is(16)) {
Emit(kArmSxth, g.DefineAsRegister(node),
g.UseRegister(mleft.left().node()), g.TempImmediate(0));
return;
} else if (mleft.right().Is(24) && m.right().Is(24)) {
Emit(kArmSxtb, g.DefineAsRegister(node),
g.UseRegister(mleft.left().node()), g.TempImmediate(0));
return;
if (m.right().HasValue() && mleft.right().HasValue()) {
uint32_t sar = m.right().Value();
uint32_t shl = mleft.right().Value();
if ((sar == shl) && (sar == 16)) {
Emit(kArmSxth, g.DefineAsRegister(node),
g.UseRegister(mleft.left().node()), g.TempImmediate(0));
return;
} else if ((sar == shl) && (sar == 24)) {
Emit(kArmSxtb, g.DefineAsRegister(node),
g.UseRegister(mleft.left().node()), g.TempImmediate(0));
return;
} else if (IsSupported(ARMv7) && (sar >= shl)) {
Emit(kArmSbfx, g.DefineAsRegister(node),
g.UseRegister(mleft.left().node()), g.TempImmediate(sar - shl),
g.TempImmediate(32 - sar));
return;
}
}
}
VisitShift(this, node, TryMatchASR);
......
......@@ -2544,6 +2544,25 @@ TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIVAndMLS) {
}
TEST_F(InstructionSelectorTest, Word32ShlWord32SarForSbfx) {
TRACED_FORRANGE(int32_t, shl, 1, 31) {
TRACED_FORRANGE(int32_t, sar, shl, 31) {
if ((shl == sar) && (sar == 16)) continue; // Sxth.
if ((shl == sar) && (sar == 24)) continue; // Sxtb.
StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
m.Return(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(shl)),
m.Int32Constant(sar)));
Stream s = m.Build(ARMv7);
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArmSbfx, s[0]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
EXPECT_EQ(sar - shl, s.ToInt32(s[0]->InputAt(1)));
EXPECT_EQ(32 - sar, s.ToInt32(s[0]->InputAt(2)));
}
}
}
TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) {
TRACED_FORRANGE(int32_t, width, 9, 23) {
if (width == 16) continue; // Uxth.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment