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/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 return; | 950 return; |
951 } | 951 } |
952 } | 952 } |
953 } | 953 } |
954 VisitShift(this, node, TryMatchASR); | 954 VisitShift(this, node, TryMatchASR); |
955 } | 955 } |
956 | 956 |
957 void InstructionSelector::VisitInt32PairAdd(Node* node) { | 957 void InstructionSelector::VisitInt32PairAdd(Node* node) { |
958 ArmOperandGenerator g(this); | 958 ArmOperandGenerator g(this); |
959 | 959 |
960 // We use UseUniqueRegister here to avoid register sharing with the output | 960 Node* projection1 = NodeProperties::FindProjection(node, 1); |
961 // registers. | 961 if (projection1) { |
962 InstructionOperand inputs[] = { | 962 // We use UseUniqueRegister here to avoid register sharing with the output |
963 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 963 // registers. |
964 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 964 InstructionOperand inputs[] = { |
| 965 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
| 966 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
965 | 967 |
966 InstructionOperand outputs[] = { | 968 InstructionOperand outputs[] = { |
967 g.DefineAsRegister(node), | 969 g.DefineAsRegister(node), |
968 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | 970 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; |
969 | 971 |
970 Emit(kArmAddPair, 2, outputs, 4, inputs); | 972 Emit(kArmAddPair, 2, outputs, 4, inputs); |
| 973 } else { |
| 974 // The high word of the result is not used, so we emit the standard 32 bit |
| 975 // instruction. |
| 976 Emit(kArmAdd | AddressingModeField::encode(kMode_Operand2_R), |
| 977 g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 978 g.UseRegister(node->InputAt(2))); |
| 979 } |
971 } | 980 } |
972 | 981 |
973 void InstructionSelector::VisitInt32PairSub(Node* node) { | 982 void InstructionSelector::VisitInt32PairSub(Node* node) { |
974 ArmOperandGenerator g(this); | 983 ArmOperandGenerator g(this); |
975 | 984 |
976 // We use UseUniqueRegister here to avoid register sharing with the output | 985 Node* projection1 = NodeProperties::FindProjection(node, 1); |
977 // register. | 986 if (projection1) { |
978 InstructionOperand inputs[] = { | 987 // We use UseUniqueRegister here to avoid register sharing with the output |
979 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 988 // register. |
980 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 989 InstructionOperand inputs[] = { |
| 990 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
| 991 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
981 | 992 |
982 InstructionOperand outputs[] = { | 993 InstructionOperand outputs[] = { |
983 g.DefineAsRegister(node), | 994 g.DefineAsRegister(node), |
984 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | 995 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; |
985 | 996 |
986 Emit(kArmSubPair, 2, outputs, 4, inputs); | 997 Emit(kArmSubPair, 2, outputs, 4, inputs); |
| 998 } else { |
| 999 // The high word of the result is not used, so we emit the standard 32 bit |
| 1000 // instruction. |
| 1001 Emit(kArmSub | AddressingModeField::encode(kMode_Operand2_R), |
| 1002 g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 1003 g.UseRegister(node->InputAt(2))); |
| 1004 } |
987 } | 1005 } |
988 | 1006 |
989 void InstructionSelector::VisitInt32PairMul(Node* node) { | 1007 void InstructionSelector::VisitInt32PairMul(Node* node) { |
990 ArmOperandGenerator g(this); | 1008 ArmOperandGenerator g(this); |
991 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), | 1009 Node* projection1 = NodeProperties::FindProjection(node, 1); |
992 g.UseUniqueRegister(node->InputAt(1)), | 1010 if (projection1) { |
993 g.UseUniqueRegister(node->InputAt(2)), | 1011 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), |
994 g.UseUniqueRegister(node->InputAt(3))}; | 1012 g.UseUniqueRegister(node->InputAt(1)), |
| 1013 g.UseUniqueRegister(node->InputAt(2)), |
| 1014 g.UseUniqueRegister(node->InputAt(3))}; |
995 | 1015 |
996 InstructionOperand outputs[] = { | 1016 InstructionOperand outputs[] = { |
997 g.DefineAsRegister(node), | 1017 g.DefineAsRegister(node), |
998 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | 1018 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; |
999 | 1019 |
1000 Emit(kArmMulPair, 2, outputs, 4, inputs); | 1020 Emit(kArmMulPair, 2, outputs, 4, inputs); |
| 1021 } else { |
| 1022 // The high word of the result is not used, so we emit the standard 32 bit |
| 1023 // instruction. |
| 1024 Emit(kArmMul | AddressingModeField::encode(kMode_Operand2_R), |
| 1025 g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), |
| 1026 g.UseRegister(node->InputAt(2))); |
| 1027 } |
1001 } | 1028 } |
1002 | 1029 |
1003 void InstructionSelector::VisitWord32PairShl(Node* node) { | 1030 namespace { |
1004 ArmOperandGenerator g(this); | 1031 // Shared routine for multiple shift operations. |
1005 // We use g.UseUniqueRegister here for InputAt(0) to guarantee that there is | 1032 void VisitWord32PairShift(InstructionSelector* selector, InstructionCode opcode, |
1006 // no register aliasing with output registers. | 1033 Node* node) { |
| 1034 ArmOperandGenerator g(selector); |
| 1035 // We use g.UseUniqueRegister here to guarantee that there is |
| 1036 // no register aliasing of input registers with output registers. |
1007 Int32Matcher m(node->InputAt(2)); | 1037 Int32Matcher m(node->InputAt(2)); |
1008 InstructionOperand shift_operand; | 1038 InstructionOperand shift_operand; |
1009 if (m.HasValue()) { | 1039 if (m.HasValue()) { |
1010 shift_operand = g.UseImmediate(m.node()); | |
1011 } else { | |
1012 shift_operand = g.UseUniqueRegister(m.node()); | |
1013 } | |
1014 | |
1015 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), | |
1016 g.UseRegister(node->InputAt(1)), | |
1017 shift_operand}; | |
1018 | |
1019 InstructionOperand outputs[] = { | |
1020 g.DefineAsRegister(node), | |
1021 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
1022 | |
1023 Emit(kArmLslPair, 2, outputs, 3, inputs); | |
1024 } | |
1025 | |
1026 void InstructionSelector::VisitWord32PairShr(Node* node) { | |
1027 ArmOperandGenerator g(this); | |
1028 // We use g.UseUniqueRegister here for InputAt(1) and InputAt(2) to to | |
1029 // guarantee that there is no register aliasing with output register. | |
1030 Int32Matcher m(node->InputAt(2)); | |
1031 InstructionOperand shift_operand; | |
1032 if (m.HasValue()) { | |
1033 shift_operand = g.UseImmediate(m.node()); | 1040 shift_operand = g.UseImmediate(m.node()); |
1034 } else { | 1041 } else { |
1035 shift_operand = g.UseUniqueRegister(m.node()); | 1042 shift_operand = g.UseUniqueRegister(m.node()); |
1036 } | 1043 } |
1037 | 1044 |
1038 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)), | 1045 InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), |
1039 g.UseUniqueRegister(node->InputAt(1)), | 1046 g.UseUniqueRegister(node->InputAt(1)), |
1040 shift_operand}; | 1047 shift_operand}; |
1041 | 1048 |
1042 InstructionOperand outputs[] = { | 1049 Node* projection1 = NodeProperties::FindProjection(node, 1); |
1043 g.DefineAsRegister(node), | |
1044 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
1045 | 1050 |
1046 Emit(kArmLsrPair, 2, outputs, 3, inputs); | 1051 InstructionOperand outputs[2]; |
| 1052 InstructionOperand temps[1]; |
| 1053 int32_t output_count = 0; |
| 1054 int32_t temp_count = 0; |
| 1055 |
| 1056 outputs[output_count++] = g.DefineAsRegister(node); |
| 1057 if (projection1) { |
| 1058 outputs[output_count++] = g.DefineAsRegister(projection1); |
| 1059 } else { |
| 1060 temps[temp_count++] = g.TempRegister(); |
| 1061 } |
| 1062 |
| 1063 selector->Emit(opcode, output_count, outputs, 3, inputs, temp_count, temps); |
| 1064 } |
| 1065 } // namespace |
| 1066 void InstructionSelector::VisitWord32PairShl(Node* node) { |
| 1067 VisitWord32PairShift(this, kArmLslPair, node); |
| 1068 } |
| 1069 |
| 1070 void InstructionSelector::VisitWord32PairShr(Node* node) { |
| 1071 VisitWord32PairShift(this, kArmLsrPair, node); |
1047 } | 1072 } |
1048 | 1073 |
1049 void InstructionSelector::VisitWord32PairSar(Node* node) { | 1074 void InstructionSelector::VisitWord32PairSar(Node* node) { |
1050 ArmOperandGenerator g(this); | 1075 VisitWord32PairShift(this, kArmAsrPair, node); |
1051 // We use g.UseUniqueRegister here for InputAt(1) and InputAt(2) to to | |
1052 // guarantee that there is no register aliasing with output register. | |
1053 Int32Matcher m(node->InputAt(2)); | |
1054 InstructionOperand shift_operand; | |
1055 if (m.HasValue()) { | |
1056 shift_operand = g.UseImmediate(m.node()); | |
1057 } else { | |
1058 shift_operand = g.UseUniqueRegister(m.node()); | |
1059 } | |
1060 | |
1061 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)), | |
1062 g.UseUniqueRegister(node->InputAt(1)), | |
1063 shift_operand}; | |
1064 | |
1065 InstructionOperand outputs[] = { | |
1066 g.DefineAsRegister(node), | |
1067 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | |
1068 | |
1069 Emit(kArmAsrPair, 2, outputs, 3, inputs); | |
1070 } | 1076 } |
1071 | 1077 |
1072 void InstructionSelector::VisitWord32Ror(Node* node) { | 1078 void InstructionSelector::VisitWord32Ror(Node* node) { |
1073 VisitShift(this, node, TryMatchROR); | 1079 VisitShift(this, node, TryMatchROR); |
1074 } | 1080 } |
1075 | 1081 |
1076 | 1082 |
1077 void InstructionSelector::VisitWord32Clz(Node* node) { | 1083 void InstructionSelector::VisitWord32Clz(Node* node) { |
1078 VisitRR(this, kArmClz, node); | 1084 VisitRR(this, kArmClz, node); |
1079 } | 1085 } |
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2276 Vector<MachineType> req_aligned = Vector<MachineType>::New(2); | 2282 Vector<MachineType> req_aligned = Vector<MachineType>::New(2); |
2277 req_aligned[0] = MachineType::Float32(); | 2283 req_aligned[0] = MachineType::Float32(); |
2278 req_aligned[1] = MachineType::Float64(); | 2284 req_aligned[1] = MachineType::Float64(); |
2279 return MachineOperatorBuilder::AlignmentRequirements:: | 2285 return MachineOperatorBuilder::AlignmentRequirements:: |
2280 SomeUnalignedAccessUnsupported(req_aligned, req_aligned); | 2286 SomeUnalignedAccessUnsupported(req_aligned, req_aligned); |
2281 } | 2287 } |
2282 | 2288 |
2283 } // namespace compiler | 2289 } // namespace compiler |
2284 } // namespace internal | 2290 } // namespace internal |
2285 } // namespace v8 | 2291 } // namespace v8 |
OLD | NEW |