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 |