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 "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 Mips64OperandGenerator g(this); | 415 Mips64OperandGenerator g(this); |
416 Emit(kMips64Nor, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 416 Emit(kMips64Nor, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
417 g.TempImmediate(0)); | 417 g.TempImmediate(0)); |
418 return; | 418 return; |
419 } | 419 } |
420 VisitBinop(this, node, kMips64Xor); | 420 VisitBinop(this, node, kMips64Xor); |
421 } | 421 } |
422 | 422 |
423 | 423 |
424 void InstructionSelector::VisitWord32Shl(Node* node) { | 424 void InstructionSelector::VisitWord32Shl(Node* node) { |
| 425 Int32BinopMatcher m(node); |
| 426 if (m.left().IsWord32And() && CanCover(node, m.left().node()) && |
| 427 m.right().IsInRange(1, 31)) { |
| 428 Mips64OperandGenerator g(this); |
| 429 Int32BinopMatcher mleft(m.left().node()); |
| 430 // Match Word32Shl(Word32And(x, mask), imm) to Shl where the mask is |
| 431 // contiguous, and the shift immediate non-zero. |
| 432 if (mleft.right().HasValue()) { |
| 433 uint32_t mask = mleft.right().Value(); |
| 434 uint32_t mask_width = base::bits::CountPopulation32(mask); |
| 435 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask); |
| 436 if ((mask_width != 0) && (mask_msb + mask_width == 32)) { |
| 437 uint32_t shift = m.right().Value(); |
| 438 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask)); |
| 439 DCHECK_NE(0u, shift); |
| 440 if ((shift + mask_width) >= 32) { |
| 441 // If the mask is contiguous and reaches or extends beyond the top |
| 442 // bit, only the shift is needed. |
| 443 Emit(kMips64Shl, g.DefineAsRegister(node), |
| 444 g.UseRegister(mleft.left().node()), |
| 445 g.UseImmediate(m.right().node())); |
| 446 return; |
| 447 } |
| 448 } |
| 449 } |
| 450 } |
425 VisitRRO(this, kMips64Shl, node); | 451 VisitRRO(this, kMips64Shl, node); |
426 } | 452 } |
427 | 453 |
428 | 454 |
429 void InstructionSelector::VisitWord32Shr(Node* node) { | 455 void InstructionSelector::VisitWord32Shr(Node* node) { |
430 Int32BinopMatcher m(node); | 456 Int32BinopMatcher m(node); |
431 if (m.left().IsWord32And() && m.right().HasValue()) { | 457 if (m.left().IsWord32And() && m.right().HasValue()) { |
432 uint32_t lsb = m.right().Value() & 0x1f; | 458 uint32_t lsb = m.right().Value() & 0x1f; |
433 Int32BinopMatcher mleft(m.left().node()); | 459 Int32BinopMatcher mleft(m.left().node()); |
434 if (mleft.right().HasValue()) { | 460 if (mleft.right().HasValue()) { |
(...skipping 26 matching lines...) Expand all Loading... |
461 Int64BinopMatcher m(node); | 487 Int64BinopMatcher m(node); |
462 if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) && | 488 if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) && |
463 m.right().IsInRange(32, 63)) { | 489 m.right().IsInRange(32, 63)) { |
464 // There's no need to sign/zero-extend to 64-bit if we shift out the upper | 490 // There's no need to sign/zero-extend to 64-bit if we shift out the upper |
465 // 32 bits anyway. | 491 // 32 bits anyway. |
466 Emit(kMips64Dshl, g.DefineSameAsFirst(node), | 492 Emit(kMips64Dshl, g.DefineSameAsFirst(node), |
467 g.UseRegister(m.left().node()->InputAt(0)), | 493 g.UseRegister(m.left().node()->InputAt(0)), |
468 g.UseImmediate(m.right().node())); | 494 g.UseImmediate(m.right().node())); |
469 return; | 495 return; |
470 } | 496 } |
| 497 if (m.left().IsWord64And() && CanCover(node, m.left().node()) && |
| 498 m.right().IsInRange(1, 63)) { |
| 499 // Match Word64Shl(Word64And(x, mask), imm) to Dshl where the mask is |
| 500 // contiguous, and the shift immediate non-zero. |
| 501 Int64BinopMatcher mleft(m.left().node()); |
| 502 if (mleft.right().HasValue()) { |
| 503 uint64_t mask = mleft.right().Value(); |
| 504 uint32_t mask_width = base::bits::CountPopulation64(mask); |
| 505 uint32_t mask_msb = base::bits::CountLeadingZeros64(mask); |
| 506 if ((mask_width != 0) && (mask_msb + mask_width == 64)) { |
| 507 uint64_t shift = m.right().Value(); |
| 508 DCHECK_EQ(0u, base::bits::CountTrailingZeros64(mask)); |
| 509 DCHECK_NE(0u, shift); |
| 510 |
| 511 if ((shift + mask_width) >= 64) { |
| 512 // If the mask is contiguous and reaches or extends beyond the top |
| 513 // bit, only the shift is needed. |
| 514 Emit(kMips64Dshl, g.DefineAsRegister(node), |
| 515 g.UseRegister(mleft.left().node()), |
| 516 g.UseImmediate(m.right().node())); |
| 517 return; |
| 518 } |
| 519 } |
| 520 } |
| 521 } |
471 VisitRRO(this, kMips64Dshl, node); | 522 VisitRRO(this, kMips64Dshl, node); |
472 } | 523 } |
473 | 524 |
474 | 525 |
475 void InstructionSelector::VisitWord64Shr(Node* node) { | 526 void InstructionSelector::VisitWord64Shr(Node* node) { |
476 Int64BinopMatcher m(node); | 527 Int64BinopMatcher m(node); |
477 if (m.left().IsWord64And() && m.right().HasValue()) { | 528 if (m.left().IsWord64And() && m.right().HasValue()) { |
478 uint32_t lsb = m.right().Value() & 0x3f; | 529 uint32_t lsb = m.right().Value() & 0x3f; |
479 Int64BinopMatcher mleft(m.left().node()); | 530 Int64BinopMatcher mleft(m.left().node()); |
480 if (mleft.right().HasValue()) { | 531 if (mleft.right().HasValue()) { |
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1663 MachineOperatorBuilder::kFloat32RoundUp | | 1714 MachineOperatorBuilder::kFloat32RoundUp | |
1664 MachineOperatorBuilder::kFloat64RoundTruncate | | 1715 MachineOperatorBuilder::kFloat64RoundTruncate | |
1665 MachineOperatorBuilder::kFloat32RoundTruncate | | 1716 MachineOperatorBuilder::kFloat32RoundTruncate | |
1666 MachineOperatorBuilder::kFloat64RoundTiesEven | | 1717 MachineOperatorBuilder::kFloat64RoundTiesEven | |
1667 MachineOperatorBuilder::kFloat32RoundTiesEven; | 1718 MachineOperatorBuilder::kFloat32RoundTiesEven; |
1668 } | 1719 } |
1669 | 1720 |
1670 } // namespace compiler | 1721 } // namespace compiler |
1671 } // namespace internal | 1722 } // namespace internal |
1672 } // namespace v8 | 1723 } // namespace v8 |
OLD | NEW |