From 39012441076e97f60b89cd546f0e789300fe6b9c Mon Sep 17 00:00:00 2001 From: "baptiste.afsa@arm.com" Date: Wed, 29 Oct 2014 10:51:10 +0000 Subject: [PATCH] [arm64] Turn Word64And into tst instruction when possible. Also add corresponding unit tests. R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/684813004 Cr-Commit-Position: refs/heads/master@{#24974} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24974 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler/arm64/instruction-selector-arm64.cc | 3 + .../arm64/instruction-selector-arm64-unittest.cc | 83 +++++++++++++++++++--- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc index 913dba8..014525f 100644 --- a/src/compiler/arm64/instruction-selector-arm64.cc +++ b/src/compiler/arm64/instruction-selector-arm64.cc @@ -1157,6 +1157,9 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, case IrOpcode::kWord32And: return VisitWordCompare(this, value, kArm64Tst32, &cont, true, kLogical32Imm); + case IrOpcode::kWord64And: + return VisitWordCompare(this, value, kArm64Tst, &cont, true, + kLogical64Imm); default: break; } diff --git a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc index 1f0c8ad..8a6384d 100644 --- a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc +++ b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc @@ -74,7 +74,7 @@ static const MachInst2 kLogicalInstructions[] = { // ARM64 logical immediates: contiguous set bits, rotated about a power of two // sized block. The block is then duplicated across the word. Below is a random // subset of the 32-bit immediates. -static const uint32_t kLogicalImmediates[] = { +static const uint32_t kLogical32Immediates[] = { 0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0, 0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000, 0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000, @@ -94,6 +94,31 @@ static const uint32_t kLogicalImmediates[] = { 0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff}; +// Random subset of 64-bit logical immediates. +static const uint64_t kLogical64Immediates[] = { + 0x0000000000000001, 0x0000000000000002, 0x0000000000000003, + 0x0000000000000070, 0x0000000000000080, 0x0000000000000100, + 0x00000000000001c0, 0x0000000000000300, 0x0000000000000600, + 0x00000000000007e0, 0x0000000000003ffc, 0x0000000000007fc0, + 0x0000000600000000, 0x0000003ffffffffc, 0x000000f000000000, + 0x000001f800000000, 0x0003fc0000000000, 0x0003fc000003fc00, + 0x0003ffffffc00000, 0x0003ffffffffffc0, 0x0006000000060000, + 0x003ffffffffc0000, 0x0180018001800180, 0x01f801f801f801f8, + 0x0600000000000000, 0x1000000010000000, 0x1000100010001000, + 0x1010101010101010, 0x1111111111111111, 0x1f001f001f001f00, + 0x1f1f1f1f1f1f1f1f, 0x1ffffffffffffffe, 0x3ffc3ffc3ffc3ffc, + 0x5555555555555555, 0x7f7f7f7f7f7f7f7f, 0x8000000000000000, + 0x8000001f8000001f, 0x8181818181818181, 0x9999999999999999, + 0x9fff9fff9fff9fff, 0xaaaaaaaaaaaaaaaa, 0xdddddddddddddddd, + 0xe0000000000001ff, 0xf800000000000000, 0xf8000000000001ff, + 0xf807f807f807f807, 0xfefefefefefefefe, 0xfffefffefffefffe, + 0xfffff807fffff807, 0xfffff9fffffff9ff, 0xfffffc0ffffffc0f, + 0xfffffc0fffffffff, 0xfffffefffffffeff, 0xfffffeffffffffff, + 0xffffff8000000000, 0xfffffffefffffffe, 0xffffffffefffffff, + 0xfffffffff9ffffff, 0xffffffffff800000, 0xffffffffffffc0ff, + 0xfffffffffffffffe}; + + // ARM64 arithmetic instructions. struct AddSub { MachInst2 mi; @@ -138,7 +163,8 @@ static const int32_t kAddSubImmediates[] = { static const MachInst2 kDPFlagSetInstructions[] = { {&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32, kMachInt32}, {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32, kMachInt32}, - {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, kMachInt32}}; + {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, kMachInt32}, + {&RawMachineAssembler::Word64And, "Word64And", kArm64Tst, kMachInt64}}; // ARM64 arithmetic with overflow instructions. @@ -287,7 +313,7 @@ TEST_P(InstructionSelectorLogicalTest, Immediate) { // TODO(all): Add support for testing 64-bit immediates. if (type == kMachInt32) { // Immediate on the right. - TRACED_FOREACH(int32_t, imm, kLogicalImmediates) { + TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { StreamBuilder m(this, type, type); m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); Stream s = m.Build(); @@ -300,7 +326,7 @@ TEST_P(InstructionSelectorLogicalTest, Immediate) { } // Immediate on the left; all logical ops should commute. - TRACED_FOREACH(int32_t, imm, kLogicalImmediates) { + TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { StreamBuilder m(this, type, type); m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0))); Stream s = m.Build(); @@ -621,8 +647,8 @@ INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, ::testing::ValuesIn(kDPFlagSetInstructions)); -TEST_F(InstructionSelectorTest, AndBranchWithImmediateOnRight) { - TRACED_FOREACH(int32_t, imm, kLogicalImmediates) { +TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnRight) { + TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { StreamBuilder m(this, kMachInt32, kMachInt32); MLabel a, b; m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b); @@ -641,6 +667,26 @@ TEST_F(InstructionSelectorTest, AndBranchWithImmediateOnRight) { } +TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnRight) { + TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { + StreamBuilder m(this, kMachInt64, kMachInt64); + MLabel a, b; + m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(imm)), &a, &b); + m.Bind(&a); + m.Return(m.Int32Constant(1)); + m.Bind(&b); + m.Return(m.Int32Constant(0)); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); + EXPECT_EQ(4U, s[0]->InputCount()); + EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); + EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); + EXPECT_EQ(kNotEqual, s[0]->flags_condition()); + } +} + + TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnRight) { TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { StreamBuilder m(this, kMachInt32, kMachInt32); @@ -677,8 +723,8 @@ TEST_F(InstructionSelectorTest, SubBranchWithImmediateOnRight) { } -TEST_F(InstructionSelectorTest, AndBranchWithImmediateOnLeft) { - TRACED_FOREACH(int32_t, imm, kLogicalImmediates) { +TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) { + TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { StreamBuilder m(this, kMachInt32, kMachInt32); MLabel a, b; m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b); @@ -698,6 +744,27 @@ TEST_F(InstructionSelectorTest, AndBranchWithImmediateOnLeft) { } +TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) { + TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { + StreamBuilder m(this, kMachInt64, kMachInt64); + MLabel a, b; + m.Branch(m.Word64And(m.Int64Constant(imm), m.Parameter(0)), &a, &b); + m.Bind(&a); + m.Return(m.Int32Constant(1)); + m.Bind(&b); + m.Return(m.Int32Constant(0)); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); + EXPECT_EQ(4U, s[0]->InputCount()); + EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); + ASSERT_LE(1U, s[0]->InputCount()); + EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); + EXPECT_EQ(kNotEqual, s[0]->flags_condition()); + } +} + + TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) { TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { StreamBuilder m(this, kMachInt32, kMachInt32); -- 2.7.4