| 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 |