OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <list> | 5 #include <list> |
6 | 6 |
7 #include "src/compiler/instruction-selector-unittest.h" | 7 #include "src/compiler/instruction-selector-unittest.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 14 matching lines...) Expand all Loading... |
25 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1; | 25 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1; |
26 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2; | 26 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2; |
27 | 27 |
28 | 28 |
29 template <typename T> | 29 template <typename T> |
30 std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) { | 30 std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) { |
31 return os << mi.constructor_name; | 31 return os << mi.constructor_name; |
32 } | 32 } |
33 | 33 |
34 | 34 |
| 35 // Helper to build Int32Constant or Int64Constant depending on the given |
| 36 // machine type. |
| 37 Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type, |
| 38 int64_t value) { |
| 39 switch (type) { |
| 40 case kMachInt32: |
| 41 return m.Int32Constant(value); |
| 42 break; |
| 43 |
| 44 case kMachInt64: |
| 45 return m.Int64Constant(value); |
| 46 break; |
| 47 |
| 48 default: |
| 49 UNIMPLEMENTED(); |
| 50 } |
| 51 return NULL; |
| 52 } |
| 53 |
| 54 |
35 // ARM64 logical instructions. | 55 // ARM64 logical instructions. |
36 static const MachInst2 kLogicalInstructions[] = { | 56 static const MachInst2 kLogicalInstructions[] = { |
37 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32}, | 57 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32}, |
38 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64}, | 58 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64}, |
39 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32}, | 59 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32}, |
40 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64}, | 60 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64}, |
41 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32, kMachInt32}, | 61 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32, kMachInt32}, |
42 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}}; | 62 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}}; |
43 | 63 |
44 | 64 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 EXPECT_EQ(2U, s[0]->InputCount()); | 299 EXPECT_EQ(2U, s[0]->InputCount()); |
280 EXPECT_EQ(1U, s[0]->OutputCount()); | 300 EXPECT_EQ(1U, s[0]->OutputCount()); |
281 } | 301 } |
282 | 302 |
283 | 303 |
284 TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) { | 304 TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) { |
285 const MachInst2 dpi = GetParam(); | 305 const MachInst2 dpi = GetParam(); |
286 const MachineType type = dpi.machine_type; | 306 const MachineType type = dpi.machine_type; |
287 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 307 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
288 StreamBuilder m(this, type, type); | 308 StreamBuilder m(this, type, type); |
289 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 309 m.Return((m.*dpi.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); |
290 Stream s = m.Build(); | 310 Stream s = m.Build(); |
291 ASSERT_EQ(1U, s.size()); | 311 ASSERT_EQ(1U, s.size()); |
292 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 312 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
293 ASSERT_EQ(2U, s[0]->InputCount()); | 313 ASSERT_EQ(2U, s[0]->InputCount()); |
294 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 314 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
295 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 315 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
296 EXPECT_EQ(1U, s[0]->OutputCount()); | 316 EXPECT_EQ(1U, s[0]->OutputCount()); |
297 } | 317 } |
298 } | 318 } |
299 | 319 |
300 | 320 |
301 TEST_P(InstructionSelectorAddSubTest, ImmediateOnLeft) { | 321 TEST_P(InstructionSelectorAddSubTest, ImmediateOnLeft) { |
302 const MachInst2 dpi = GetParam(); | 322 const MachInst2 dpi = GetParam(); |
303 const MachineType type = dpi.machine_type; | 323 const MachineType type = dpi.machine_type; |
304 | 324 |
305 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 325 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
306 StreamBuilder m(this, type, type); | 326 StreamBuilder m(this, type, type); |
307 m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0))); | 327 m.Return((m.*dpi.constructor)(BuildConstant(m, type, imm), m.Parameter(0))); |
308 Stream s = m.Build(); | 328 Stream s = m.Build(); |
309 | 329 |
310 // Add can support an immediate on the left by commuting, but Sub can't | 330 // Add can support an immediate on the left by commuting, but Sub can't |
311 // commute. We test zero-on-left Sub later. | 331 // commute. We test zero-on-left Sub later. |
312 if (strstr(dpi.constructor_name, "Add") != NULL) { | 332 if (strstr(dpi.constructor_name, "Add") != NULL) { |
313 ASSERT_EQ(1U, s.size()); | 333 ASSERT_EQ(1U, s.size()); |
314 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 334 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
315 ASSERT_EQ(2U, s[0]->InputCount()); | 335 ASSERT_EQ(2U, s[0]->InputCount()); |
316 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 336 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
317 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 337 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
318 EXPECT_EQ(1U, s[0]->OutputCount()); | 338 EXPECT_EQ(1U, s[0]->OutputCount()); |
319 } | 339 } |
320 } | 340 } |
321 } | 341 } |
322 | 342 |
323 | 343 |
324 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, | 344 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, |
325 ::testing::ValuesIn(kAddSubInstructions)); | 345 ::testing::ValuesIn(kAddSubInstructions)); |
326 | 346 |
327 | 347 |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 EXPECT_EQ(2U, s[0]->InputCount()); | 1017 EXPECT_EQ(2U, s[0]->InputCount()); |
998 EXPECT_EQ(1U, s[0]->OutputCount()); | 1018 EXPECT_EQ(1U, s[0]->OutputCount()); |
999 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1019 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1000 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1020 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
1001 } | 1021 } |
1002 | 1022 |
1003 | 1023 |
1004 TEST_P(InstructionSelectorComparisonTest, WithImmediate) { | 1024 TEST_P(InstructionSelectorComparisonTest, WithImmediate) { |
1005 const MachInst2 cmp = GetParam(); | 1025 const MachInst2 cmp = GetParam(); |
1006 const MachineType type = cmp.machine_type; | 1026 const MachineType type = cmp.machine_type; |
1007 // TODO(all): Add support for testing 64-bit immediates. | 1027 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
1008 if (type == kMachInt32) { | 1028 // Compare with 0 are turned into tst instruction. |
1009 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1029 if (imm == 0) continue; |
1010 // Compare with 0 are turned into tst instruction. | 1030 StreamBuilder m(this, type, type); |
1011 if (imm == 0) continue; | 1031 m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); |
1012 StreamBuilder m(this, type, type); | 1032 Stream s = m.Build(); |
1013 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 1033 ASSERT_EQ(1U, s.size()); |
1014 Stream s = m.Build(); | 1034 EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode()); |
1015 ASSERT_EQ(1U, s.size()); | 1035 ASSERT_EQ(2U, s[0]->InputCount()); |
1016 EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode()); | 1036 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
1017 ASSERT_EQ(2U, s[0]->InputCount()); | 1037 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
1018 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1038 EXPECT_EQ(1U, s[0]->OutputCount()); |
1019 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 1039 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1020 EXPECT_EQ(1U, s[0]->OutputCount()); | 1040 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
1021 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1041 } |
1022 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1042 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
1023 } | 1043 // Compare with 0 are turned into tst instruction. |
1024 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 1044 if (imm == 0) continue; |
1025 // Compare with 0 are turned into tst instruction. | 1045 StreamBuilder m(this, type, type); |
1026 if (imm == 0) continue; | 1046 m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); |
1027 StreamBuilder m(this, type, type); | 1047 Stream s = m.Build(); |
1028 m.Return((m.*cmp.constructor)(m.Int32Constant(imm), m.Parameter(0))); | 1048 ASSERT_EQ(1U, s.size()); |
1029 Stream s = m.Build(); | 1049 EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode()); |
1030 ASSERT_EQ(1U, s.size()); | 1050 ASSERT_EQ(2U, s[0]->InputCount()); |
1031 EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode()); | 1051 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
1032 ASSERT_EQ(2U, s[0]->InputCount()); | 1052 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
1033 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 1053 EXPECT_EQ(1U, s[0]->OutputCount()); |
1034 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 1054 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1035 EXPECT_EQ(1U, s[0]->OutputCount()); | 1055 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
1036 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | |
1037 EXPECT_EQ(kEqual, s[0]->flags_condition()); | |
1038 } | |
1039 } | 1056 } |
1040 } | 1057 } |
1041 | 1058 |
1042 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 1059 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
1043 InstructionSelectorComparisonTest, | 1060 InstructionSelectorComparisonTest, |
1044 ::testing::ValuesIn(kComparisonInstructions)); | 1061 ::testing::ValuesIn(kComparisonInstructions)); |
1045 | 1062 |
1046 | 1063 |
1047 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { | 1064 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { |
1048 { | 1065 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1095 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 1112 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); |
1096 EXPECT_EQ(1U, s[0]->OutputCount()); | 1113 EXPECT_EQ(1U, s[0]->OutputCount()); |
1097 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 1114 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
1098 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 1115 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
1099 } | 1116 } |
1100 } | 1117 } |
1101 | 1118 |
1102 } // namespace compiler | 1119 } // namespace compiler |
1103 } // namespace internal | 1120 } // namespace internal |
1104 } // namespace v8 | 1121 } // namespace v8 |
OLD | NEW |