ARM64: Refactor instruction selection unit tests.
authorrodolph.perfetta@arm.com <rodolph.perfetta@arm.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 19 Aug 2014 10:14:29 +0000 (10:14 +0000)
committerrodolph.perfetta@arm.com <rodolph.perfetta@arm.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 19 Aug 2014 10:14:29 +0000 (10:14 +0000)
BUG=
R=bmeurer@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23188 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc

index e0de590..72ab8f2 100644 (file)
@@ -18,6 +18,7 @@ struct DPI {
   Constructor constructor;
   const char* constructor_name;
   ArchOpcode arch_opcode;
+  MachineType machine_type;
 };
 
 
@@ -28,105 +29,139 @@ std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
 
 // ARM64 Logical instructions.
 static const DPI kLogicalInstructions[] = {
-    {&RawMachineAssembler::Word32And, "Word32And", kArm64And32},
-    {&RawMachineAssembler::Word64And, "Word64And", kArm64And},
-    {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32},
-    {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or},
-    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32},
-    {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor}};
+    {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32},
+    {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64},
+    {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32},
+    {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64},
+    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32, kMachInt32},
+    {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}};
 
 
 // ARM64 Arithmetic instructions.
 static const DPI kAddSubInstructions[] = {
-    {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32},
-    {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add},
-    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32},
-    {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub}};
-
-
-// ARM64 Add/Sub immediates.
-// TODO(all): Test only a subset of the immediates, similar to what we do for
-// arm. Unit tests should be really fast!
-class AddSubImmediates V8_FINAL : public std::list<int32_t> {
- public:
-  AddSubImmediates() {
-    for (int32_t imm12 = 0; imm12 < 4096; ++imm12) {
-      CHECK(Assembler::IsImmAddSub(imm12));
-      CHECK(Assembler::IsImmAddSub(imm12 << 12));
-      push_back(imm12);
-      push_back(imm12 << 12);
-    }
-  }
-};
+    {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32},
+    {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64},
+    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32},
+    {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}};
+
+
+// ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12.
+// Below is a combination of a random subset and some edge values.
+static const int32_t kAddSubImmediates[] = {
+    0,        1,        69,       493,      599,      701,      719,
+    768,      818,      842,      945,      1246,     1286,     1429,
+    1669,     2171,     2179,     2182,     2254,     2334,     2338,
+    2343,     2396,     2449,     2610,     2732,     2855,     2876,
+    2944,     3377,     3458,     3475,     3476,     3540,     3574,
+    3601,     3813,     3871,     3917,     4095,     4096,     16384,
+    364544,   462848,   970752,   1523712,  1863680,  2363392,  3219456,
+    3280896,  4247552,  4526080,  4575232,  4960256,  5505024,  5894144,
+    6004736,  6193152,  6385664,  6795264,  7114752,  7233536,  7348224,
+    7499776,  7573504,  7729152,  8634368,  8937472,  9465856,  10354688,
+    10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224,
+    15597568, 15892480, 16773120};
 
 
 // ARM64 Mul/Div instructions.
 static const DPI kMulDivInstructions[] = {
-    {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32},
-    {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul},
-    {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32},
-    {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv},
-    {&RawMachineAssembler::Int32UDiv, "Int32UDiv", kArm64Udiv32},
-    {&RawMachineAssembler::Int64UDiv, "Int64UDiv", kArm64Udiv}};
+    {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32},
+    {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64},
+    {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32},
+    {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64},
+    {&RawMachineAssembler::Int32UDiv, "Int32UDiv", kArm64Udiv32, kMachInt32},
+    {&RawMachineAssembler::Int64UDiv, "Int64UDiv", kArm64Udiv, kMachInt64}};
 
 }  // namespace
 
 
-// TODO(all): Use TEST_P, see instruction-selector-arm-unittest.cc.
-TEST_F(InstructionSelectorTest, LogicalWithParameter) {
-  TRACED_FOREACH(DPI, dpi, kLogicalInstructions) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    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());
-  }
-}
+// -----------------------------------------------------------------------------
+// Logical instructions.
 
 
-// TODO(all): Use TEST_P, see instruction-selector-arm-unittest.cc.
-TEST_F(InstructionSelectorTest, AddSubWithParameter) {
-  TRACED_FOREACH(DPI, dpi, kAddSubInstructions) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    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());
-  }
+typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorLogicalTest;
+
+TEST_P(InstructionSelectorLogicalTest, 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());
 }
 
 
-// TODO(all): Use TEST_P, see instruction-selector-arm-unittest.cc.
-TEST_F(InstructionSelectorTest, AddSubWithImmediate) {
-  AddSubImmediates immediates;
-  TRACED_FOREACH(DPI, dpi, kAddSubInstructions) {
-    for (AddSubImmediates::const_iterator j = immediates.begin();
-         j != immediates.end(); ++j) {
-      int32_t imm = *j;
-      SCOPED_TRACE(::testing::Message() << "imm = " << imm);
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      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_TRUE(s[0]->InputAt(1)->IsImmediate());
-    }
-  }
+// TODO(all): add immediate tests.
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
+                        ::testing::ValuesIn(kLogicalInstructions));
+
+
+// -----------------------------------------------------------------------------
+// Add and Sub instructions.
+
+typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorAddSubTest;
+
+TEST_P(InstructionSelectorAddSubTest, 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());
 }
 
 
-// TODO(all): Use TEST_P, see instruction-selector-arm-unittest.cc.
-TEST_F(InstructionSelectorTest, MulDivWithParameter) {
-  TRACED_FOREACH(DPI, dpi, kMulDivInstructions) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+TEST_P(InstructionSelectorAddSubTest, Immediate) {
+  const DPI dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    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());
   }
 }
 
 
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest,
+                        ::testing::ValuesIn(kAddSubInstructions));
+
+
+// -----------------------------------------------------------------------------
+// Mul and Div instructions.
+
+
+typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorMulDivTest;
+
+
+TEST_P(InstructionSelectorMulDivTest, 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());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest,
+                        ::testing::ValuesIn(kMulDivInstructions));
+
+
 // -----------------------------------------------------------------------------
 // Conversions.