| 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 |