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 #include "src/ppc/frames-ppc.h" | 9 #include "src/ppc/frames-ppc.h" |
10 | 10 |
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node), | 803 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node), |
804 g.UseRegister(mleft.left().node())); | 804 g.UseRegister(mleft.left().node())); |
805 return; | 805 return; |
806 } | 806 } |
807 } | 807 } |
808 VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm); | 808 VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm); |
809 } | 809 } |
810 | 810 |
811 #if !V8_TARGET_ARCH_PPC64 | 811 #if !V8_TARGET_ARCH_PPC64 |
812 void VisitPairBinop(InstructionSelector* selector, InstructionCode opcode, | 812 void VisitPairBinop(InstructionSelector* selector, InstructionCode opcode, |
813 Node* node) { | 813 InstructionCode opcode2, Node* node) { |
814 PPCOperandGenerator g(selector); | 814 PPCOperandGenerator g(selector); |
815 | 815 |
816 // We use UseUniqueRegister here to avoid register sharing with the output | 816 Node* projection1 = NodeProperties::FindProjection(node, 1); |
817 // registers. | 817 if (projection1) { |
818 InstructionOperand inputs[] = { | 818 // We use UseUniqueRegister here to avoid register sharing with the output |
819 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 819 // registers. |
820 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 820 InstructionOperand inputs[] = { |
| 821 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
| 822 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
821 | 823 |
822 InstructionOperand outputs[] = { | 824 InstructionOperand outputs[] = { |
823 g.DefineAsRegister(node), | 825 g.DefineAsRegister(node), |
824 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | 826 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; |
825 | 827 |
826 selector->Emit(opcode, 2, outputs, 4, inputs); | 828 selector->Emit(opcode, 2, outputs, 4, inputs); |
| 829 } else { |
| 830 // The high word of the result is not used, so we emit the standard 32 bit |
| 831 // instruction. |
| 832 selector->Emit(opcode2, g.DefineSameAsFirst(node), |
| 833 g.UseRegister(node->InputAt(0)), |
| 834 g.UseRegister(node->InputAt(2))); |
| 835 } |
827 } | 836 } |
828 | 837 |
829 void InstructionSelector::VisitInt32PairAdd(Node* node) { | 838 void InstructionSelector::VisitInt32PairAdd(Node* node) { |
830 VisitPairBinop(this, kPPC_AddPair, node); | 839 VisitPairBinop(this, kPPC_AddPair, kPPC_Add, node); |
831 } | 840 } |
832 | 841 |
833 void InstructionSelector::VisitInt32PairSub(Node* node) { | 842 void InstructionSelector::VisitInt32PairSub(Node* node) { |
834 VisitPairBinop(this, kPPC_SubPair, node); | 843 VisitPairBinop(this, kPPC_SubPair, kPPC_Sub, node); |
835 } | 844 } |
836 | 845 |
837 void InstructionSelector::VisitInt32PairMul(Node* node) { | 846 void InstructionSelector::VisitInt32PairMul(Node* node) { |
838 PPCOperandGenerator g(this); | 847 PPCOperandGenerator g(this); |
839 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), | 848 Node* projection1 = NodeProperties::FindProjection(node, 1); |
840 g.UseUniqueRegister(node->InputAt(1)), | 849 if (projection1) { |
841 g.UseUniqueRegister(node->InputAt(2)), | 850 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), |
842 g.UseRegister(node->InputAt(3))}; | 851 g.UseUniqueRegister(node->InputAt(1)), |
| 852 g.UseUniqueRegister(node->InputAt(2)), |
| 853 g.UseUniqueRegister(node->InputAt(3))}; |
843 | 854 |
844 InstructionOperand outputs[] = { | 855 InstructionOperand outputs[] = { |
845 g.DefineAsRegister(node), | 856 g.DefineAsRegister(node), |
846 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | 857 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; |
847 | 858 |
848 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 859 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
849 | 860 |
850 Emit(kPPC_MulPair, 2, outputs, 4, inputs, 2, temps); | 861 Emit(kPPC_MulPair, 2, outputs, 4, inputs, 2, temps); |
| 862 } else { |
| 863 // The high word of the result is not used, so we emit the standard 32 bit |
| 864 // instruction. |
| 865 Emit(kPPC_Mul32, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 866 g.UseRegister(node->InputAt(2))); |
| 867 } |
851 } | 868 } |
852 | 869 |
| 870 namespace { |
| 871 // Shared routine for multiple shift operations. |
853 void VisitPairShift(InstructionSelector* selector, InstructionCode opcode, | 872 void VisitPairShift(InstructionSelector* selector, InstructionCode opcode, |
854 Node* node) { | 873 Node* node) { |
855 PPCOperandGenerator g(selector); | 874 PPCOperandGenerator g(selector); |
| 875 // We use g.UseUniqueRegister here to guarantee that there is |
| 876 // no register aliasing of input registers with output registers. |
856 Int32Matcher m(node->InputAt(2)); | 877 Int32Matcher m(node->InputAt(2)); |
857 InstructionOperand shift_operand; | 878 InstructionOperand shift_operand; |
858 if (m.HasValue()) { | 879 if (m.HasValue()) { |
859 shift_operand = g.UseImmediate(m.node()); | 880 shift_operand = g.UseImmediate(m.node()); |
860 } else { | 881 } else { |
861 shift_operand = g.UseUniqueRegister(m.node()); | 882 shift_operand = g.UseUniqueRegister(m.node()); |
862 } | 883 } |
863 | 884 |
864 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)), | 885 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), |
865 g.UseRegister(node->InputAt(1)), | 886 g.UseUniqueRegister(node->InputAt(1)), |
866 shift_operand}; | 887 shift_operand}; |
867 | 888 |
868 InstructionOperand outputs[] = { | 889 Node* projection1 = NodeProperties::FindProjection(node, 1); |
869 g.DefineSameAsFirst(node), | |
870 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
871 | 890 |
872 selector->Emit(opcode, 2, outputs, 3, inputs); | 891 InstructionOperand outputs[2]; |
| 892 InstructionOperand temps[1]; |
| 893 int32_t output_count = 0; |
| 894 int32_t temp_count = 0; |
| 895 |
| 896 outputs[output_count++] = g.DefineAsRegister(node); |
| 897 if (projection1) { |
| 898 outputs[output_count++] = g.DefineAsRegister(projection1); |
| 899 } else { |
| 900 temps[temp_count++] = g.TempRegister(); |
| 901 } |
| 902 |
| 903 selector->Emit(opcode, output_count, outputs, 3, inputs, temp_count, temps); |
873 } | 904 } |
| 905 } // namespace |
874 | 906 |
875 void InstructionSelector::VisitWord32PairShl(Node* node) { | 907 void InstructionSelector::VisitWord32PairShl(Node* node) { |
876 VisitPairShift(this, kPPC_ShiftLeftPair, node); | 908 VisitPairShift(this, kPPC_ShiftLeftPair, node); |
877 } | 909 } |
878 | 910 |
879 void InstructionSelector::VisitWord32PairShr(Node* node) { | 911 void InstructionSelector::VisitWord32PairShr(Node* node) { |
880 VisitPairShift(this, kPPC_ShiftRightPair, node); | 912 VisitPairShift(this, kPPC_ShiftRightPair, node); |
881 } | 913 } |
882 | 914 |
883 void InstructionSelector::VisitWord32PairSar(Node* node) { | 915 void InstructionSelector::VisitWord32PairSar(Node* node) { |
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2061 // static | 2093 // static |
2062 MachineOperatorBuilder::AlignmentRequirements | 2094 MachineOperatorBuilder::AlignmentRequirements |
2063 InstructionSelector::AlignmentRequirements() { | 2095 InstructionSelector::AlignmentRequirements() { |
2064 return MachineOperatorBuilder::AlignmentRequirements:: | 2096 return MachineOperatorBuilder::AlignmentRequirements:: |
2065 FullUnalignedAccessSupport(); | 2097 FullUnalignedAccessSupport(); |
2066 } | 2098 } |
2067 | 2099 |
2068 } // namespace compiler | 2100 } // namespace compiler |
2069 } // namespace internal | 2101 } // namespace internal |
2070 } // namespace v8 | 2102 } // namespace v8 |
OLD | NEW |