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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 case kNoImmediate: | 64 case kNoImmediate: |
65 return false; | 65 return false; |
66 } | 66 } |
67 return false; | 67 return false; |
68 } | 68 } |
69 }; | 69 }; |
70 | 70 |
71 | 71 |
72 namespace { | 72 namespace { |
73 | 73 |
74 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { | 74 void VisitRR(InstructionSelector* selector, InstructionCode opcode, |
| 75 Node* node) { |
75 PPCOperandGenerator g(selector); | 76 PPCOperandGenerator g(selector); |
76 selector->Emit(opcode, g.DefineAsRegister(node), | 77 selector->Emit(opcode, g.DefineAsRegister(node), |
77 g.UseRegister(node->InputAt(0))); | 78 g.UseRegister(node->InputAt(0))); |
78 } | 79 } |
79 | 80 |
80 | 81 void VisitRRR(InstructionSelector* selector, InstructionCode opcode, |
81 void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { | 82 Node* node) { |
82 PPCOperandGenerator g(selector); | 83 PPCOperandGenerator g(selector); |
83 selector->Emit(opcode, g.DefineAsRegister(node), | 84 selector->Emit(opcode, g.DefineAsRegister(node), |
84 g.UseRegister(node->InputAt(0)), | 85 g.UseRegister(node->InputAt(0)), |
85 g.UseRegister(node->InputAt(1))); | 86 g.UseRegister(node->InputAt(1))); |
86 } | 87 } |
87 | 88 |
88 | 89 void VisitRRO(InstructionSelector* selector, InstructionCode opcode, Node* node, |
89 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node, | |
90 ImmediateMode operand_mode) { | 90 ImmediateMode operand_mode) { |
91 PPCOperandGenerator g(selector); | 91 PPCOperandGenerator g(selector); |
92 selector->Emit(opcode, g.DefineAsRegister(node), | 92 selector->Emit(opcode, g.DefineAsRegister(node), |
93 g.UseRegister(node->InputAt(0)), | 93 g.UseRegister(node->InputAt(0)), |
94 g.UseOperand(node->InputAt(1), operand_mode)); | 94 g.UseOperand(node->InputAt(1), operand_mode)); |
95 } | 95 } |
96 | 96 |
97 | 97 |
98 #if V8_TARGET_ARCH_PPC64 | 98 #if V8_TARGET_ARCH_PPC64 |
99 void VisitTryTruncateDouble(InstructionSelector* selector, ArchOpcode opcode, | 99 void VisitTryTruncateDouble(InstructionSelector* selector, |
100 Node* node) { | 100 InstructionCode opcode, Node* node) { |
101 PPCOperandGenerator g(selector); | 101 PPCOperandGenerator g(selector); |
102 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; | 102 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; |
103 InstructionOperand outputs[2]; | 103 InstructionOperand outputs[2]; |
104 size_t output_count = 0; | 104 size_t output_count = 0; |
105 outputs[output_count++] = g.DefineAsRegister(node); | 105 outputs[output_count++] = g.DefineAsRegister(node); |
106 | 106 |
107 Node* success_output = NodeProperties::FindProjection(node, 1); | 107 Node* success_output = NodeProperties::FindProjection(node, 1); |
108 if (success_output) { | 108 if (success_output) { |
109 outputs[output_count++] = g.DefineAsRegister(success_output); | 109 outputs[output_count++] = g.DefineAsRegister(success_output); |
110 } | 110 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, | 149 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
150 cont->frame_state()); | 150 cont->frame_state()); |
151 } else { | 151 } else { |
152 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 152 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
153 } | 153 } |
154 } | 154 } |
155 | 155 |
156 | 156 |
157 // Shared routine for multiple binary operations. | 157 // Shared routine for multiple binary operations. |
158 template <typename Matcher> | 158 template <typename Matcher> |
159 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, | 159 void VisitBinop(InstructionSelector* selector, Node* node, |
160 ImmediateMode operand_mode) { | 160 InstructionCode opcode, ImmediateMode operand_mode) { |
161 FlagsContinuation cont; | 161 FlagsContinuation cont; |
162 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); | 162 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); |
163 } | 163 } |
164 | 164 |
165 } // namespace | 165 } // namespace |
166 | 166 |
167 | 167 |
168 void InstructionSelector::VisitLoad(Node* node) { | 168 void InstructionSelector::VisitLoad(Node* node) { |
169 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); | 169 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
170 PPCOperandGenerator g(this); | 170 PPCOperandGenerator g(this); |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 } else if (mleft.right().Is(24) && m.right().Is(24)) { | 778 } else if (mleft.right().Is(24) && m.right().Is(24)) { |
779 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node), | 779 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node), |
780 g.UseRegister(mleft.left().node())); | 780 g.UseRegister(mleft.left().node())); |
781 return; | 781 return; |
782 } | 782 } |
783 } | 783 } |
784 VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm); | 784 VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm); |
785 } | 785 } |
786 | 786 |
787 #if !V8_TARGET_ARCH_PPC64 | 787 #if !V8_TARGET_ARCH_PPC64 |
788 void VisitPairBinop(InstructionSelector* selector, ArchOpcode opcode, | 788 void VisitPairBinop(InstructionSelector* selector, InstructionCode opcode, |
789 Node* node) { | 789 Node* node) { |
790 PPCOperandGenerator g(selector); | 790 PPCOperandGenerator g(selector); |
791 | 791 |
792 // We use UseUniqueRegister here to avoid register sharing with the output | 792 // We use UseUniqueRegister here to avoid register sharing with the output |
793 // registers. | 793 // registers. |
794 InstructionOperand inputs[] = { | 794 InstructionOperand inputs[] = { |
795 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), | 795 g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), |
796 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; | 796 g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; |
797 | 797 |
798 InstructionOperand outputs[] = { | 798 InstructionOperand outputs[] = { |
799 g.DefineAsRegister(node), | 799 g.DefineAsRegister(node), |
800 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; | 800 g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; |
801 | 801 |
802 selector->Emit(opcode, 2, outputs, 4, inputs); | 802 selector->Emit(opcode, 2, outputs, 4, inputs); |
803 } | 803 } |
804 | 804 |
805 void InstructionSelector::VisitInt32PairAdd(Node* node) { | 805 void InstructionSelector::VisitInt32PairAdd(Node* node) { |
806 VisitPairBinop(this, kPPC_AddPair, node); | 806 VisitPairBinop(this, kPPC_AddPair, node); |
807 } | 807 } |
808 | 808 |
809 void InstructionSelector::VisitInt32PairSub(Node* node) { | 809 void InstructionSelector::VisitInt32PairSub(Node* node) { |
810 VisitPairBinop(this, kPPC_SubPair, node); | 810 VisitPairBinop(this, kPPC_SubPair, node); |
811 } | 811 } |
812 | 812 |
813 void VisitPairShift(InstructionSelector* selector, ArchOpcode opcode, | 813 void VisitPairShift(InstructionSelector* selector, InstructionCode opcode, |
814 Node* node) { | 814 Node* node) { |
815 PPCOperandGenerator g(selector); | 815 PPCOperandGenerator g(selector); |
816 Int32Matcher m(node->InputAt(2)); | 816 Int32Matcher m(node->InputAt(2)); |
817 InstructionOperand shift_operand; | 817 InstructionOperand shift_operand; |
818 if (m.HasValue()) { | 818 if (m.HasValue()) { |
819 shift_operand = g.UseImmediate(m.node()); | 819 shift_operand = g.UseImmediate(m.node()); |
820 } else { | 820 } else { |
821 shift_operand = g.UseUniqueRegister(m.node()); | 821 shift_operand = g.UseUniqueRegister(m.node()); |
822 } | 822 } |
823 | 823 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 | 1162 |
1163 | 1163 |
1164 #if V8_TARGET_ARCH_PPC64 | 1164 #if V8_TARGET_ARCH_PPC64 |
1165 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) { | 1165 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) { |
1166 VisitRR(this, kPPC_BitcastInt64ToDouble, node); | 1166 VisitRR(this, kPPC_BitcastInt64ToDouble, node); |
1167 } | 1167 } |
1168 #endif | 1168 #endif |
1169 | 1169 |
1170 | 1170 |
1171 void InstructionSelector::VisitFloat32Add(Node* node) { | 1171 void InstructionSelector::VisitFloat32Add(Node* node) { |
1172 VisitRRR(this, kPPC_AddDouble, node); | 1172 VisitRRR(this, kPPC_AddDouble | MiscField::encode(1), node); |
1173 } | 1173 } |
1174 | 1174 |
1175 | 1175 |
1176 void InstructionSelector::VisitFloat64Add(Node* node) { | 1176 void InstructionSelector::VisitFloat64Add(Node* node) { |
1177 // TODO(mbrandy): detect multiply-add | 1177 // TODO(mbrandy): detect multiply-add |
1178 VisitRRR(this, kPPC_AddDouble, node); | 1178 VisitRRR(this, kPPC_AddDouble, node); |
1179 } | 1179 } |
1180 | 1180 |
1181 | 1181 |
1182 void InstructionSelector::VisitFloat32Sub(Node* node) { | 1182 void InstructionSelector::VisitFloat32Sub(Node* node) { |
1183 PPCOperandGenerator g(this); | 1183 PPCOperandGenerator g(this); |
1184 Float32BinopMatcher m(node); | 1184 Float32BinopMatcher m(node); |
1185 if (m.left().IsMinusZero()) { | 1185 if (m.left().IsMinusZero()) { |
1186 Emit(kPPC_NegDouble, g.DefineAsRegister(node), | 1186 Emit(kPPC_NegDouble | MiscField::encode(1), g.DefineAsRegister(node), |
1187 g.UseRegister(m.right().node())); | 1187 g.UseRegister(m.right().node())); |
1188 return; | 1188 return; |
1189 } | 1189 } |
1190 VisitRRR(this, kPPC_SubDouble, node); | 1190 VisitRRR(this, kPPC_SubDouble | MiscField::encode(1), node); |
1191 } | 1191 } |
1192 | 1192 |
1193 | 1193 |
1194 void InstructionSelector::VisitFloat64Sub(Node* node) { | 1194 void InstructionSelector::VisitFloat64Sub(Node* node) { |
1195 // TODO(mbrandy): detect multiply-subtract | 1195 // TODO(mbrandy): detect multiply-subtract |
1196 PPCOperandGenerator g(this); | 1196 PPCOperandGenerator g(this); |
1197 Float64BinopMatcher m(node); | 1197 Float64BinopMatcher m(node); |
1198 if (m.left().IsMinusZero()) { | 1198 if (m.left().IsMinusZero()) { |
1199 if (m.right().IsFloat64RoundDown() && | 1199 if (m.right().IsFloat64RoundDown() && |
1200 CanCover(m.node(), m.right().node())) { | 1200 CanCover(m.node(), m.right().node())) { |
(...skipping 10 matching lines...) Expand all Loading... |
1211 } | 1211 } |
1212 Emit(kPPC_NegDouble, g.DefineAsRegister(node), | 1212 Emit(kPPC_NegDouble, g.DefineAsRegister(node), |
1213 g.UseRegister(m.right().node())); | 1213 g.UseRegister(m.right().node())); |
1214 return; | 1214 return; |
1215 } | 1215 } |
1216 VisitRRR(this, kPPC_SubDouble, node); | 1216 VisitRRR(this, kPPC_SubDouble, node); |
1217 } | 1217 } |
1218 | 1218 |
1219 | 1219 |
1220 void InstructionSelector::VisitFloat32Mul(Node* node) { | 1220 void InstructionSelector::VisitFloat32Mul(Node* node) { |
1221 VisitRRR(this, kPPC_MulDouble, node); | 1221 VisitRRR(this, kPPC_MulDouble | MiscField::encode(1), node); |
1222 } | 1222 } |
1223 | 1223 |
1224 | 1224 |
1225 void InstructionSelector::VisitFloat64Mul(Node* node) { | 1225 void InstructionSelector::VisitFloat64Mul(Node* node) { |
1226 // TODO(mbrandy): detect negate | 1226 // TODO(mbrandy): detect negate |
1227 VisitRRR(this, kPPC_MulDouble, node); | 1227 VisitRRR(this, kPPC_MulDouble, node); |
1228 } | 1228 } |
1229 | 1229 |
1230 | 1230 |
1231 void InstructionSelector::VisitFloat32Div(Node* node) { | 1231 void InstructionSelector::VisitFloat32Div(Node* node) { |
1232 VisitRRR(this, kPPC_DivDouble, node); | 1232 VisitRRR(this, kPPC_DivDouble | MiscField::encode(1), node); |
1233 } | 1233 } |
1234 | 1234 |
1235 | 1235 |
1236 void InstructionSelector::VisitFloat64Div(Node* node) { | 1236 void InstructionSelector::VisitFloat64Div(Node* node) { |
1237 VisitRRR(this, kPPC_DivDouble, node); | 1237 VisitRRR(this, kPPC_DivDouble, node); |
1238 } | 1238 } |
1239 | 1239 |
1240 | 1240 |
1241 void InstructionSelector::VisitFloat64Mod(Node* node) { | 1241 void InstructionSelector::VisitFloat64Mod(Node* node) { |
1242 PPCOperandGenerator g(this); | 1242 PPCOperandGenerator g(this); |
1243 Emit(kPPC_ModDouble, g.DefineAsFixed(node, d1), | 1243 Emit(kPPC_ModDouble, g.DefineAsFixed(node, d1), |
1244 g.UseFixed(node->InputAt(0), d1), | 1244 g.UseFixed(node->InputAt(0), d1), |
1245 g.UseFixed(node->InputAt(1), d2))->MarkAsCall(); | 1245 g.UseFixed(node->InputAt(1), d2))->MarkAsCall(); |
1246 } | 1246 } |
1247 | 1247 |
1248 | 1248 |
1249 void InstructionSelector::VisitFloat32Max(Node* node) { UNREACHABLE(); } | 1249 void InstructionSelector::VisitFloat32Max(Node* node) { UNREACHABLE(); } |
1250 | 1250 |
1251 | 1251 |
1252 void InstructionSelector::VisitFloat64Max(Node* node) { UNREACHABLE(); } | 1252 void InstructionSelector::VisitFloat64Max(Node* node) { UNREACHABLE(); } |
1253 | 1253 |
1254 | 1254 |
1255 void InstructionSelector::VisitFloat32Min(Node* node) { UNREACHABLE(); } | 1255 void InstructionSelector::VisitFloat32Min(Node* node) { UNREACHABLE(); } |
1256 | 1256 |
1257 | 1257 |
1258 void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); } | 1258 void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); } |
1259 | 1259 |
1260 | 1260 |
1261 void InstructionSelector::VisitFloat32Abs(Node* node) { | 1261 void InstructionSelector::VisitFloat32Abs(Node* node) { |
1262 VisitRR(this, kPPC_AbsDouble, node); | 1262 VisitRR(this, kPPC_AbsDouble | MiscField::encode(1), node); |
1263 } | 1263 } |
1264 | 1264 |
1265 | 1265 |
1266 void InstructionSelector::VisitFloat64Abs(Node* node) { | 1266 void InstructionSelector::VisitFloat64Abs(Node* node) { |
1267 VisitRR(this, kPPC_AbsDouble, node); | 1267 VisitRR(this, kPPC_AbsDouble, node); |
1268 } | 1268 } |
1269 | 1269 |
1270 | 1270 |
1271 void InstructionSelector::VisitFloat32Sqrt(Node* node) { | 1271 void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
1272 VisitRR(this, kPPC_SqrtDouble, node); | 1272 VisitRR(this, kPPC_SqrtDouble | MiscField::encode(1), node); |
1273 } | 1273 } |
1274 | 1274 |
1275 | 1275 |
1276 void InstructionSelector::VisitFloat64Sqrt(Node* node) { | 1276 void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
1277 VisitRR(this, kPPC_SqrtDouble, node); | 1277 VisitRR(this, kPPC_SqrtDouble, node); |
1278 } | 1278 } |
1279 | 1279 |
1280 | 1280 |
1281 void InstructionSelector::VisitFloat32RoundDown(Node* node) { | 1281 void InstructionSelector::VisitFloat32RoundDown(Node* node) { |
1282 VisitRR(this, kPPC_FloorDouble, node); | 1282 VisitRR(this, kPPC_FloorDouble | MiscField::encode(1), node); |
1283 } | 1283 } |
1284 | 1284 |
1285 | 1285 |
1286 void InstructionSelector::VisitFloat64RoundDown(Node* node) { | 1286 void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
1287 VisitRR(this, kPPC_FloorDouble, node); | 1287 VisitRR(this, kPPC_FloorDouble, node); |
1288 } | 1288 } |
1289 | 1289 |
1290 | 1290 |
1291 void InstructionSelector::VisitFloat32RoundUp(Node* node) { | 1291 void InstructionSelector::VisitFloat32RoundUp(Node* node) { |
1292 VisitRR(this, kPPC_CeilDouble, node); | 1292 VisitRR(this, kPPC_CeilDouble | MiscField::encode(1), node); |
1293 } | 1293 } |
1294 | 1294 |
1295 | 1295 |
1296 void InstructionSelector::VisitFloat64RoundUp(Node* node) { | 1296 void InstructionSelector::VisitFloat64RoundUp(Node* node) { |
1297 VisitRR(this, kPPC_CeilDouble, node); | 1297 VisitRR(this, kPPC_CeilDouble, node); |
1298 } | 1298 } |
1299 | 1299 |
1300 | 1300 |
1301 void InstructionSelector::VisitFloat32RoundTruncate(Node* node) { | 1301 void InstructionSelector::VisitFloat32RoundTruncate(Node* node) { |
1302 VisitRR(this, kPPC_TruncateDouble, node); | 1302 VisitRR(this, kPPC_TruncateDouble | MiscField::encode(1), node); |
1303 } | 1303 } |
1304 | 1304 |
1305 | 1305 |
1306 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 1306 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
1307 VisitRR(this, kPPC_TruncateDouble, node); | 1307 VisitRR(this, kPPC_TruncateDouble, node); |
1308 } | 1308 } |
1309 | 1309 |
1310 | 1310 |
1311 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 1311 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
1312 VisitRR(this, kPPC_RoundDouble, node); | 1312 VisitRR(this, kPPC_RoundDouble, node); |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1890 MachineOperatorBuilder::kFloat64RoundTruncate | | 1890 MachineOperatorBuilder::kFloat64RoundTruncate | |
1891 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1891 MachineOperatorBuilder::kFloat64RoundTiesAway | |
1892 MachineOperatorBuilder::kWord32Popcnt | | 1892 MachineOperatorBuilder::kWord32Popcnt | |
1893 MachineOperatorBuilder::kWord64Popcnt; | 1893 MachineOperatorBuilder::kWord64Popcnt; |
1894 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. | 1894 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. |
1895 } | 1895 } |
1896 | 1896 |
1897 } // namespace compiler | 1897 } // namespace compiler |
1898 } // namespace internal | 1898 } // namespace internal |
1899 } // namespace v8 | 1899 } // namespace v8 |
OLD | NEW |