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/compiler/int64-lowering.h" | 5 #include "src/compiler/int64-lowering.h" |
6 #include "src/compiler/common-operator.h" | 6 #include "src/compiler/common-operator.h" |
7 #include "src/compiler/diamond.h" | 7 #include "src/compiler/diamond.h" |
8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
| 11 #include "src/compiler/node-matchers.h" |
11 #include "src/compiler/node-properties.h" | 12 #include "src/compiler/node-properties.h" |
12 | 13 |
13 #include "src/compiler/node.h" | 14 #include "src/compiler/node.h" |
14 #include "src/wasm/wasm-module.h" | 15 #include "src/wasm/wasm-module.h" |
15 #include "src/zone.h" | 16 #include "src/zone.h" |
16 | 17 |
17 namespace v8 { | 18 namespace v8 { |
18 namespace internal { | 19 namespace internal { |
19 namespace compiler { | 20 namespace compiler { |
20 | 21 |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 graph()->NewNode(common()->Int32Constant(4)), store, | 544 graph()->NewNode(common()->Int32Constant(4)), store, |
544 graph()->start()); | 545 graph()->start()); |
545 | 546 |
546 Node* low_node = | 547 Node* low_node = |
547 graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot, | 548 graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot, |
548 graph()->NewNode(common()->Int32Constant(0)), store, | 549 graph()->NewNode(common()->Int32Constant(0)), store, |
549 graph()->start()); | 550 graph()->start()); |
550 ReplaceNode(node, low_node, high_node); | 551 ReplaceNode(node, low_node, high_node); |
551 break; | 552 break; |
552 } | 553 } |
| 554 case IrOpcode::kWord64Ror: { |
| 555 DCHECK(node->InputCount() == 2); |
| 556 Node* input = node->InputAt(0); |
| 557 Node* shift = HasReplacementLow(node->InputAt(1)) |
| 558 ? GetReplacementLow(node->InputAt(1)) |
| 559 : node->InputAt(1); |
| 560 Int32Matcher m(shift); |
| 561 if (m.HasValue()) { |
| 562 // Precondition: 0 <= shift < 64. |
| 563 int32_t shift_value = m.Value() & 0x3f; |
| 564 if (shift_value == 0) { |
| 565 ReplaceNode(node, GetReplacementLow(input), |
| 566 GetReplacementHigh(input)); |
| 567 } else if (shift_value == 32) { |
| 568 ReplaceNode(node, GetReplacementHigh(input), |
| 569 GetReplacementLow(input)); |
| 570 } else { |
| 571 Node* low_input; |
| 572 Node* high_input; |
| 573 if (shift_value < 32) { |
| 574 low_input = GetReplacementLow(input); |
| 575 high_input = GetReplacementHigh(input); |
| 576 } else { |
| 577 low_input = GetReplacementHigh(input); |
| 578 high_input = GetReplacementLow(input); |
| 579 } |
| 580 int32_t masked_shift_value = shift_value & 0x1f; |
| 581 Node* masked_shift = |
| 582 graph()->NewNode(common()->Int32Constant(masked_shift_value)); |
| 583 Node* inv_shift = graph()->NewNode( |
| 584 common()->Int32Constant(32 - masked_shift_value)); |
| 585 |
| 586 Node* low_node = graph()->NewNode( |
| 587 machine()->Word32Or(), |
| 588 graph()->NewNode(machine()->Word32Shr(), low_input, masked_shift), |
| 589 graph()->NewNode(machine()->Word32Shl(), high_input, inv_shift)); |
| 590 Node* high_node = graph()->NewNode( |
| 591 machine()->Word32Or(), graph()->NewNode(machine()->Word32Shr(), |
| 592 high_input, masked_shift), |
| 593 graph()->NewNode(machine()->Word32Shl(), low_input, inv_shift)); |
| 594 ReplaceNode(node, low_node, high_node); |
| 595 } |
| 596 } else { |
| 597 Node* safe_shift = shift; |
| 598 if (!machine()->Word32ShiftIsSafe()) { |
| 599 safe_shift = |
| 600 graph()->NewNode(machine()->Word32And(), shift, |
| 601 graph()->NewNode(common()->Int32Constant(0x1f))); |
| 602 } |
| 603 |
| 604 // By creating this bit-mask with SAR and SHL we do not have to deal |
| 605 // with shift == 0 as a special case. |
| 606 Node* inv_mask = graph()->NewNode( |
| 607 machine()->Word32Shl(), |
| 608 graph()->NewNode(machine()->Word32Sar(), |
| 609 graph()->NewNode(common()->Int32Constant( |
| 610 std::numeric_limits<int32_t>::min())), |
| 611 safe_shift), |
| 612 graph()->NewNode(common()->Int32Constant(1))); |
| 613 |
| 614 Node* bit_mask = |
| 615 graph()->NewNode(machine()->Word32Xor(), inv_mask, |
| 616 graph()->NewNode(common()->Int32Constant(-1))); |
| 617 |
| 618 // We have to mask the shift value for this comparison. If |
| 619 // !machine()->Word32ShiftIsSafe() then the masking should already be |
| 620 // part of the graph. |
| 621 Node* masked_shift6 = shift; |
| 622 if (machine()->Word32ShiftIsSafe()) { |
| 623 masked_shift6 = |
| 624 graph()->NewNode(machine()->Word32And(), shift, |
| 625 graph()->NewNode(common()->Int32Constant(0x3f))); |
| 626 } |
| 627 |
| 628 Diamond lt32( |
| 629 graph(), common(), |
| 630 graph()->NewNode(machine()->Int32LessThan(), masked_shift6, |
| 631 graph()->NewNode(common()->Int32Constant(32)))); |
| 632 |
| 633 // The low word and the high word can be swapped either at the input or |
| 634 // at the output. We swap the inputs so that shift does not have to be |
| 635 // kept for so long in a register. |
| 636 Node* input_low = |
| 637 lt32.Phi(MachineRepresentation::kWord32, GetReplacementLow(input), |
| 638 GetReplacementHigh(input)); |
| 639 Node* input_high = |
| 640 lt32.Phi(MachineRepresentation::kWord32, GetReplacementHigh(input), |
| 641 GetReplacementLow(input)); |
| 642 |
| 643 Node* rotate_low = |
| 644 graph()->NewNode(machine()->Word32Ror(), input_low, safe_shift); |
| 645 Node* rotate_high = |
| 646 graph()->NewNode(machine()->Word32Ror(), input_high, safe_shift); |
| 647 |
| 648 Node* low_node = graph()->NewNode( |
| 649 machine()->Word32Or(), |
| 650 graph()->NewNode(machine()->Word32And(), rotate_low, bit_mask), |
| 651 graph()->NewNode(machine()->Word32And(), rotate_high, inv_mask)); |
| 652 |
| 653 Node* high_node = graph()->NewNode( |
| 654 machine()->Word32Or(), |
| 655 graph()->NewNode(machine()->Word32And(), rotate_high, bit_mask), |
| 656 graph()->NewNode(machine()->Word32And(), rotate_low, inv_mask)); |
| 657 |
| 658 ReplaceNode(node, low_node, high_node); |
| 659 } |
| 660 break; |
| 661 } |
553 // kExprI64Clz: | 662 // kExprI64Clz: |
554 case IrOpcode::kWord64Clz: { | 663 case IrOpcode::kWord64Clz: { |
555 DCHECK(node->InputCount() == 1); | 664 DCHECK(node->InputCount() == 1); |
556 Node* input = node->InputAt(0); | 665 Node* input = node->InputAt(0); |
557 Diamond d( | 666 Diamond d( |
558 graph(), common(), | 667 graph(), common(), |
559 graph()->NewNode(machine()->Word32Equal(), GetReplacementHigh(input), | 668 graph()->NewNode(machine()->Word32Equal(), GetReplacementHigh(input), |
560 graph()->NewNode(common()->Int32Constant(0)))); | 669 graph()->NewNode(common()->Int32Constant(0)))); |
561 | 670 |
562 Node* low_node = d.Phi( | 671 Node* low_node = d.Phi( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 high_node->ReplaceInput(i, GetReplacementHigh(node->InputAt(i))); | 726 high_node->ReplaceInput(i, GetReplacementHigh(node->InputAt(i))); |
618 } | 727 } |
619 } else { | 728 } else { |
620 DefaultLowering(node); | 729 DefaultLowering(node); |
621 } | 730 } |
622 break; | 731 break; |
623 } | 732 } |
624 | 733 |
625 default: { DefaultLowering(node); } | 734 default: { DefaultLowering(node); } |
626 } | 735 } |
627 } | 736 } // NOLINT(readability/fn_size) |
628 | 737 |
629 void Int64Lowering::LowerComparison(Node* node, const Operator* high_word_op, | 738 void Int64Lowering::LowerComparison(Node* node, const Operator* high_word_op, |
630 const Operator* low_word_op) { | 739 const Operator* low_word_op) { |
631 DCHECK(node->InputCount() == 2); | 740 DCHECK(node->InputCount() == 2); |
632 Node* left = node->InputAt(0); | 741 Node* left = node->InputAt(0); |
633 Node* right = node->InputAt(1); | 742 Node* right = node->InputAt(1); |
634 Node* replacement = graph()->NewNode( | 743 Node* replacement = graph()->NewNode( |
635 machine()->Word32Or(), | 744 machine()->Word32Or(), |
636 graph()->NewNode(high_word_op, GetReplacementHigh(left), | 745 graph()->NewNode(high_word_op, GetReplacementHigh(left), |
637 GetReplacementHigh(right)), | 746 GetReplacementHigh(right)), |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 common()->Phi(MachineRepresentation::kWord32, value_count), | 818 common()->Phi(MachineRepresentation::kWord32, value_count), |
710 value_count + 1, inputs_low, false), | 819 value_count + 1, inputs_low, false), |
711 graph()->NewNode( | 820 graph()->NewNode( |
712 common()->Phi(MachineRepresentation::kWord32, value_count), | 821 common()->Phi(MachineRepresentation::kWord32, value_count), |
713 value_count + 1, inputs_high, false)); | 822 value_count + 1, inputs_high, false)); |
714 } | 823 } |
715 } | 824 } |
716 } // namespace compiler | 825 } // namespace compiler |
717 } // namespace internal | 826 } // namespace internal |
718 } // namespace v8 | 827 } // namespace v8 |
OLD | NEW |