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, ValParameter) { |
| 390 const MachInst2 dpi = GetParam(); |
| 391 const MachineType type = dpi.machine_type; |
| 392 StreamBuilder m(this, type, type, type); |
| 393 m.Return( |
| 394 m.Projection(0, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)))); |
| 395 Stream s = m.Build(); |
| 396 ASSERT_EQ(1U, s.size()); |
| 397 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 398 EXPECT_EQ(2U, s[0]->InputCount()); |
| 399 EXPECT_LE(1U, s[0]->OutputCount()); |
| 400 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 401 } |
| 402 |
| 403 |
| 404 TEST_P(InstructionSelectorOvfAddSubTest, ValImmediateOnRight) { |
| 405 const MachInst2 dpi = GetParam(); |
| 406 const MachineType type = dpi.machine_type; |
| 407 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 408 StreamBuilder m(this, type, type); |
| 409 m.Return(m.Projection( |
| 410 0, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)))); |
| 411 Stream s = m.Build(); |
| 412 ASSERT_EQ(1U, s.size()); |
| 413 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 414 ASSERT_EQ(2U, s[0]->InputCount()); |
| 415 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 416 EXPECT_LE(1U, s[0]->OutputCount()); |
| 417 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 418 } |
| 419 } |
| 420 |
| 421 |
| 422 TEST_P(InstructionSelectorOvfAddSubTest, BothParameter) { |
| 423 const MachInst2 dpi = GetParam(); |
| 424 const MachineType type = dpi.machine_type; |
| 425 StreamBuilder m(this, type, type, type); |
| 426 Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)); |
| 427 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); |
| 428 Stream s = m.Build(); |
| 429 ASSERT_LE(1U, s.size()); |
| 430 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 431 EXPECT_EQ(2U, s[0]->InputCount()); |
| 432 EXPECT_EQ(2U, s[0]->OutputCount()); |
| 433 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 434 EXPECT_EQ(kOverflow, s[0]->flags_condition()); |
| 435 } |
| 436 |
| 437 |
| 438 TEST_P(InstructionSelectorOvfAddSubTest, BothImmediateOnRight) { |
| 439 const MachInst2 dpi = GetParam(); |
| 440 const MachineType type = dpi.machine_type; |
| 441 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 442 StreamBuilder m(this, type, type); |
| 443 Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)); |
| 444 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); |
| 445 Stream s = m.Build(); |
| 446 ASSERT_LE(1U, s.size()); |
| 447 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
| 448 ASSERT_EQ(2U, s[0]->InputCount()); |
| 449 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 450 EXPECT_EQ(2U, s[0]->OutputCount()); |
| 451 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 452 EXPECT_EQ(kOverflow, s[0]->flags_condition()); |
| 453 } |
| 454 } |
| 455 |
| 456 |
| 457 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 458 InstructionSelectorOvfAddSubTest, |
| 459 ::testing::ValuesIn(kOvfAddSubInstructions)); |
| 460 |
| 461 |
| 462 TEST_F(InstructionSelectorTest, OvfFlagAddImmediateOnLeft) { |
| 463 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 464 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 465 m.Return(m.Projection( |
| 466 1, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)))); |
| 467 Stream s = m.Build(); |
| 468 |
| 469 ASSERT_EQ(1U, s.size()); |
| 470 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 471 EXPECT_EQ(2U, s[0]->InputCount()); |
| 472 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 473 EXPECT_LE(1U, s[0]->OutputCount()); |
| 474 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 475 EXPECT_EQ(kOverflow, s[0]->flags_condition()); |
| 476 } |
| 477 } |
| 478 |
| 479 |
| 480 TEST_F(InstructionSelectorTest, OvfValAddImmediateOnLeft) { |
| 481 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 482 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 483 m.Return(m.Projection( |
| 484 0, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)))); |
| 485 Stream s = m.Build(); |
| 486 |
| 487 ASSERT_EQ(1U, s.size()); |
| 488 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 489 ASSERT_EQ(2U, s[0]->InputCount()); |
| 490 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 491 EXPECT_LE(1U, s[0]->OutputCount()); |
| 492 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
| 493 } |
| 494 } |
| 495 |
| 496 |
| 497 TEST_F(InstructionSelectorTest, OvfBothAddImmediateOnLeft) { |
| 498 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
| 499 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 500 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)); |
| 501 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); |
| 502 Stream s = m.Build(); |
| 503 |
| 504 ASSERT_LE(1U, s.size()); |
| 505 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); |
| 506 ASSERT_EQ(2U, s[0]->InputCount()); |
| 507 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
| 508 EXPECT_EQ(2U, s[0]->OutputCount()); |
| 509 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 510 EXPECT_EQ(kOverflow, s[0]->flags_condition()); |
| 511 } |
| 512 } |
| 513 |
| 514 |
| 515 // ----------------------------------------------------------------------------- |
339 // Shift instructions. | 516 // Shift instructions. |
340 | 517 |
341 | 518 |
342 typedef InstructionSelectorTestWithParam<MachInst2> | 519 typedef InstructionSelectorTestWithParam<MachInst2> |
343 InstructionSelectorShiftTest; | 520 InstructionSelectorShiftTest; |
344 | 521 |
345 | 522 |
346 TEST_P(InstructionSelectorShiftTest, Parameter) { | 523 TEST_P(InstructionSelectorShiftTest, Parameter) { |
347 const MachInst2 dpi = GetParam(); | 524 const MachInst2 dpi = GetParam(); |
348 const MachineType type = dpi.machine_type; | 525 const MachineType type = dpi.machine_type; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 } | 712 } |
536 | 713 |
537 | 714 |
538 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 715 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
539 InstructionSelectorMemoryAccessTest, | 716 InstructionSelectorMemoryAccessTest, |
540 ::testing::ValuesIn(kMemoryAccesses)); | 717 ::testing::ValuesIn(kMemoryAccesses)); |
541 | 718 |
542 } // namespace compiler | 719 } // namespace compiler |
543 } // namespace internal | 720 } // namespace internal |
544 } // namespace v8 | 721 } // namespace v8 |
OLD | NEW |