Chromium Code Reviews| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff, | 79 0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff, |
| 80 0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff, | 80 0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff, |
| 81 0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000, | 81 0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000, |
| 82 0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf, | 82 0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf, |
| 83 0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff, | 83 0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff, |
| 84 0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff, | 84 0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff, |
| 85 0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff}; | 85 0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff}; |
| 86 | 86 |
| 87 | 87 |
| 88 // ARM64 arithmetic instructions. | 88 // ARM64 arithmetic instructions. |
| 89 static const MachInst2 kAddSubInstructions[] = { | 89 struct AddSub { |
| 90 {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32}, | 90 MachInst2 mi; |
| 91 {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64}, | 91 ArchOpcode negate_arch_opcode; |
| 92 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32}, | 92 }; |
| 93 {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}}; | 93 |
| 94 | |
| 95 std::ostream& operator<<(std::ostream& os, const AddSub& op) { | |
| 96 return os << op.mi; | |
| 97 } | |
| 98 | |
| 99 | |
| 100 static const AddSub kAddSubInstructions[] = { | |
| 101 {{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32}, | |
| 102 kArm64Sub32}, | |
| 103 {{&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64}, | |
| 104 kArm64Sub}, | |
| 105 {{&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32}, | |
| 106 kArm64Add32}, | |
| 107 {{&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}, | |
| 108 kArm64Add}}; | |
| 94 | 109 |
| 95 | 110 |
| 96 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12. | 111 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12. |
| 97 // Below is a combination of a random subset and some edge values. | 112 // Below is a combination of a random subset and some edge values. |
| 98 static const int32_t kAddSubImmediates[] = { | 113 static const int32_t kAddSubImmediates[] = { |
| 99 0, 1, 69, 493, 599, 701, 719, | 114 0, 1, 69, 493, 599, 701, 719, |
| 100 768, 818, 842, 945, 1246, 1286, 1429, | 115 768, 818, 842, 945, 1246, 1286, 1429, |
| 101 1669, 2171, 2179, 2182, 2254, 2334, 2338, | 116 1669, 2171, 2179, 2182, 2254, 2334, 2338, |
| 102 2343, 2396, 2449, 2610, 2732, 2855, 2876, | 117 2343, 2396, 2449, 2610, 2732, 2855, 2876, |
| 103 2944, 3377, 3458, 3475, 3476, 3540, 3574, | 118 2944, 3377, 3458, 3475, 3476, 3540, 3574, |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 } | 298 } |
| 284 | 299 |
| 285 | 300 |
| 286 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, | 301 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, |
| 287 ::testing::ValuesIn(kLogicalInstructions)); | 302 ::testing::ValuesIn(kLogicalInstructions)); |
| 288 | 303 |
| 289 | 304 |
| 290 // ----------------------------------------------------------------------------- | 305 // ----------------------------------------------------------------------------- |
| 291 // Add and Sub instructions. | 306 // Add and Sub instructions. |
| 292 | 307 |
| 293 typedef InstructionSelectorTestWithParam<MachInst2> | 308 typedef InstructionSelectorTestWithParam<AddSub> InstructionSelectorAddSubTest; |
| 294 InstructionSelectorAddSubTest; | |
| 295 | 309 |
| 296 | 310 |
| 297 TEST_P(InstructionSelectorAddSubTest, Parameter) { | 311 TEST_P(InstructionSelectorAddSubTest, Parameter) { |
| 298 const MachInst2 dpi = GetParam(); | 312 const AddSub dpi = GetParam(); |
| 299 const MachineType type = dpi.machine_type; | 313 const MachineType type = dpi.mi.machine_type; |
| 300 StreamBuilder m(this, type, type, type); | 314 StreamBuilder m(this, type, type, type); |
| 301 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 315 m.Return((m.*dpi.mi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 302 Stream s = m.Build(); | 316 Stream s = m.Build(); |
| 303 ASSERT_EQ(1U, s.size()); | 317 ASSERT_EQ(1U, s.size()); |
| 304 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 318 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode()); |
| 305 EXPECT_EQ(2U, s[0]->InputCount()); | 319 EXPECT_EQ(2U, s[0]->InputCount()); |
| 306 EXPECT_EQ(1U, s[0]->OutputCount()); | 320 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 307 } | 321 } |
| 308 | 322 |
| 309 | 323 |
| 310 TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) { | 324 TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) { |
| 311 const MachInst2 dpi = GetParam(); | 325 const AddSub dpi = GetParam(); |
| 312 const MachineType type = dpi.machine_type; | 326 const MachineType type = dpi.mi.machine_type; |
| 313 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 327 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 314 StreamBuilder m(this, type, type); | 328 StreamBuilder m(this, type, type); |
| 315 m.Return((m.*dpi.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); | 329 m.Return( |
| 330 (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); | |
| 316 Stream s = m.Build(); | 331 Stream s = m.Build(); |
| 317 ASSERT_EQ(1U, s.size()); | 332 ASSERT_EQ(1U, s.size()); |
| 318 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 333 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode()); |
| 319 ASSERT_EQ(2U, s[0]->InputCount()); | 334 ASSERT_EQ(2U, s[0]->InputCount()); |
| 320 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 335 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 321 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); | 336 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
| 322 EXPECT_EQ(1U, s[0]->OutputCount()); | 337 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 323 } | 338 } |
| 324 } | 339 } |
| 325 | 340 |
| 326 | 341 |
| 342 TEST_P(InstructionSelectorAddSubTest, NegImmediateOnRight) { | |
| 343 const AddSub dpi = GetParam(); | |
| 344 const MachineType type = dpi.mi.machine_type; | |
| 345 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | |
| 346 if (imm == 0) continue; | |
| 347 StreamBuilder m(this, type, type); | |
| 348 m.Return( | |
| 349 (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(m, type, -imm))); | |
| 350 Stream s = m.Build(); | |
| 351 ASSERT_EQ(1U, s.size()); | |
| 352 EXPECT_EQ(dpi.negate_arch_opcode, s[0]->arch_opcode()); | |
| 353 ASSERT_EQ(2U, s[0]->InputCount()); | |
| 354 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); | |
| 355 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | |
| 356 EXPECT_EQ(1U, s[0]->OutputCount()); | |
| 357 } | |
| 358 } | |
| 359 | |
| 360 | |
| 327 TEST_P(InstructionSelectorAddSubTest, ImmediateOnLeft) { | 361 TEST_P(InstructionSelectorAddSubTest, ImmediateOnLeft) { |
| 328 const MachInst2 dpi = GetParam(); | 362 const AddSub dpi = GetParam(); |
| 329 const MachineType type = dpi.machine_type; | 363 const MachineType type = dpi.mi.machine_type; |
| 330 | 364 |
| 331 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 365 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 332 StreamBuilder m(this, type, type); | 366 StreamBuilder m(this, type, type); |
| 333 m.Return((m.*dpi.constructor)(BuildConstant(m, type, imm), m.Parameter(0))); | 367 m.Return( |
| 368 (m.*dpi.mi.constructor)(BuildConstant(m, type, imm), m.Parameter(0))); | |
| 334 Stream s = m.Build(); | 369 Stream s = m.Build(); |
| 335 | 370 |
| 336 // Add can support an immediate on the left by commuting, but Sub can't | 371 // Add can support an immediate on the left by commuting, but Sub can't |
| 337 // commute. We test zero-on-left Sub later. | 372 // commute. We test zero-on-left Sub later. |
| 338 if (strstr(dpi.constructor_name, "Add") != NULL) { | 373 if (strstr(dpi.mi.constructor_name, "Add") != NULL) { |
|
Benedikt Meurer
2014/09/30 04:47:49
See comment below.
| |
| 339 ASSERT_EQ(1U, s.size()); | 374 ASSERT_EQ(1U, s.size()); |
| 340 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 375 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode()); |
| 341 ASSERT_EQ(2U, s[0]->InputCount()); | 376 ASSERT_EQ(2U, s[0]->InputCount()); |
| 342 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 377 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
| 343 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); | 378 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); |
| 344 EXPECT_EQ(1U, s[0]->OutputCount()); | 379 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 345 } | 380 } |
| 346 } | 381 } |
| 347 } | 382 } |
| 348 | 383 |
| 349 | 384 |
| 385 TEST_P(InstructionSelectorAddSubTest, NegImmediateOnLeft) { | |
| 386 const AddSub dpi = GetParam(); | |
| 387 const MachineType type = dpi.mi.machine_type; | |
| 388 | |
| 389 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | |
| 390 if (imm == 0) continue; | |
| 391 StreamBuilder m(this, type, type); | |
| 392 m.Return( | |
| 393 (m.*dpi.mi.constructor)(BuildConstant(m, type, -imm), m.Parameter(0))); | |
| 394 Stream s = m.Build(); | |
| 395 | |
| 396 // Add can support an immediate on the left by commuting, but Sub can't | |
| 397 // commute. | |
| 398 if (strstr(dpi.mi.constructor_name, "Add") != NULL) { | |
|
Benedikt Meurer
2014/09/30 04:47:49
Please split the test case instead of filtering, i
m.m.capewell
2014/09/30 17:42:09
I can do this, or add a new "commutes" bool in the
Benedikt Meurer
2014/10/01 15:21:46
Split it, please.
m.m.capewell
2014/10/02 14:43:43
Done.
| |
| 399 ASSERT_EQ(1U, s.size()); | |
| 400 EXPECT_EQ(dpi.negate_arch_opcode, s[0]->arch_opcode()); | |
| 401 ASSERT_EQ(2U, s[0]->InputCount()); | |
| 402 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); | |
| 403 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | |
| 404 EXPECT_EQ(1U, s[0]->OutputCount()); | |
| 405 } | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 | |
| 350 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, | 410 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, |
| 351 ::testing::ValuesIn(kAddSubInstructions)); | 411 ::testing::ValuesIn(kAddSubInstructions)); |
| 352 | 412 |
| 353 | 413 |
| 354 TEST_F(InstructionSelectorTest, SubZeroOnLeft) { | 414 TEST_F(InstructionSelectorTest, SubZeroOnLeft) { |
| 355 // Subtraction with zero on the left maps to Neg. | 415 // Subtraction with zero on the left maps to Neg. |
| 356 { | 416 { |
| 357 // 32-bit subtract. | 417 // 32-bit subtract. |
| 358 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 418 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); |
| 359 m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0))); | 419 m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0))); |
| (...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1388 ASSERT_EQ(1U, s.size()); | 1448 ASSERT_EQ(1U, s.size()); |
| 1389 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); | 1449 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); |
| 1390 EXPECT_EQ(1U, s[0]->InputCount()); | 1450 EXPECT_EQ(1U, s[0]->InputCount()); |
| 1391 EXPECT_EQ(1U, s[0]->OutputCount()); | 1451 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 1392 } | 1452 } |
| 1393 } | 1453 } |
| 1394 | 1454 |
| 1395 } // namespace compiler | 1455 } // namespace compiler |
| 1396 } // namespace internal | 1456 } // namespace internal |
| 1397 } // namespace v8 | 1457 } // namespace v8 |
| OLD | NEW |