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 "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
6 | 6 |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
11 namespace compiler { | 11 namespace compiler { |
12 | 12 |
| 13 namespace { |
| 14 |
| 15 // Immediates (random subset). |
| 16 static const int32_t kImmediates[] = { |
| 17 kMinInt, -42, -1, 0, 1, 2, 3, 4, 5, |
| 18 6, 7, 8, 16, 42, 0xff, 0xffff, 0x0f0f0f0f, kMaxInt}; |
| 19 |
| 20 } // namespace |
| 21 |
| 22 |
13 // ----------------------------------------------------------------------------- | 23 // ----------------------------------------------------------------------------- |
14 // Conversions. | 24 // Conversions. |
15 | 25 |
16 | 26 |
17 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) { | 27 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) { |
18 StreamBuilder m(this, kMachFloat32, kMachFloat64); | 28 StreamBuilder m(this, kMachFloat32, kMachFloat64); |
19 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0))); | 29 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0))); |
20 Stream s = m.Build(); | 30 Stream s = m.Build(); |
21 ASSERT_EQ(1U, s.size()); | 31 ASSERT_EQ(1U, s.size()); |
22 EXPECT_EQ(kSSECvtss2sd, s[0]->arch_opcode()); | 32 EXPECT_EQ(kSSECvtss2sd, s[0]->arch_opcode()); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 {11, false, kMode_None}}; | 340 {11, false, kMode_None}}; |
331 | 341 |
332 } // namespace | 342 } // namespace |
333 | 343 |
334 | 344 |
335 typedef InstructionSelectorTestWithParam<MultParam> InstructionSelectorMultTest; | 345 typedef InstructionSelectorTestWithParam<MultParam> InstructionSelectorMultTest; |
336 | 346 |
337 | 347 |
338 static unsigned InputCountForLea(AddressingMode mode) { | 348 static unsigned InputCountForLea(AddressingMode mode) { |
339 switch (mode) { | 349 switch (mode) { |
| 350 case kMode_MR1I: |
| 351 case kMode_MR2I: |
| 352 case kMode_MR4I: |
| 353 case kMode_MR8I: |
| 354 return 3U; |
| 355 case kMode_M1I: |
| 356 case kMode_M2I: |
| 357 case kMode_M4I: |
| 358 case kMode_M8I: |
| 359 return 2U; |
340 case kMode_MR1: | 360 case kMode_MR1: |
341 case kMode_MR2: | 361 case kMode_MR2: |
342 case kMode_MR4: | 362 case kMode_MR4: |
343 case kMode_MR8: | 363 case kMode_MR8: |
344 return 2U; | 364 return 2U; |
345 case kMode_M1: | 365 case kMode_M1: |
346 case kMode_M2: | 366 case kMode_M2: |
347 case kMode_M4: | 367 case kMode_M4: |
348 case kMode_M8: | 368 case kMode_M8: |
349 return 1U; | 369 return 1U; |
350 default: | 370 default: |
351 UNREACHABLE(); | 371 UNREACHABLE(); |
352 return 0U; | 372 return 0U; |
353 } | 373 } |
354 } | 374 } |
355 | 375 |
356 | 376 |
| 377 static AddressingMode AddressingModeForAddMult(const MultParam& m) { |
| 378 switch (m.addressing_mode) { |
| 379 case kMode_MR1: |
| 380 return kMode_MR1I; |
| 381 case kMode_MR2: |
| 382 return kMode_MR2I; |
| 383 case kMode_MR4: |
| 384 return kMode_MR4I; |
| 385 case kMode_MR8: |
| 386 return kMode_MR8I; |
| 387 case kMode_M1: |
| 388 return kMode_M1I; |
| 389 case kMode_M2: |
| 390 return kMode_M2I; |
| 391 case kMode_M4: |
| 392 return kMode_M4I; |
| 393 case kMode_M8: |
| 394 return kMode_M8I; |
| 395 default: |
| 396 UNREACHABLE(); |
| 397 return kMode_None; |
| 398 } |
| 399 } |
| 400 |
| 401 |
357 TEST_P(InstructionSelectorMultTest, Mult32) { | 402 TEST_P(InstructionSelectorMultTest, Mult32) { |
358 const MultParam m_param = GetParam(); | 403 const MultParam m_param = GetParam(); |
359 StreamBuilder m(this, kMachInt32, kMachInt32); | 404 StreamBuilder m(this, kMachInt32, kMachInt32); |
360 Node* param = m.Parameter(0); | 405 Node* param = m.Parameter(0); |
361 Node* mult = m.Int32Mul(param, m.Int32Constant(m_param.value)); | 406 Node* mult = m.Int32Mul(param, m.Int32Constant(m_param.value)); |
362 m.Return(mult); | 407 m.Return(mult); |
363 Stream s = m.Build(); | 408 Stream s = m.Build(); |
364 ASSERT_EQ(1U, s.size()); | 409 ASSERT_EQ(1U, s.size()); |
365 EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode()); | 410 EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode()); |
366 if (m_param.lea_expected) { | 411 if (m_param.lea_expected) { |
(...skipping 22 matching lines...) Expand all Loading... |
389 EXPECT_EQ(param->id(), s.ToVreg(s[0]->InputAt(0))); | 434 EXPECT_EQ(param->id(), s.ToVreg(s[0]->InputAt(0))); |
390 } else { | 435 } else { |
391 EXPECT_EQ(kX64Imul, s[0]->arch_opcode()); | 436 EXPECT_EQ(kX64Imul, s[0]->arch_opcode()); |
392 ASSERT_EQ(2U, s[0]->InputCount()); | 437 ASSERT_EQ(2U, s[0]->InputCount()); |
393 // TODO(dcarney): why is this happening? | 438 // TODO(dcarney): why is this happening? |
394 EXPECT_EQ(param->id(), s.ToVreg(s[0]->InputAt(1))); | 439 EXPECT_EQ(param->id(), s.ToVreg(s[0]->InputAt(1))); |
395 } | 440 } |
396 } | 441 } |
397 | 442 |
398 | 443 |
| 444 TEST_P(InstructionSelectorMultTest, MultAdd32) { |
| 445 TRACED_FOREACH(int32_t, imm, kImmediates) { |
| 446 const MultParam m_param = GetParam(); |
| 447 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 448 Node* param = m.Parameter(0); |
| 449 Node* mult = m.Int32Add(m.Int32Mul(param, m.Int32Constant(m_param.value)), |
| 450 m.Int32Constant(imm)); |
| 451 m.Return(mult); |
| 452 Stream s = m.Build(); |
| 453 if (m_param.lea_expected) { |
| 454 ASSERT_EQ(1U, s.size()); |
| 455 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode()); |
| 456 EXPECT_EQ(AddressingModeForAddMult(m_param), s[0]->addressing_mode()); |
| 457 unsigned input_count = InputCountForLea(s[0]->addressing_mode()); |
| 458 ASSERT_EQ(input_count, s[0]->InputCount()); |
| 459 ASSERT_EQ(InstructionOperand::IMMEDIATE, |
| 460 s[0]->InputAt(input_count - 1)->kind()); |
| 461 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(input_count - 1))); |
| 462 } else { |
| 463 ASSERT_EQ(2U, s.size()); |
| 464 EXPECT_EQ(kX64Imul32, s[0]->arch_opcode()); |
| 465 EXPECT_EQ(kX64Add32, s[1]->arch_opcode()); |
| 466 } |
| 467 } |
| 468 } |
| 469 |
| 470 |
| 471 TEST_P(InstructionSelectorMultTest, MultAdd64) { |
| 472 TRACED_FOREACH(int32_t, imm, kImmediates) { |
| 473 const MultParam m_param = GetParam(); |
| 474 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 475 Node* param = m.Parameter(0); |
| 476 Node* mult = m.Int64Add(m.Int64Mul(param, m.Int64Constant(m_param.value)), |
| 477 m.Int64Constant(imm)); |
| 478 m.Return(mult); |
| 479 Stream s = m.Build(); |
| 480 if (m_param.lea_expected) { |
| 481 ASSERT_EQ(1U, s.size()); |
| 482 EXPECT_EQ(kX64Lea, s[0]->arch_opcode()); |
| 483 EXPECT_EQ(AddressingModeForAddMult(m_param), s[0]->addressing_mode()); |
| 484 unsigned input_count = InputCountForLea(s[0]->addressing_mode()); |
| 485 ASSERT_EQ(input_count, s[0]->InputCount()); |
| 486 ASSERT_EQ(InstructionOperand::IMMEDIATE, |
| 487 s[0]->InputAt(input_count - 1)->kind()); |
| 488 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(input_count - 1))); |
| 489 } else { |
| 490 ASSERT_EQ(2U, s.size()); |
| 491 EXPECT_EQ(kX64Imul, s[0]->arch_opcode()); |
| 492 EXPECT_EQ(kX64Add, s[1]->arch_opcode()); |
| 493 } |
| 494 } |
| 495 } |
| 496 |
| 497 |
399 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMultTest, | 498 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMultTest, |
400 ::testing::ValuesIn(kMultParams)); | 499 ::testing::ValuesIn(kMultParams)); |
401 | 500 |
402 } // namespace compiler | 501 } // namespace compiler |
403 } // namespace internal | 502 } // namespace internal |
404 } // namespace v8 | 503 } // namespace v8 |
OLD | NEW |