From a8b09acd7b9a97a1ec38e17aaba43010caeee013 Mon Sep 17 00:00:00 2001 From: "m.m.capewell@googlemail.com" Date: Wed, 20 Aug 2014 09:25:30 +0000 Subject: [PATCH] [turbofan] Add ARM64 tests and fix shift bug Add more tests for logical immediate and shift instruction selection, and fix bug in range for supported shifts. BUG= R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/487163004 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23220 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- .../arm64/instruction-selector-arm64.cc | 4 +- .../instruction-selector-arm64-unittest.cc | 108 +++++++++++++++++- 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc index b46906280..f6a80dec2 100644 --- a/src/compiler/arm64/instruction-selector-arm64.cc +++ b/src/compiler/arm64/instruction-selector-arm64.cc @@ -57,9 +57,9 @@ class Arm64OperandGenerator V8_FINAL : public OperandGenerator { // TODO(dcarney): -values can be handled by instruction swapping return Assembler::IsImmAddSub(value); case kShift32Imm: - return 0 <= value && value < 31; + return 0 <= value && value < 32; case kShift64Imm: - return 0 <= value && value < 63; + return 0 <= value && value < 64; case kLoadStoreImm: return (0 <= value && value < (1 << 9)) || (-(1 << 6) <= value && value < (1 << 6)); diff --git a/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc b/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc index 72ab8f25b..29bc926d3 100644 --- a/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc +++ b/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc @@ -37,6 +37,29 @@ static const DPI kLogicalInstructions[] = { {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}}; +// 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[] = { + 0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0, + 0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000, + 0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000, + 0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000, + 0x01800000, 0x01800180, 0x01f801f8, 0x03fe0000, 0x03ffffc0, 0x03fffffc, + 0x06000000, 0x07fc0000, 0x07ffc000, 0x07ffffc0, 0x07ffffe0, 0x0ffe0ffe, + 0x0ffff800, 0x0ffffff0, 0x0fffffff, 0x18001800, 0x1f001f00, 0x1f801f80, + 0x30303030, 0x3ff03ff0, 0x3ff83ff8, 0x3fff0000, 0x3fff8000, 0x3fffffc0, + 0x70007000, 0x7f7f7f7f, 0x7fc00000, 0x7fffffc0, 0x8000001f, 0x800001ff, + 0x81818181, 0x9fff9fff, 0xc00007ff, 0xc0ffffff, 0xdddddddd, 0xe00001ff, + 0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff, + 0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff, + 0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000, + 0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf, + 0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff, + 0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff, + 0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff}; + + // ARM64 Arithmetic instructions. static const DPI kAddSubInstructions[] = { {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32}, @@ -62,6 +85,18 @@ static const int32_t kAddSubImmediates[] = { 15597568, 15892480, 16773120}; +// ARM64 shift instructions. +static const DPI kShiftInstructions[] = { + {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32}, + {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64}, + {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32}, + {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Shr, kMachInt64}, + {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Sar32, kMachInt32}, + {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Sar, kMachInt64}, + {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, + {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}}; + + // ARM64 Mul/Div instructions. static const DPI kMulDivInstructions[] = { {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32}, @@ -93,7 +128,38 @@ TEST_P(InstructionSelectorLogicalTest, Parameter) { } -// TODO(all): add immediate tests. +TEST_P(InstructionSelectorLogicalTest, Immediate) { + const DPI dpi = GetParam(); + const MachineType type = dpi.machine_type; + // TODO(all): Add support for testing 64-bit immediates. + if (type == kMachInt32) { + // Immediate on the right. + TRACED_FOREACH(uint32_t, imm, kLogicalImmediates) { + StreamBuilder m(this, type, type); + m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); + EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); + EXPECT_EQ(1U, s[0]->OutputCount()); + } + + // Immediate on the left; all logical ops should commute. + TRACED_FOREACH(uint32_t, imm, kLogicalImmediates) { + StreamBuilder m(this, type, type); + m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); + EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); + EXPECT_EQ(1U, s[0]->OutputCount()); + } + } +} INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, @@ -139,6 +205,46 @@ INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, ::testing::ValuesIn(kAddSubInstructions)); +// ----------------------------------------------------------------------------- +// Shift instructions. + + +typedef InstructionSelectorTestWithParam InstructionSelectorShiftTest; + +TEST_P(InstructionSelectorShiftTest, Parameter) { + const DPI dpi = GetParam(); + const MachineType type = dpi.machine_type; + StreamBuilder m(this, type, type, type); + m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); + EXPECT_EQ(2U, s[0]->InputCount()); + EXPECT_EQ(1U, s[0]->OutputCount()); +} + + +TEST_P(InstructionSelectorShiftTest, Immediate) { + const DPI dpi = GetParam(); + const MachineType type = dpi.machine_type; + TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { + StreamBuilder m(this, type, type); + m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); + EXPECT_EQ(2U, s[0]->InputCount()); + EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); + EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); + EXPECT_EQ(1U, s[0]->OutputCount()); + } +} + + +INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, + ::testing::ValuesIn(kShiftInstructions)); + + // ----------------------------------------------------------------------------- // Mul and Div instructions. -- 2.34.1