[turbofan] Recognize sign extension of 8-bit and 16-bit values on arm64.

R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#25475}
This commit is contained in:
baptiste.afsa 2014-11-24 03:00:10 -08:00 committed by Commit bot
parent be0fcaa2bc
commit 9b5c279b9f
4 changed files with 55 additions and 0 deletions

View File

@ -416,6 +416,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kArm64Mov32:
__ Mov(i.OutputRegister32(), i.InputRegister32(0));
break;
case kArm64Sxtb32:
__ Sxtb(i.OutputRegister32(), i.InputRegister32(0));
break;
case kArm64Sxth32:
__ Sxth(i.OutputRegister32(), i.InputRegister32(0));
break;
case kArm64Sxtw:
__ Sxtw(i.OutputRegister(), i.InputRegister32(0));
break;

View File

@ -65,6 +65,8 @@ namespace compiler {
V(Arm64Ror) \
V(Arm64Ror32) \
V(Arm64Mov32) \
V(Arm64Sxtb32) \
V(Arm64Sxth32) \
V(Arm64Sxtw) \
V(Arm64Ubfx) \
V(Arm64Ubfx32) \

View File

@ -608,6 +608,21 @@ 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;
}
}
VisitRRO(this, kArm64Asr32, node, kShift32Imm);
}

View File

@ -2129,6 +2129,38 @@ TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) {
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output()));
}
TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) {
{
StreamBuilder m(this, kMachInt32, kMachInt32);
Node* const p0 = m.Parameter(0);
Node* const r =
m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24));
m.Return(r);
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64Sxtb32, s[0]->arch_opcode());
ASSERT_EQ(1U, s[0]->InputCount());
EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
ASSERT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
}
{
StreamBuilder m(this, kMachInt32, kMachInt32);
Node* const p0 = m.Parameter(0);
Node* const r =
m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16));
m.Return(r);
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64Sxth32, s[0]->arch_opcode());
ASSERT_EQ(1U, s[0]->InputCount());
EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
ASSERT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
}
}
} // namespace compiler
} // namespace internal
} // namespace v8