| 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 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 } | 600 } |
| 601 | 601 |
| 602 | 602 |
| 603 void InstructionSelector::VisitWord32Sar(Node* node) { | 603 void InstructionSelector::VisitWord32Sar(Node* node) { |
| 604 VisitShift(this, node, kX87Sar); | 604 VisitShift(this, node, kX87Sar); |
| 605 } | 605 } |
| 606 | 606 |
| 607 void InstructionSelector::VisitInt32PairAdd(Node* node) { | 607 void InstructionSelector::VisitInt32PairAdd(Node* node) { |
| 608 X87OperandGenerator g(this); | 608 X87OperandGenerator g(this); |
| 609 | 609 |
| 610 // We use UseUniqueRegister here to avoid register sharing with the temp | 610 Node* projection1 = NodeProperties::FindProjection(node, 1); |
| 611 // register. | 611 if (projection1) { |
| 612 InstructionOperand inputs[] = { | 612 // We use UseUniqueRegister here to avoid register sharing with the temp |
| 613 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 613 // register. |
| 614 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 614 InstructionOperand inputs[] = { |
| 615 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
| 616 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
| 615 | 617 |
| 616 InstructionOperand outputs[] = { | 618 InstructionOperand outputs[] = {g.DefineSameAsFirst(node), |
| 617 g.DefineSameAsFirst(node), | 619 g.DefineAsRegister(projection1)}; |
| 618 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
| 619 | 620 |
| 620 InstructionOperand temps[] = {g.TempRegister()}; | 621 InstructionOperand temps[] = {g.TempRegister()}; |
| 621 | 622 |
| 622 Emit(kX87AddPair, 2, outputs, 4, inputs, 1, temps); | 623 Emit(kX87AddPair, 2, outputs, 4, inputs, 1, temps); |
| 624 } else { |
| 625 // The high word of the result is not used, so we emit the standard 32 bit |
| 626 // instruction. |
| 627 Emit(kX87Add, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 628 g.Use(node->InputAt(2))); |
| 629 } |
| 623 } | 630 } |
| 624 | 631 |
| 625 void InstructionSelector::VisitInt32PairSub(Node* node) { | 632 void InstructionSelector::VisitInt32PairSub(Node* node) { |
| 626 X87OperandGenerator g(this); | 633 X87OperandGenerator g(this); |
| 627 | 634 |
| 628 // We use UseUniqueRegister here to avoid register sharing with the temp | 635 Node* projection1 = NodeProperties::FindProjection(node, 1); |
| 629 // register. | 636 if (projection1) { |
| 630 InstructionOperand inputs[] = { | 637 // We use UseUniqueRegister here to avoid register sharing with the temp |
| 631 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 638 // register. |
| 632 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 639 InstructionOperand inputs[] = { |
| 640 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
| 641 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
| 633 | 642 |
| 634 InstructionOperand outputs[] = { | 643 InstructionOperand outputs[] = {g.DefineSameAsFirst(node), |
| 635 g.DefineSameAsFirst(node), | 644 g.DefineAsRegister(projection1)}; |
| 636 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
| 637 | 645 |
| 638 InstructionOperand temps[] = {g.TempRegister()}; | 646 InstructionOperand temps[] = {g.TempRegister()}; |
| 639 | 647 |
| 640 Emit(kX87SubPair, 2, outputs, 4, inputs, 1, temps); | 648 Emit(kX87SubPair, 2, outputs, 4, inputs, 1, temps); |
| 649 } else { |
| 650 // The high word of the result is not used, so we emit the standard 32 bit |
| 651 // instruction. |
| 652 Emit(kX87Sub, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 653 g.Use(node->InputAt(2))); |
| 654 } |
| 641 } | 655 } |
| 642 | 656 |
| 643 void InstructionSelector::VisitInt32PairMul(Node* node) { | 657 void InstructionSelector::VisitInt32PairMul(Node* node) { |
| 644 X87OperandGenerator g(this); | 658 X87OperandGenerator g(this); |
| 645 | 659 |
| 646 // InputAt(3) explicitly shares ecx with OutputRegister(1) to save one | 660 Node* projection1 = NodeProperties::FindProjection(node, 1); |
| 647 // register and one mov instruction. | 661 if (projection1) { |
| 648 InstructionOperand inputs[] = { | 662 // InputAt(3) explicitly shares ecx with OutputRegister(1) to save one |
| 649 g.UseUnique(node->InputAt(0)), g.UseUnique(node->InputAt(1)), | 663 // register and one mov instruction. |
| 650 g.UseUniqueRegister(node->InputAt(2)), g.UseFixed(node->InputAt(3), ecx)}; | 664 InstructionOperand inputs[] = {g.UseUnique(node->InputAt(0)), |
| 665 g.UseUnique(node->InputAt(1)), |
| 666 g.UseUniqueRegister(node->InputAt(2)), |
| 667 g.UseFixed(node->InputAt(3), ecx)}; |
| 651 | 668 |
| 652 InstructionOperand outputs[] = { | 669 InstructionOperand outputs[] = { |
| 653 g.DefineAsFixed(node, eax), | 670 g.DefineAsFixed(node, eax), |
| 654 g.DefineAsFixed(NodeProperties::FindProjection(node, 1), ecx)}; | 671 g.DefineAsFixed(NodeProperties::FindProjection(node, 1), ecx)}; |
| 655 | 672 |
| 656 InstructionOperand temps[] = {g.TempRegister(edx)}; | 673 InstructionOperand temps[] = {g.TempRegister(edx)}; |
| 657 | 674 |
| 658 Emit(kX87MulPair, 2, outputs, 4, inputs, 1, temps); | 675 Emit(kX87MulPair, 2, outputs, 4, inputs, 1, temps); |
| 676 } else { |
| 677 // The high word of the result is not used, so we emit the standard 32 bit |
| 678 // instruction. |
| 679 Emit(kX87Imul, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 680 g.Use(node->InputAt(2))); |
| 681 } |
| 659 } | 682 } |
| 660 | 683 |
| 661 void VisitWord32PairShift(InstructionSelector* selector, InstructionCode opcode, | 684 void VisitWord32PairShift(InstructionSelector* selector, InstructionCode opcode, |
| 662 Node* node) { | 685 Node* node) { |
| 663 X87OperandGenerator g(selector); | 686 X87OperandGenerator g(selector); |
| 664 | 687 |
| 665 Node* shift = node->InputAt(2); | 688 Node* shift = node->InputAt(2); |
| 666 InstructionOperand shift_operand; | 689 InstructionOperand shift_operand; |
| 667 if (g.CanBeImmediate(shift)) { | 690 if (g.CanBeImmediate(shift)) { |
| 668 shift_operand = g.UseImmediate(shift); | 691 shift_operand = g.UseImmediate(shift); |
| 669 } else { | 692 } else { |
| 670 shift_operand = g.UseFixed(shift, ecx); | 693 shift_operand = g.UseFixed(shift, ecx); |
| 671 } | 694 } |
| 672 InstructionOperand inputs[] = {g.UseFixed(node->InputAt(0), eax), | 695 InstructionOperand inputs[] = {g.UseFixed(node->InputAt(0), eax), |
| 673 g.UseFixed(node->InputAt(1), edx), | 696 g.UseFixed(node->InputAt(1), edx), |
| 674 shift_operand}; | 697 shift_operand}; |
| 675 | 698 |
| 676 InstructionOperand outputs[] = { | 699 InstructionOperand outputs[2]; |
| 677 g.DefineAsFixed(node, eax), | 700 InstructionOperand temps[1]; |
| 678 g.DefineAsFixed(NodeProperties::FindProjection(node, 1), edx)}; | 701 int32_t output_count = 0; |
| 702 int32_t temp_count = 0; |
| 703 outputs[output_count++] = g.DefineAsFixed(node, eax); |
| 704 Node* projection1 = NodeProperties::FindProjection(node, 1); |
| 705 if (projection1) { |
| 706 outputs[output_count++] = g.DefineAsFixed(projection1, edx); |
| 707 } else { |
| 708 temps[temp_count++] = g.TempRegister(edx); |
| 709 } |
| 679 | 710 |
| 680 selector->Emit(opcode, 2, outputs, 3, inputs); | 711 selector->Emit(opcode, output_count, outputs, 3, inputs, temp_count, temps); |
| 681 } | 712 } |
| 682 | 713 |
| 683 void InstructionSelector::VisitWord32PairShl(Node* node) { | 714 void InstructionSelector::VisitWord32PairShl(Node* node) { |
| 684 VisitWord32PairShift(this, kX87ShlPair, node); | 715 VisitWord32PairShift(this, kX87ShlPair, node); |
| 685 } | 716 } |
| 686 | 717 |
| 687 void InstructionSelector::VisitWord32PairShr(Node* node) { | 718 void InstructionSelector::VisitWord32PairShr(Node* node) { |
| 688 VisitWord32PairShift(this, kX87ShrPair, node); | 719 VisitWord32PairShift(this, kX87ShrPair, node); |
| 689 } | 720 } |
| 690 | 721 |
| (...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1751 // static | 1782 // static |
| 1752 MachineOperatorBuilder::AlignmentRequirements | 1783 MachineOperatorBuilder::AlignmentRequirements |
| 1753 InstructionSelector::AlignmentRequirements() { | 1784 InstructionSelector::AlignmentRequirements() { |
| 1754 return MachineOperatorBuilder::AlignmentRequirements:: | 1785 return MachineOperatorBuilder::AlignmentRequirements:: |
| 1755 FullUnalignedAccessSupport(); | 1786 FullUnalignedAccessSupport(); |
| 1756 } | 1787 } |
| 1757 | 1788 |
| 1758 } // namespace compiler | 1789 } // namespace compiler |
| 1759 } // namespace internal | 1790 } // namespace internal |
| 1760 } // namespace v8 | 1791 } // namespace v8 |
| OLD | NEW |