| 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 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | 1260 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |
| 1261 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | 1261 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
| 1262 &buffer.instruction_args.front())->MarkAsCall(); | 1262 &buffer.instruction_args.front())->MarkAsCall(); |
| 1263 Emit(kArchRet, 0, nullptr, output_count, outputs); | 1263 Emit(kArchRet, 0, nullptr, output_count, outputs); |
| 1264 } | 1264 } |
| 1265 } | 1265 } |
| 1266 | 1266 |
| 1267 | 1267 |
| 1268 namespace { | 1268 namespace { |
| 1269 | 1269 |
| 1270 // Shared routine for multiple compare operations. |
| 1271 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1272 InstructionOperand left, InstructionOperand right, |
| 1273 FlagsContinuation* cont) { |
| 1274 ArmOperandGenerator g(selector); |
| 1275 opcode = cont->Encode(opcode); |
| 1276 if (cont->IsBranch()) { |
| 1277 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1278 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1279 } else { |
| 1280 DCHECK(cont->IsSet()); |
| 1281 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
| 1282 } |
| 1283 } |
| 1284 |
| 1285 |
| 1270 // Shared routine for multiple float32 compare operations. | 1286 // Shared routine for multiple float32 compare operations. |
| 1271 void VisitFloat32Compare(InstructionSelector* selector, Node* node, | 1287 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
| 1272 FlagsContinuation* cont) { | 1288 FlagsContinuation* cont) { |
| 1273 ArmOperandGenerator g(selector); | 1289 ArmOperandGenerator g(selector); |
| 1274 Float32BinopMatcher m(node); | 1290 Float32BinopMatcher m(node); |
| 1275 InstructionOperand rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node()) | 1291 if (m.right().Is(0.0f)) { |
| 1276 : g.UseRegister(m.right().node()); | 1292 VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()), |
| 1277 if (cont->IsBranch()) { | 1293 g.UseImmediate(m.right().node()), cont); |
| 1278 selector->Emit(cont->Encode(kArmVcmpF32), g.NoOutput(), | 1294 } else if (m.left().Is(0.0f)) { |
| 1279 g.UseRegister(m.left().node()), rhs, | 1295 cont->Commute(); |
| 1280 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1296 VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.right().node()), |
| 1297 g.UseImmediate(m.left().node()), cont); |
| 1281 } else { | 1298 } else { |
| 1282 DCHECK(cont->IsSet()); | 1299 VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()), |
| 1283 selector->Emit(cont->Encode(kArmVcmpF32), | 1300 g.UseRegister(m.right().node()), cont); |
| 1284 g.DefineAsRegister(cont->result()), | |
| 1285 g.UseRegister(m.left().node()), rhs); | |
| 1286 } | 1301 } |
| 1287 } | 1302 } |
| 1288 | 1303 |
| 1289 | 1304 |
| 1290 // Shared routine for multiple float64 compare operations. | 1305 // Shared routine for multiple float64 compare operations. |
| 1291 void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1306 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
| 1292 FlagsContinuation* cont) { | 1307 FlagsContinuation* cont) { |
| 1293 ArmOperandGenerator g(selector); | 1308 ArmOperandGenerator g(selector); |
| 1294 Float64BinopMatcher m(node); | 1309 Float64BinopMatcher m(node); |
| 1295 InstructionOperand rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node()) | 1310 if (m.right().Is(0.0)) { |
| 1296 : g.UseRegister(m.right().node()); | 1311 VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()), |
| 1297 if (cont->IsBranch()) { | 1312 g.UseImmediate(m.right().node()), cont); |
| 1298 selector->Emit(cont->Encode(kArmVcmpF64), g.NoOutput(), | 1313 } else if (m.left().Is(0.0)) { |
| 1299 g.UseRegister(m.left().node()), rhs, | 1314 cont->Commute(); |
| 1300 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1315 VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.right().node()), |
| 1316 g.UseImmediate(m.left().node()), cont); |
| 1301 } else { | 1317 } else { |
| 1302 DCHECK(cont->IsSet()); | 1318 VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()), |
| 1303 selector->Emit(cont->Encode(kArmVcmpF64), | 1319 g.UseRegister(m.right().node()), cont); |
| 1304 g.DefineAsRegister(cont->result()), | |
| 1305 g.UseRegister(m.left().node()), rhs); | |
| 1306 } | 1320 } |
| 1307 } | 1321 } |
| 1308 | 1322 |
| 1309 | 1323 |
| 1310 // Shared routine for multiple word compare operations. | 1324 // Shared routine for multiple word compare operations. |
| 1311 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1325 void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 1312 InstructionCode opcode, FlagsContinuation* cont) { | 1326 InstructionCode opcode, FlagsContinuation* cont) { |
| 1313 ArmOperandGenerator g(selector); | 1327 ArmOperandGenerator g(selector); |
| 1314 Int32BinopMatcher m(node); | 1328 Int32BinopMatcher m(node); |
| 1315 InstructionOperand inputs[5]; | 1329 InstructionOperand inputs[5]; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1382 case IrOpcode::kUint32LessThan: | 1396 case IrOpcode::kUint32LessThan: |
| 1383 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1397 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1384 return VisitWordCompare(selector, value, cont); | 1398 return VisitWordCompare(selector, value, cont); |
| 1385 case IrOpcode::kUint32LessThanOrEqual: | 1399 case IrOpcode::kUint32LessThanOrEqual: |
| 1386 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1400 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1387 return VisitWordCompare(selector, value, cont); | 1401 return VisitWordCompare(selector, value, cont); |
| 1388 case IrOpcode::kFloat32Equal: | 1402 case IrOpcode::kFloat32Equal: |
| 1389 cont->OverwriteAndNegateIfEqual(kEqual); | 1403 cont->OverwriteAndNegateIfEqual(kEqual); |
| 1390 return VisitFloat32Compare(selector, value, cont); | 1404 return VisitFloat32Compare(selector, value, cont); |
| 1391 case IrOpcode::kFloat32LessThan: | 1405 case IrOpcode::kFloat32LessThan: |
| 1392 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1406 cont->OverwriteAndNegateIfEqual(kFloatLessThan); |
| 1393 return VisitFloat32Compare(selector, value, cont); | 1407 return VisitFloat32Compare(selector, value, cont); |
| 1394 case IrOpcode::kFloat32LessThanOrEqual: | 1408 case IrOpcode::kFloat32LessThanOrEqual: |
| 1395 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1409 cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual); |
| 1396 return VisitFloat32Compare(selector, value, cont); | 1410 return VisitFloat32Compare(selector, value, cont); |
| 1397 case IrOpcode::kFloat64Equal: | 1411 case IrOpcode::kFloat64Equal: |
| 1398 cont->OverwriteAndNegateIfEqual(kEqual); | 1412 cont->OverwriteAndNegateIfEqual(kEqual); |
| 1399 return VisitFloat64Compare(selector, value, cont); | 1413 return VisitFloat64Compare(selector, value, cont); |
| 1400 case IrOpcode::kFloat64LessThan: | 1414 case IrOpcode::kFloat64LessThan: |
| 1401 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1415 cont->OverwriteAndNegateIfEqual(kFloatLessThan); |
| 1402 return VisitFloat64Compare(selector, value, cont); | 1416 return VisitFloat64Compare(selector, value, cont); |
| 1403 case IrOpcode::kFloat64LessThanOrEqual: | 1417 case IrOpcode::kFloat64LessThanOrEqual: |
| 1404 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1418 cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual); |
| 1405 return VisitFloat64Compare(selector, value, cont); | 1419 return VisitFloat64Compare(selector, value, cont); |
| 1406 case IrOpcode::kProjection: | 1420 case IrOpcode::kProjection: |
| 1407 // Check if this is the overflow output projection of an | 1421 // Check if this is the overflow output projection of an |
| 1408 // <Operation>WithOverflow node. | 1422 // <Operation>WithOverflow node. |
| 1409 if (ProjectionIndexOf(value->op()) == 1u) { | 1423 if (ProjectionIndexOf(value->op()) == 1u) { |
| 1410 // We cannot combine the <Operation>WithOverflow with this branch | 1424 // We cannot combine the <Operation>WithOverflow with this branch |
| 1411 // unless the 0th projection (the use of the actual value of the | 1425 // unless the 0th projection (the use of the actual value of the |
| 1412 // <Operation> is either NULL, which means there's no use of the | 1426 // <Operation> is either NULL, which means there's no use of the |
| 1413 // actual value, or was already defined, which means it is scheduled | 1427 // actual value, or was already defined, which means it is scheduled |
| 1414 // *AFTER* this branch). | 1428 // *AFTER* this branch). |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1558 } | 1572 } |
| 1559 | 1573 |
| 1560 | 1574 |
| 1561 void InstructionSelector::VisitFloat32Equal(Node* node) { | 1575 void InstructionSelector::VisitFloat32Equal(Node* node) { |
| 1562 FlagsContinuation cont(kEqual, node); | 1576 FlagsContinuation cont(kEqual, node); |
| 1563 VisitFloat32Compare(this, node, &cont); | 1577 VisitFloat32Compare(this, node, &cont); |
| 1564 } | 1578 } |
| 1565 | 1579 |
| 1566 | 1580 |
| 1567 void InstructionSelector::VisitFloat32LessThan(Node* node) { | 1581 void InstructionSelector::VisitFloat32LessThan(Node* node) { |
| 1568 FlagsContinuation cont(kUnsignedLessThan, node); | 1582 FlagsContinuation cont(kFloatLessThan, node); |
| 1569 VisitFloat32Compare(this, node, &cont); | 1583 VisitFloat32Compare(this, node, &cont); |
| 1570 } | 1584 } |
| 1571 | 1585 |
| 1572 | 1586 |
| 1573 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { | 1587 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
| 1574 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); | 1588 FlagsContinuation cont(kFloatLessThanOrEqual, node); |
| 1575 VisitFloat32Compare(this, node, &cont); | 1589 VisitFloat32Compare(this, node, &cont); |
| 1576 } | 1590 } |
| 1577 | 1591 |
| 1578 | 1592 |
| 1579 void InstructionSelector::VisitFloat64Equal(Node* node) { | 1593 void InstructionSelector::VisitFloat64Equal(Node* node) { |
| 1580 FlagsContinuation cont(kEqual, node); | 1594 FlagsContinuation cont(kEqual, node); |
| 1581 VisitFloat64Compare(this, node, &cont); | 1595 VisitFloat64Compare(this, node, &cont); |
| 1582 } | 1596 } |
| 1583 | 1597 |
| 1584 | 1598 |
| 1585 void InstructionSelector::VisitFloat64LessThan(Node* node) { | 1599 void InstructionSelector::VisitFloat64LessThan(Node* node) { |
| 1586 FlagsContinuation cont(kUnsignedLessThan, node); | 1600 FlagsContinuation cont(kFloatLessThan, node); |
| 1587 VisitFloat64Compare(this, node, &cont); | 1601 VisitFloat64Compare(this, node, &cont); |
| 1588 } | 1602 } |
| 1589 | 1603 |
| 1590 | 1604 |
| 1591 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { | 1605 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
| 1592 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); | 1606 FlagsContinuation cont(kFloatLessThanOrEqual, node); |
| 1593 VisitFloat64Compare(this, node, &cont); | 1607 VisitFloat64Compare(this, node, &cont); |
| 1594 } | 1608 } |
| 1595 | 1609 |
| 1596 | 1610 |
| 1597 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { | 1611 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
| 1598 VisitRR(this, kArmVmovLowU32F64, node); | 1612 VisitRR(this, kArmVmovLowU32F64, node); |
| 1599 } | 1613 } |
| 1600 | 1614 |
| 1601 | 1615 |
| 1602 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { | 1616 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1646 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1660 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
| 1647 MachineOperatorBuilder::kFloat64RoundTruncate | | 1661 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1648 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1662 MachineOperatorBuilder::kFloat64RoundTiesAway; |
| 1649 } | 1663 } |
| 1650 return flags; | 1664 return flags; |
| 1651 } | 1665 } |
| 1652 | 1666 |
| 1653 } // namespace compiler | 1667 } // namespace compiler |
| 1654 } // namespace internal | 1668 } // namespace internal |
| 1655 } // namespace v8 | 1669 } // namespace v8 |
| OLD | NEW |