OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/s390/frames-s390.h" | 9 #include "src/s390/frames-s390.h" |
10 | 10 |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 } else if (mleft.right().Is(24) && m.right().Is(24)) { | 828 } else if (mleft.right().Is(24) && m.right().Is(24)) { |
829 Emit(kS390_ExtendSignWord8, g.DefineAsRegister(node), | 829 Emit(kS390_ExtendSignWord8, g.DefineAsRegister(node), |
830 g.UseRegister(mleft.left().node())); | 830 g.UseRegister(mleft.left().node())); |
831 return; | 831 return; |
832 } | 832 } |
833 } | 833 } |
834 VisitRRO(this, kS390_ShiftRightArith32, node, kShift32Imm); | 834 VisitRRO(this, kS390_ShiftRightArith32, node, kShift32Imm); |
835 } | 835 } |
836 | 836 |
837 #if !V8_TARGET_ARCH_S390X | 837 #if !V8_TARGET_ARCH_S390X |
838 void VisitPairBinop(InstructionSelector* selector, ArchOpcode opcode, | 838 void VisitPairBinop(InstructionSelector* selector, InstructionCode opcode, |
839 Node* node) { | 839 InstructionCode opcode2, Node* node) { |
840 S390OperandGenerator g(selector); | 840 S390OperandGenerator g(selector); |
841 | 841 |
842 // We use UseUniqueRegister here to avoid register sharing with the output | 842 Node* projection1 = NodeProperties::FindProjection(node, 1); |
843 // registers. | 843 if (projection1) { |
844 InstructionOperand inputs[] = { | 844 // We use UseUniqueRegister here to avoid register sharing with the output |
845 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 845 // registers. |
846 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 846 InstructionOperand inputs[] = { |
| 847 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
| 848 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
847 | 849 |
848 InstructionOperand outputs[] = { | 850 InstructionOperand outputs[] = { |
849 g.DefineAsRegister(node), | 851 g.DefineAsRegister(node), |
850 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | 852 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; |
851 | 853 |
852 selector->Emit(opcode, 2, outputs, 4, inputs); | 854 selector->Emit(opcode, 2, outputs, 4, inputs); |
| 855 } else { |
| 856 // The high word of the result is not used, so we emit the standard 32 bit |
| 857 // instruction. |
| 858 selector->Emit(opcode2, g.DefineSameAsFirst(node), |
| 859 g.UseRegister(node->InputAt(0)), |
| 860 g.UseRegister(node->InputAt(2))); |
| 861 } |
853 } | 862 } |
854 | 863 |
855 void InstructionSelector::VisitInt32PairAdd(Node* node) { | 864 void InstructionSelector::VisitInt32PairAdd(Node* node) { |
856 VisitPairBinop(this, kS390_AddPair, node); | 865 VisitPairBinop(this, kS390_AddPair, kS390_Add32, node); |
857 } | 866 } |
858 | 867 |
859 void InstructionSelector::VisitInt32PairSub(Node* node) { | 868 void InstructionSelector::VisitInt32PairSub(Node* node) { |
860 VisitPairBinop(this, kS390_SubPair, node); | 869 VisitPairBinop(this, kS390_SubPair, kS390_Sub32, node); |
861 } | 870 } |
862 | 871 |
863 void InstructionSelector::VisitInt32PairMul(Node* node) { | 872 void InstructionSelector::VisitInt32PairMul(Node* node) { |
864 S390OperandGenerator g(this); | 873 S390OperandGenerator g(this); |
865 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), | 874 Node* projection1 = NodeProperties::FindProjection(node, 1); |
866 g.UseUniqueRegister(node->InputAt(1)), | 875 if (projection1) { |
867 g.UseUniqueRegister(node->InputAt(2)), | 876 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), |
868 g.UseUniqueRegister(node->InputAt(3))}; | 877 g.UseUniqueRegister(node->InputAt(1)), |
| 878 g.UseUniqueRegister(node->InputAt(2)), |
| 879 g.UseUniqueRegister(node->InputAt(3))}; |
869 | 880 |
870 InstructionOperand outputs[] = { | 881 InstructionOperand outputs[] = { |
871 g.DefineAsRegister(node), | 882 g.DefineAsRegister(node), |
872 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | 883 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; |
873 | 884 |
874 Emit(kS390_MulPair, 2, outputs, 4, inputs); | 885 Emit(kS390_MulPair, 2, outputs, 4, inputs); |
| 886 } else { |
| 887 // The high word of the result is not used, so we emit the standard 32 bit |
| 888 // instruction. |
| 889 Emit(kS390_Mul32, g.DefineSameAsFirst(node), |
| 890 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(2))); |
| 891 } |
875 } | 892 } |
876 | 893 |
877 void VisitPairShift(InstructionSelector* selector, ArchOpcode opcode, | 894 namespace { |
| 895 // Shared routine for multiple shift operations. |
| 896 void VisitPairShift(InstructionSelector* selector, InstructionCode opcode, |
878 Node* node) { | 897 Node* node) { |
879 S390OperandGenerator g(selector); | 898 S390OperandGenerator g(selector); |
| 899 // We use g.UseUniqueRegister here to guarantee that there is |
| 900 // no register aliasing of input registers with output registers. |
880 Int32Matcher m(node->InputAt(2)); | 901 Int32Matcher m(node->InputAt(2)); |
881 InstructionOperand shift_operand; | 902 InstructionOperand shift_operand; |
882 if (m.HasValue()) { | 903 if (m.HasValue()) { |
883 shift_operand = g.UseImmediate(m.node()); | 904 shift_operand = g.UseImmediate(m.node()); |
884 } else { | 905 } else { |
885 shift_operand = g.UseUniqueRegister(m.node()); | 906 shift_operand = g.UseUniqueRegister(m.node()); |
886 } | 907 } |
887 | 908 |
888 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)), | 909 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), |
889 g.UseRegister(node->InputAt(1)), | 910 g.UseUniqueRegister(node->InputAt(1)), |
890 shift_operand}; | 911 shift_operand}; |
891 | 912 |
892 InstructionOperand outputs[] = { | 913 Node* projection1 = NodeProperties::FindProjection(node, 1); |
893 g.DefineSameAsFirst(node), | |
894 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
895 | 914 |
896 selector->Emit(opcode, 2, outputs, 3, inputs); | 915 InstructionOperand outputs[2]; |
| 916 InstructionOperand temps[1]; |
| 917 int32_t output_count = 0; |
| 918 int32_t temp_count = 0; |
| 919 |
| 920 outputs[output_count++] = g.DefineAsRegister(node); |
| 921 if (projection1) { |
| 922 outputs[output_count++] = g.DefineAsRegister(projection1); |
| 923 } else { |
| 924 temps[temp_count++] = g.TempRegister(); |
| 925 } |
| 926 |
| 927 selector->Emit(opcode, output_count, outputs, 3, inputs, temp_count, temps); |
897 } | 928 } |
| 929 } // namespace |
898 | 930 |
899 void InstructionSelector::VisitWord32PairShl(Node* node) { | 931 void InstructionSelector::VisitWord32PairShl(Node* node) { |
900 VisitPairShift(this, kS390_ShiftLeftPair, node); | 932 VisitPairShift(this, kS390_ShiftLeftPair, node); |
901 } | 933 } |
902 | 934 |
903 void InstructionSelector::VisitWord32PairShr(Node* node) { | 935 void InstructionSelector::VisitWord32PairShr(Node* node) { |
904 VisitPairShift(this, kS390_ShiftRightPair, node); | 936 VisitPairShift(this, kS390_ShiftRightPair, node); |
905 } | 937 } |
906 | 938 |
907 void InstructionSelector::VisitWord32PairSar(Node* node) { | 939 void InstructionSelector::VisitWord32PairSar(Node* node) { |
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 // static | 2063 // static |
2032 MachineOperatorBuilder::AlignmentRequirements | 2064 MachineOperatorBuilder::AlignmentRequirements |
2033 InstructionSelector::AlignmentRequirements() { | 2065 InstructionSelector::AlignmentRequirements() { |
2034 return MachineOperatorBuilder::AlignmentRequirements:: | 2066 return MachineOperatorBuilder::AlignmentRequirements:: |
2035 FullUnalignedAccessSupport(); | 2067 FullUnalignedAccessSupport(); |
2036 } | 2068 } |
2037 | 2069 |
2038 } // namespace compiler | 2070 } // namespace compiler |
2039 } // namespace internal | 2071 } // namespace internal |
2040 } // namespace v8 | 2072 } // namespace v8 |
OLD | NEW |