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 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace compiler { | 9 namespace compiler { |
10 | 10 |
(...skipping 2337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2348 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), | 2348 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
2349 memacc.type); | 2349 memacc.type); |
2350 m.Store(memacc.type.representation(), m.Parameter(0), | 2350 m.Store(memacc.type.representation(), m.Parameter(0), |
2351 m.Int32Constant(index), m.Parameter(1), kNoWriteBarrier); | 2351 m.Int32Constant(index), m.Parameter(1), kNoWriteBarrier); |
2352 m.Return(m.Int32Constant(0)); | 2352 m.Return(m.Int32Constant(0)); |
2353 Stream s = m.Build(); | 2353 Stream s = m.Build(); |
2354 ASSERT_EQ(1U, s.size()); | 2354 ASSERT_EQ(1U, s.size()); |
2355 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); | 2355 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); |
2356 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 2356 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
2357 ASSERT_EQ(3U, s[0]->InputCount()); | 2357 ASSERT_EQ(3U, s[0]->InputCount()); |
2358 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 2358 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(2)->kind()); |
2359 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | 2359 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(2))); |
2360 EXPECT_EQ(0U, s[0]->OutputCount()); | 2360 EXPECT_EQ(0U, s[0]->OutputCount()); |
2361 } | 2361 } |
2362 } | 2362 } |
2363 | 2363 |
2364 TEST_P(InstructionSelectorMemoryAccessTest, StoreZero) { | 2364 TEST_P(InstructionSelectorMemoryAccessTest, StoreZero) { |
2365 const MemoryAccess memacc = GetParam(); | 2365 const MemoryAccess memacc = GetParam(); |
2366 TRACED_FOREACH(int32_t, index, memacc.immediates) { | 2366 TRACED_FOREACH(int32_t, index, memacc.immediates) { |
2367 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer()); | 2367 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer()); |
2368 m.Store(memacc.type.representation(), m.Parameter(0), | 2368 m.Store(memacc.type.representation(), m.Parameter(0), |
2369 m.Int32Constant(index), m.Int32Constant(0), kNoWriteBarrier); | 2369 m.Int32Constant(index), m.Int32Constant(0), kNoWriteBarrier); |
2370 m.Return(m.Int32Constant(0)); | 2370 m.Return(m.Int32Constant(0)); |
2371 Stream s = m.Build(); | 2371 Stream s = m.Build(); |
2372 ASSERT_EQ(1U, s.size()); | 2372 ASSERT_EQ(1U, s.size()); |
2373 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); | 2373 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); |
2374 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); | 2374 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); |
2375 ASSERT_EQ(3U, s[0]->InputCount()); | 2375 ASSERT_EQ(3U, s[0]->InputCount()); |
2376 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | |
2377 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | |
2378 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(2)->kind()); | 2376 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(2)->kind()); |
2379 EXPECT_EQ(0, s.ToInt64(s[0]->InputAt(2))); | 2377 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(2))); |
| 2378 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(0)->kind()); |
| 2379 EXPECT_EQ(0, s.ToInt64(s[0]->InputAt(0))); |
2380 EXPECT_EQ(0U, s[0]->OutputCount()); | 2380 EXPECT_EQ(0U, s[0]->OutputCount()); |
2381 } | 2381 } |
2382 } | 2382 } |
2383 | 2383 |
| 2384 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithShiftedIndex) { |
| 2385 const MemoryAccess memacc = GetParam(); |
| 2386 TRACED_FORRANGE(int, immediate_shift, 0, 4) { |
| 2387 // 32 bit shift |
| 2388 { |
| 2389 StreamBuilder m(this, memacc.type, MachineType::Pointer(), |
| 2390 MachineType::Int32()); |
| 2391 Node* const index = |
| 2392 m.Word32Shl(m.Parameter(1), m.Int32Constant(immediate_shift)); |
| 2393 m.Return(m.Load(memacc.type, m.Parameter(0), index)); |
| 2394 Stream s = m.Build(); |
| 2395 if (immediate_shift == ElementSizeLog2Of(memacc.type.representation())) { |
| 2396 ASSERT_EQ(1U, s.size()); |
| 2397 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode()); |
| 2398 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 2399 EXPECT_EQ(3U, s[0]->InputCount()); |
| 2400 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2401 } else { |
| 2402 // Make sure we haven't merged the shift into the load instruction. |
| 2403 ASSERT_NE(1U, s.size()); |
| 2404 EXPECT_NE(memacc.ldr_opcode, s[0]->arch_opcode()); |
| 2405 EXPECT_NE(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 2406 } |
| 2407 } |
| 2408 // 64 bit shift |
| 2409 { |
| 2410 StreamBuilder m(this, memacc.type, MachineType::Pointer(), |
| 2411 MachineType::Int64()); |
| 2412 Node* const index = |
| 2413 m.Word64Shl(m.Parameter(1), m.Int64Constant(immediate_shift)); |
| 2414 m.Return(m.Load(memacc.type, m.Parameter(0), index)); |
| 2415 Stream s = m.Build(); |
| 2416 if (immediate_shift == ElementSizeLog2Of(memacc.type.representation())) { |
| 2417 ASSERT_EQ(1U, s.size()); |
| 2418 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode()); |
| 2419 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 2420 EXPECT_EQ(3U, s[0]->InputCount()); |
| 2421 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 2422 } else { |
| 2423 // Make sure we haven't merged the shift into the load instruction. |
| 2424 ASSERT_NE(1U, s.size()); |
| 2425 EXPECT_NE(memacc.ldr_opcode, s[0]->arch_opcode()); |
| 2426 EXPECT_NE(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 2427 } |
| 2428 } |
| 2429 } |
| 2430 } |
| 2431 |
| 2432 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithShiftedIndex) { |
| 2433 const MemoryAccess memacc = GetParam(); |
| 2434 TRACED_FORRANGE(int, immediate_shift, 0, 4) { |
| 2435 // 32 bit shift |
| 2436 { |
| 2437 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 2438 MachineType::Int32(), memacc.type); |
| 2439 Node* const index = |
| 2440 m.Word32Shl(m.Parameter(1), m.Int32Constant(immediate_shift)); |
| 2441 m.Store(memacc.type.representation(), m.Parameter(0), index, |
| 2442 m.Parameter(2), kNoWriteBarrier); |
| 2443 m.Return(m.Int32Constant(0)); |
| 2444 Stream s = m.Build(); |
| 2445 if (immediate_shift == ElementSizeLog2Of(memacc.type.representation())) { |
| 2446 ASSERT_EQ(1U, s.size()); |
| 2447 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); |
| 2448 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 2449 EXPECT_EQ(4U, s[0]->InputCount()); |
| 2450 EXPECT_EQ(0U, s[0]->OutputCount()); |
| 2451 } else { |
| 2452 // Make sure we haven't merged the shift into the store instruction. |
| 2453 ASSERT_NE(1U, s.size()); |
| 2454 EXPECT_NE(memacc.str_opcode, s[0]->arch_opcode()); |
| 2455 EXPECT_NE(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 2456 } |
| 2457 } |
| 2458 // 64 bit shift |
| 2459 { |
| 2460 StreamBuilder m(this, MachineType::Int64(), MachineType::Pointer(), |
| 2461 MachineType::Int64(), memacc.type); |
| 2462 Node* const index = |
| 2463 m.Word64Shl(m.Parameter(1), m.Int64Constant(immediate_shift)); |
| 2464 m.Store(memacc.type.representation(), m.Parameter(0), index, |
| 2465 m.Parameter(2), kNoWriteBarrier); |
| 2466 m.Return(m.Int64Constant(0)); |
| 2467 Stream s = m.Build(); |
| 2468 if (immediate_shift == ElementSizeLog2Of(memacc.type.representation())) { |
| 2469 ASSERT_EQ(1U, s.size()); |
| 2470 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); |
| 2471 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 2472 EXPECT_EQ(4U, s[0]->InputCount()); |
| 2473 EXPECT_EQ(0U, s[0]->OutputCount()); |
| 2474 } else { |
| 2475 // Make sure we haven't merged the shift into the store instruction. |
| 2476 ASSERT_NE(1U, s.size()); |
| 2477 EXPECT_NE(memacc.str_opcode, s[0]->arch_opcode()); |
| 2478 EXPECT_NE(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 2479 } |
| 2480 } |
| 2481 } |
| 2482 } |
| 2483 |
2384 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 2484 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
2385 InstructionSelectorMemoryAccessTest, | 2485 InstructionSelectorMemoryAccessTest, |
2386 ::testing::ValuesIn(kMemoryAccesses)); | 2486 ::testing::ValuesIn(kMemoryAccesses)); |
2387 | 2487 |
2388 | 2488 |
2389 // ----------------------------------------------------------------------------- | 2489 // ----------------------------------------------------------------------------- |
2390 // Comparison instructions. | 2490 // Comparison instructions. |
2391 | 2491 |
2392 static const MachInst2 kComparisonInstructions[] = { | 2492 static const MachInst2 kComparisonInstructions[] = { |
2393 {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, | 2493 {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, |
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3470 ASSERT_EQ(2U, s[0]->InputCount()); | 3570 ASSERT_EQ(2U, s[0]->InputCount()); |
3471 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3571 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
3472 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 3572 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
3473 ASSERT_EQ(1U, s[0]->OutputCount()); | 3573 ASSERT_EQ(1U, s[0]->OutputCount()); |
3474 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3574 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
3475 } | 3575 } |
3476 | 3576 |
3477 } // namespace compiler | 3577 } // namespace compiler |
3478 } // namespace internal | 3578 } // namespace internal |
3479 } // namespace v8 | 3579 } // namespace v8 |
OLD | NEW |