| 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/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
| 8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 } | 639 } |
| 640 | 640 |
| 641 | 641 |
| 642 void InstructionSelector::VisitWord32Sar(Node* node) { | 642 void InstructionSelector::VisitWord32Sar(Node* node) { |
| 643 VisitShift(this, node, kIA32Sar); | 643 VisitShift(this, node, kIA32Sar); |
| 644 } | 644 } |
| 645 | 645 |
| 646 void InstructionSelector::VisitInt32PairAdd(Node* node) { | 646 void InstructionSelector::VisitInt32PairAdd(Node* node) { |
| 647 IA32OperandGenerator g(this); | 647 IA32OperandGenerator g(this); |
| 648 | 648 |
| 649 // We use UseUniqueRegister here to avoid register sharing with the temp | 649 Node* projection1 = NodeProperties::FindProjection(node, 1); |
| 650 // register. | 650 if (projection1) { |
| 651 InstructionOperand inputs[] = { | 651 // We use UseUniqueRegister here to avoid register sharing with the temp |
| 652 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 652 // register. |
| 653 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 653 InstructionOperand inputs[] = { |
| 654 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
| 655 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
| 654 | 656 |
| 655 InstructionOperand outputs[] = { | 657 InstructionOperand outputs[] = {g.DefineSameAsFirst(node), |
| 656 g.DefineSameAsFirst(node), | 658 g.DefineAsRegister(projection1)}; |
| 657 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
| 658 | 659 |
| 659 InstructionOperand temps[] = {g.TempRegister()}; | 660 InstructionOperand temps[] = {g.TempRegister()}; |
| 660 | 661 |
| 661 Emit(kIA32AddPair, 2, outputs, 4, inputs, 1, temps); | 662 Emit(kIA32AddPair, 2, outputs, 4, inputs, 1, temps); |
| 663 } else { |
| 664 // The high word of the result is not used, so we emit the standard 32 bit |
| 665 // instruction. |
| 666 Emit(kIA32Add, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 667 g.Use(node->InputAt(2))); |
| 668 } |
| 662 } | 669 } |
| 663 | 670 |
| 664 void InstructionSelector::VisitInt32PairSub(Node* node) { | 671 void InstructionSelector::VisitInt32PairSub(Node* node) { |
| 665 IA32OperandGenerator g(this); | 672 IA32OperandGenerator g(this); |
| 666 | 673 |
| 667 // We use UseUniqueRegister here to avoid register sharing with the temp | 674 Node* projection1 = NodeProperties::FindProjection(node, 1); |
| 668 // register. | 675 if (projection1) { |
| 669 InstructionOperand inputs[] = { | 676 // We use UseUniqueRegister here to avoid register sharing with the temp |
| 670 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 677 // register. |
| 671 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 678 InstructionOperand inputs[] = { |
| 679 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
| 680 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
| 672 | 681 |
| 673 InstructionOperand outputs[] = { | 682 InstructionOperand outputs[] = {g.DefineSameAsFirst(node), |
| 674 g.DefineSameAsFirst(node), | 683 g.DefineAsRegister(projection1)}; |
| 675 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
| 676 | 684 |
| 677 InstructionOperand temps[] = {g.TempRegister()}; | 685 InstructionOperand temps[] = {g.TempRegister()}; |
| 678 | 686 |
| 679 Emit(kIA32SubPair, 2, outputs, 4, inputs, 1, temps); | 687 Emit(kIA32SubPair, 2, outputs, 4, inputs, 1, temps); |
| 688 } else { |
| 689 // The high word of the result is not used, so we emit the standard 32 bit |
| 690 // instruction. |
| 691 Emit(kIA32Sub, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 692 g.Use(node->InputAt(2))); |
| 693 } |
| 680 } | 694 } |
| 681 | 695 |
| 682 void InstructionSelector::VisitInt32PairMul(Node* node) { | 696 void InstructionSelector::VisitInt32PairMul(Node* node) { |
| 683 IA32OperandGenerator g(this); | 697 IA32OperandGenerator g(this); |
| 684 | 698 |
| 685 // InputAt(3) explicitly shares ecx with OutputRegister(1) to save one | 699 Node* projection1 = NodeProperties::FindProjection(node, 1); |
| 686 // register and one mov instruction. | 700 if (projection1) { |
| 687 InstructionOperand inputs[] = { | 701 // InputAt(3) explicitly shares ecx with OutputRegister(1) to save one |
| 688 g.UseUnique(node->InputAt(0)), g.UseUnique(node->InputAt(1)), | 702 // register and one mov instruction. |
| 689 g.UseUniqueRegister(node->InputAt(2)), g.UseFixed(node->InputAt(3), ecx)}; | 703 InstructionOperand inputs[] = {g.UseUnique(node->InputAt(0)), |
| 704 g.UseUnique(node->InputAt(1)), |
| 705 g.UseUniqueRegister(node->InputAt(2)), |
| 706 g.UseFixed(node->InputAt(3), ecx)}; |
| 690 | 707 |
| 691 InstructionOperand outputs[] = { | 708 InstructionOperand outputs[] = { |
| 692 g.DefineAsFixed(node, eax), | 709 g.DefineAsFixed(node, eax), |
| 693 g.DefineAsFixed(NodeProperties::FindProjection(node, 1), ecx)}; | 710 g.DefineAsFixed(NodeProperties::FindProjection(node, 1), ecx)}; |
| 694 | 711 |
| 695 InstructionOperand temps[] = {g.TempRegister(edx)}; | 712 InstructionOperand temps[] = {g.TempRegister(edx)}; |
| 696 | 713 |
| 697 Emit(kIA32MulPair, 2, outputs, 4, inputs, 1, temps); | 714 Emit(kIA32MulPair, 2, outputs, 4, inputs, 1, temps); |
| 715 } else { |
| 716 // The high word of the result is not used, so we emit the standard 32 bit |
| 717 // instruction. |
| 718 Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 719 g.Use(node->InputAt(2))); |
| 720 } |
| 698 } | 721 } |
| 699 | 722 |
| 700 void VisitWord32PairShift(InstructionSelector* selector, InstructionCode opcode, | 723 void VisitWord32PairShift(InstructionSelector* selector, InstructionCode opcode, |
| 701 Node* node) { | 724 Node* node) { |
| 702 IA32OperandGenerator g(selector); | 725 IA32OperandGenerator g(selector); |
| 703 | 726 |
| 704 Node* shift = node->InputAt(2); | 727 Node* shift = node->InputAt(2); |
| 705 InstructionOperand shift_operand; | 728 InstructionOperand shift_operand; |
| 706 if (g.CanBeImmediate(shift)) { | 729 if (g.CanBeImmediate(shift)) { |
| 707 shift_operand = g.UseImmediate(shift); | 730 shift_operand = g.UseImmediate(shift); |
| 708 } else { | 731 } else { |
| 709 shift_operand = g.UseFixed(shift, ecx); | 732 shift_operand = g.UseFixed(shift, ecx); |
| 710 } | 733 } |
| 711 InstructionOperand inputs[] = {g.UseFixed(node->InputAt(0), eax), | 734 InstructionOperand inputs[] = {g.UseFixed(node->InputAt(0), eax), |
| 712 g.UseFixed(node->InputAt(1), edx), | 735 g.UseFixed(node->InputAt(1), edx), |
| 713 shift_operand}; | 736 shift_operand}; |
| 714 | 737 |
| 715 InstructionOperand outputs[] = { | 738 InstructionOperand outputs[2]; |
| 716 g.DefineAsFixed(node, eax), | 739 InstructionOperand temps[1]; |
| 717 g.DefineAsFixed(NodeProperties::FindProjection(node, 1), edx)}; | 740 int32_t output_count = 0; |
| 741 int32_t temp_count = 0; |
| 742 outputs[output_count++] = g.DefineAsFixed(node, eax); |
| 743 Node* projection1 = NodeProperties::FindProjection(node, 1); |
| 744 if (projection1) { |
| 745 outputs[output_count++] = g.DefineAsFixed(projection1, edx); |
| 746 } else { |
| 747 temps[temp_count++] = g.TempRegister(edx); |
| 748 } |
| 718 | 749 |
| 719 selector->Emit(opcode, 2, outputs, 3, inputs); | 750 selector->Emit(opcode, output_count, outputs, 3, inputs, temp_count, temps); |
| 720 } | 751 } |
| 721 | 752 |
| 722 void InstructionSelector::VisitWord32PairShl(Node* node) { | 753 void InstructionSelector::VisitWord32PairShl(Node* node) { |
| 723 VisitWord32PairShift(this, kIA32ShlPair, node); | 754 VisitWord32PairShift(this, kIA32ShlPair, node); |
| 724 } | 755 } |
| 725 | 756 |
| 726 void InstructionSelector::VisitWord32PairShr(Node* node) { | 757 void InstructionSelector::VisitWord32PairShr(Node* node) { |
| 727 VisitWord32PairShift(this, kIA32ShrPair, node); | 758 VisitWord32PairShift(this, kIA32ShrPair, node); |
| 728 } | 759 } |
| 729 | 760 |
| (...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 // static | 1748 // static |
| 1718 MachineOperatorBuilder::AlignmentRequirements | 1749 MachineOperatorBuilder::AlignmentRequirements |
| 1719 InstructionSelector::AlignmentRequirements() { | 1750 InstructionSelector::AlignmentRequirements() { |
| 1720 return MachineOperatorBuilder::AlignmentRequirements:: | 1751 return MachineOperatorBuilder::AlignmentRequirements:: |
| 1721 FullUnalignedAccessSupport(); | 1752 FullUnalignedAccessSupport(); |
| 1722 } | 1753 } |
| 1723 | 1754 |
| 1724 } // namespace compiler | 1755 } // namespace compiler |
| 1725 } // namespace internal | 1756 } // namespace internal |
| 1726 } // namespace v8 | 1757 } // namespace v8 |
| OLD | NEW |