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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 2944, 3377, 3458, 3475, 3476, 3540, 3574, | 81 2944, 3377, 3458, 3475, 3476, 3540, 3574, |
| 82 3601, 3813, 3871, 3917, 4095, 4096, 16384, | 82 3601, 3813, 3871, 3917, 4095, 4096, 16384, |
| 83 364544, 462848, 970752, 1523712, 1863680, 2363392, 3219456, | 83 364544, 462848, 970752, 1523712, 1863680, 2363392, 3219456, |
| 84 3280896, 4247552, 4526080, 4575232, 4960256, 5505024, 5894144, | 84 3280896, 4247552, 4526080, 4575232, 4960256, 5505024, 5894144, |
| 85 6004736, 6193152, 6385664, 6795264, 7114752, 7233536, 7348224, | 85 6004736, 6193152, 6385664, 6795264, 7114752, 7233536, 7348224, |
| 86 7499776, 7573504, 7729152, 8634368, 8937472, 9465856, 10354688, | 86 7499776, 7573504, 7729152, 8634368, 8937472, 9465856, 10354688, |
| 87 10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224, | 87 10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224, |
| 88 15597568, 15892480, 16773120}; | 88 15597568, 15892480, 16773120}; |
| 89 | 89 |
| 90 | 90 |
| 91 // ARM64 arithmetic with overflow instructions. | |
| 92 static const MachInst2 kOvfAddSubInstructions[] = { | |
| 93 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", | |
| 94 kArm64Add32, kMachInt32}, | |
| 95 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", | |
| 96 kArm64Sub32, kMachInt32}}; | |
| 97 | |
| 98 | |
| 91 // ARM64 shift instructions. | 99 // ARM64 shift instructions. |
| 92 static const MachInst2 kShiftInstructions[] = { | 100 static const MachInst2 kShiftInstructions[] = { |
| 93 {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32}, | 101 {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32}, |
| 94 {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64}, | 102 {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64}, |
| 95 {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32}, | 103 {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32}, |
| 96 {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Shr, kMachInt64}, | 104 {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Shr, kMachInt64}, |
| 97 {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Sar32, kMachInt32}, | 105 {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Sar32, kMachInt32}, |
| 98 {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Sar, kMachInt64}, | 106 {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Sar, kMachInt64}, |
| 99 {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, | 107 {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, |
| 100 {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}}; | 108 {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}}; |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 | 337 |
| 330 ASSERT_EQ(1U, s.size()); | 338 ASSERT_EQ(1U, s.size()); |
| 331 EXPECT_EQ(kArm64Neg, s[0]->arch_opcode()); | 339 EXPECT_EQ(kArm64Neg, s[0]->arch_opcode()); |
| 332 EXPECT_EQ(1U, s[0]->InputCount()); | 340 EXPECT_EQ(1U, s[0]->InputCount()); |
| 333 EXPECT_EQ(1U, s[0]->OutputCount()); | 341 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 334 } | 342 } |
| 335 } | 343 } |
| 336 | 344 |
| 337 | 345 |
| 338 // ----------------------------------------------------------------------------- | 346 // ----------------------------------------------------------------------------- |
| 347 // Add and subtract instructions with overflow. | |
| 348 | |
| 349 | |
| 350 typedef InstructionSelectorTestWithParam<MachInst2> | |
| 351 InstructionSelectorOvfAddSubTest; | |
| 352 | |
| 353 | |
| 354 TEST_P(InstructionSelectorOvfAddSubTest, OvfParameter) { | |
| 355 const MachInst2 dpi = GetParam(); | |
| 356 const MachineType type = dpi.machine_type; | |
| 357 StreamBuilder m(this, type, type, type); | |
| 358 m.Return( | |
| 359 m.Projection(1, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)))); | |
| 360 Stream s = m.Build(); | |
| 361 ASSERT_EQ(1U, s.size()); | |
| 362 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 363 EXPECT_EQ(2U, s[0]->InputCount()); | |
| 364 EXPECT_LE(1U, s[0]->OutputCount()); | |
| 365 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | |
| 366 EXPECT_EQ(kOverflow, s[0]->flags_condition()); | |
| 367 } | |
| 368 | |
| 369 | |
| 370 TEST_P(InstructionSelectorOvfAddSubTest, OvfImmediateOnRight) { | |
| 371 const MachInst2 dpi = GetParam(); | |
| 372 const MachineType type = dpi.machine_type; | |
| 373 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | |
| 374 StreamBuilder m(this, type, type); | |
| 375 m.Return(m.Projection( | |
| 376 1, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)))); | |
| 377 Stream s = m.Build(); | |
| 378 ASSERT_EQ(1U, s.size()); | |
| 379 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 380 ASSERT_EQ(2U, s[0]->InputCount()); | |
| 381 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | |
| 382 EXPECT_LE(1U, s[0]->OutputCount()); | |
| 383 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | |
| 384 EXPECT_EQ(kOverflow, s[0]->flags_condition()); | |
| 385 } | |
| 386 } | |
| 387 | |
| 388 | |
| 389 TEST_P(InstructionSelectorOvfAddSubTest, OvfImmediateOnLeft) { | |
| 390 const MachInst2 dpi = GetParam(); | |
| 391 const MachineType type = dpi.machine_type; | |
| 392 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | |
| 393 StreamBuilder m(this, type, type); | |
| 394 m.Return(m.Projection( | |
| 395 1, (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)))); | |
| 396 Stream s = m.Build(); | |
| 397 | |
| 398 // Add can support an immediate on the left by commuting, but Sub can't | |
| 399 // commute. | |
| 400 if (strstr(dpi.constructor_name, "Add") != NULL) { | |
|
Benedikt Meurer
2014/09/05 10:31:25
Hm, that looks rather fragile to me. Can we limit
m.m.capewell
2014/09/05 10:38:34
Sure, I'll replace these cases with TEST_F.
m.m.capewell
2014/09/05 14:26:52
Done.
| |
| 401 ASSERT_EQ(1U, s.size()); | |
| 402 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 403 ASSERT_EQ(2U, s[0]->InputCount()); | |
| 404 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | |
| 405 EXPECT_LE(1U, s[0]->OutputCount()); | |
| 406 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | |
| 407 EXPECT_EQ(kOverflow, s[0]->flags_condition()); | |
| 408 } | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 | |
| 413 TEST_P(InstructionSelectorOvfAddSubTest, ValParameter) { | |
| 414 const MachInst2 dpi = GetParam(); | |
| 415 const MachineType type = dpi.machine_type; | |
| 416 StreamBuilder m(this, type, type, type); | |
| 417 m.Return( | |
| 418 m.Projection(0, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)))); | |
| 419 Stream s = m.Build(); | |
| 420 ASSERT_EQ(1U, s.size()); | |
| 421 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 422 EXPECT_EQ(2U, s[0]->InputCount()); | |
| 423 EXPECT_LE(1U, s[0]->OutputCount()); | |
| 424 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | |
| 425 } | |
| 426 | |
| 427 | |
| 428 TEST_P(InstructionSelectorOvfAddSubTest, ValImmediateOnRight) { | |
| 429 const MachInst2 dpi = GetParam(); | |
| 430 const MachineType type = dpi.machine_type; | |
| 431 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | |
| 432 StreamBuilder m(this, type, type); | |
| 433 m.Return(m.Projection( | |
| 434 0, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)))); | |
| 435 Stream s = m.Build(); | |
| 436 ASSERT_EQ(1U, s.size()); | |
| 437 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 438 ASSERT_EQ(2U, s[0]->InputCount()); | |
| 439 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | |
| 440 EXPECT_LE(1U, s[0]->OutputCount()); | |
| 441 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | |
| 442 } | |
| 443 } | |
| 444 | |
| 445 | |
| 446 TEST_P(InstructionSelectorOvfAddSubTest, ValImmediateOnLeft) { | |
| 447 const MachInst2 dpi = GetParam(); | |
| 448 const MachineType type = dpi.machine_type; | |
| 449 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | |
| 450 StreamBuilder m(this, type, type); | |
| 451 m.Return(m.Projection( | |
| 452 0, (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)))); | |
| 453 Stream s = m.Build(); | |
| 454 | |
| 455 // Add can support an immediate on the left by commuting, but Sub can't | |
| 456 // commute. | |
| 457 if (strstr(dpi.constructor_name, "Add") != NULL) { | |
|
Benedikt Meurer
2014/09/05 10:31:25
Hm, that looks rather fragile to me. Can we limit
m.m.capewell
2014/09/05 14:26:52
Done.
| |
| 458 ASSERT_EQ(1U, s.size()); | |
| 459 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 460 ASSERT_EQ(2U, s[0]->InputCount()); | |
| 461 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | |
| 462 EXPECT_LE(1U, s[0]->OutputCount()); | |
| 463 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | |
| 464 } | |
| 465 } | |
| 466 } | |
| 467 | |
| 468 | |
| 469 TEST_P(InstructionSelectorOvfAddSubTest, BothParameter) { | |
| 470 const MachInst2 dpi = GetParam(); | |
| 471 const MachineType type = dpi.machine_type; | |
| 472 StreamBuilder m(this, type, type, type); | |
| 473 Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)); | |
| 474 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); | |
| 475 Stream s = m.Build(); | |
| 476 ASSERT_LE(1U, s.size()); | |
| 477 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 478 EXPECT_EQ(2U, s[0]->InputCount()); | |
| 479 EXPECT_EQ(2U, s[0]->OutputCount()); | |
| 480 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | |
| 481 EXPECT_EQ(kOverflow, s[0]->flags_condition()); | |
| 482 } | |
| 483 | |
| 484 | |
| 485 TEST_P(InstructionSelectorOvfAddSubTest, BothImmediateOnRight) { | |
| 486 const MachInst2 dpi = GetParam(); | |
| 487 const MachineType type = dpi.machine_type; | |
| 488 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | |
| 489 StreamBuilder m(this, type, type); | |
| 490 Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)); | |
| 491 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); | |
| 492 Stream s = m.Build(); | |
| 493 ASSERT_LE(1U, s.size()); | |
| 494 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 495 ASSERT_EQ(2U, s[0]->InputCount()); | |
| 496 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | |
| 497 EXPECT_EQ(2U, s[0]->OutputCount()); | |
| 498 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | |
| 499 EXPECT_EQ(kOverflow, s[0]->flags_condition()); | |
| 500 } | |
| 501 } | |
| 502 | |
| 503 | |
| 504 TEST_P(InstructionSelectorOvfAddSubTest, BothImmediateOnLeft) { | |
| 505 const MachInst2 dpi = GetParam(); | |
| 506 const MachineType type = dpi.machine_type; | |
| 507 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | |
| 508 StreamBuilder m(this, type, type); | |
| 509 Node* n = (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)); | |
| 510 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); | |
| 511 Stream s = m.Build(); | |
| 512 | |
| 513 // Add can support an immediate on the left by commuting, but Sub can't | |
| 514 // commute. | |
| 515 if (strstr(dpi.constructor_name, "Add") != NULL) { | |
|
Benedikt Meurer
2014/09/05 10:31:25
Hm, that looks rather fragile to me. Can we limit
m.m.capewell
2014/09/05 14:26:52
Done.
| |
| 516 ASSERT_LE(1U, s.size()); | |
| 517 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | |
| 518 ASSERT_EQ(2U, s[0]->InputCount()); | |
| 519 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | |
| 520 EXPECT_EQ(2U, s[0]->OutputCount()); | |
| 521 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | |
| 522 EXPECT_EQ(kOverflow, s[0]->flags_condition()); | |
| 523 } | |
| 524 } | |
| 525 } | |
| 526 | |
| 527 | |
| 528 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | |
| 529 InstructionSelectorOvfAddSubTest, | |
| 530 ::testing::ValuesIn(kOvfAddSubInstructions)); | |
| 531 | |
| 532 | |
| 533 // ----------------------------------------------------------------------------- | |
| 339 // Shift instructions. | 534 // Shift instructions. |
| 340 | 535 |
| 341 | 536 |
| 342 typedef InstructionSelectorTestWithParam<MachInst2> | 537 typedef InstructionSelectorTestWithParam<MachInst2> |
| 343 InstructionSelectorShiftTest; | 538 InstructionSelectorShiftTest; |
| 344 | 539 |
| 345 | 540 |
| 346 TEST_P(InstructionSelectorShiftTest, Parameter) { | 541 TEST_P(InstructionSelectorShiftTest, Parameter) { |
| 347 const MachInst2 dpi = GetParam(); | 542 const MachInst2 dpi = GetParam(); |
| 348 const MachineType type = dpi.machine_type; | 543 const MachineType type = dpi.machine_type; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 535 } | 730 } |
| 536 | 731 |
| 537 | 732 |
| 538 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 733 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 539 InstructionSelectorMemoryAccessTest, | 734 InstructionSelectorMemoryAccessTest, |
| 540 ::testing::ValuesIn(kMemoryAccesses)); | 735 ::testing::ValuesIn(kMemoryAccesses)); |
| 541 | 736 |
| 542 } // namespace compiler | 737 } // namespace compiler |
| 543 } // namespace internal | 738 } // namespace internal |
| 544 } // namespace v8 | 739 } // namespace v8 |
| OLD | NEW |