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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 289 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
290 EXPECT_EQ(1U, s[0]->OutputCount()); | 290 EXPECT_EQ(1U, s[0]->OutputCount()); |
291 } | 291 } |
292 } | 292 } |
293 | 293 |
294 | 294 |
295 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, | 295 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, |
296 ::testing::ValuesIn(kShiftInstructions)); | 296 ::testing::ValuesIn(kShiftInstructions)); |
297 | 297 |
298 | 298 |
| 299 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) { |
| 300 // The available shift operand range is `0 <= imm < 32`, but we also test |
| 301 // that immediates outside this range are handled properly (modulo-32). |
| 302 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 303 int32_t lsb = shift & 0x1f; |
| 304 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
| 305 uint32_t jnk = rng()->NextInt(); |
| 306 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; |
| 307 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; |
| 308 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 309 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)), |
| 310 m.Int32Constant(shift))); |
| 311 Stream s = m.Build(); |
| 312 ASSERT_EQ(1U, s.size()); |
| 313 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); |
| 314 ASSERT_EQ(3U, s[0]->InputCount()); |
| 315 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 316 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 317 } |
| 318 } |
| 319 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 320 int32_t lsb = shift & 0x1f; |
| 321 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
| 322 uint32_t jnk = rng()->NextInt(); |
| 323 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; |
| 324 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; |
| 325 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 326 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)), |
| 327 m.Int32Constant(shift))); |
| 328 Stream s = m.Build(); |
| 329 ASSERT_EQ(1U, s.size()); |
| 330 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); |
| 331 ASSERT_EQ(3U, s[0]->InputCount()); |
| 332 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 333 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
| 334 } |
| 335 } |
| 336 } |
| 337 |
| 338 |
299 // ---------------------------------------------------------------------------- | 339 // ---------------------------------------------------------------------------- |
300 // Logical instructions. | 340 // Logical instructions. |
301 // ---------------------------------------------------------------------------- | 341 // ---------------------------------------------------------------------------- |
302 | 342 |
303 | 343 |
304 typedef InstructionSelectorTestWithParam<MachInst2> | 344 typedef InstructionSelectorTestWithParam<MachInst2> |
305 InstructionSelectorLogicalTest; | 345 InstructionSelectorLogicalTest; |
306 | 346 |
307 | 347 |
308 TEST_P(InstructionSelectorLogicalTest, Parameter) { | 348 TEST_P(InstructionSelectorLogicalTest, Parameter) { |
309 const MachInst2 dpi = GetParam(); | 349 const MachInst2 dpi = GetParam(); |
310 const MachineType type = dpi.machine_type; | 350 const MachineType type = dpi.machine_type; |
311 StreamBuilder m(this, type, type, type); | 351 StreamBuilder m(this, type, type, type); |
312 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 352 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
313 Stream s = m.Build(); | 353 Stream s = m.Build(); |
314 ASSERT_EQ(1U, s.size()); | 354 ASSERT_EQ(1U, s.size()); |
315 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 355 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
316 EXPECT_EQ(2U, s[0]->InputCount()); | 356 EXPECT_EQ(2U, s[0]->InputCount()); |
317 EXPECT_EQ(1U, s[0]->OutputCount()); | 357 EXPECT_EQ(1U, s[0]->OutputCount()); |
318 } | 358 } |
319 | 359 |
320 | 360 |
321 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, | 361 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, |
322 ::testing::ValuesIn(kLogicalInstructions)); | 362 ::testing::ValuesIn(kLogicalInstructions)); |
323 | 363 |
324 | 364 |
| 365 TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { |
| 366 // The available shift operand range is `0 <= imm < 32`, but we also test |
| 367 // that immediates outside this range are handled properly (modulo-32). |
| 368 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 369 int32_t lsb = shift & 0x1f; |
| 370 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 371 uint32_t msk = (1 << width) - 1; |
| 372 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 373 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), |
| 374 m.Int32Constant(msk))); |
| 375 Stream s = m.Build(); |
| 376 ASSERT_EQ(1U, s.size()); |
| 377 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); |
| 378 ASSERT_EQ(3U, s[0]->InputCount()); |
| 379 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 380 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; |
| 381 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); |
| 382 } |
| 383 } |
| 384 TRACED_FORRANGE(int32_t, shift, -32, 63) { |
| 385 int32_t lsb = shift & 0x1f; |
| 386 TRACED_FORRANGE(int32_t, width, 1, 31) { |
| 387 uint32_t msk = (1 << width) - 1; |
| 388 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 389 m.Return( |
| 390 m.Word32And(m.Int32Constant(msk), |
| 391 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); |
| 392 Stream s = m.Build(); |
| 393 ASSERT_EQ(1U, s.size()); |
| 394 EXPECT_EQ(kMipsExt, s[0]->arch_opcode()); |
| 395 ASSERT_EQ(3U, s[0]->InputCount()); |
| 396 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
| 397 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; |
| 398 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); |
| 399 } |
| 400 } |
| 401 } |
| 402 |
| 403 |
325 // ---------------------------------------------------------------------------- | 404 // ---------------------------------------------------------------------------- |
326 // MUL/DIV instructions. | 405 // MUL/DIV instructions. |
327 // ---------------------------------------------------------------------------- | 406 // ---------------------------------------------------------------------------- |
328 | 407 |
329 | 408 |
330 typedef InstructionSelectorTestWithParam<MachInst2> | 409 typedef InstructionSelectorTestWithParam<MachInst2> |
331 InstructionSelectorMulDivTest; | 410 InstructionSelectorMulDivTest; |
332 | 411 |
333 | 412 |
334 TEST_P(InstructionSelectorMulDivTest, Parameter) { | 413 TEST_P(InstructionSelectorMulDivTest, Parameter) { |
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 EXPECT_EQ(kMipsFloat64Min, s[0]->arch_opcode()); | 985 EXPECT_EQ(kMipsFloat64Min, s[0]->arch_opcode()); |
907 ASSERT_EQ(2U, s[0]->InputCount()); | 986 ASSERT_EQ(2U, s[0]->InputCount()); |
908 ASSERT_EQ(1U, s[0]->OutputCount()); | 987 ASSERT_EQ(1U, s[0]->OutputCount()); |
909 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 988 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
910 } | 989 } |
911 | 990 |
912 | 991 |
913 } // namespace compiler | 992 } // namespace compiler |
914 } // namespace internal | 993 } // namespace internal |
915 } // namespace v8 | 994 } // namespace v8 |
OLD | NEW |