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/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
955 } | 955 } |
956 case IrOpcode::kNumberShiftRightLogical: { | 956 case IrOpcode::kNumberShiftRightLogical: { |
957 Type* rhs_type = GetUpperBound(node->InputAt(1)); | 957 Type* rhs_type = GetUpperBound(node->InputAt(1)); |
958 VisitBinop(node, UseInfo::TruncatingWord32(), | 958 VisitBinop(node, UseInfo::TruncatingWord32(), |
959 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); | 959 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); |
960 if (lower()) { | 960 if (lower()) { |
961 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type); | 961 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type); |
962 } | 962 } |
963 break; | 963 break; |
964 } | 964 } |
| 965 case IrOpcode::kNumberFloor: { |
| 966 VisitUnop(node, UseInfo::Float64(), MachineRepresentation::kFloat64); |
| 967 if (lower()) DeferReplacement(node, lowering->Float64Floor(node)); |
| 968 break; |
| 969 } |
965 case IrOpcode::kNumberToInt32: { | 970 case IrOpcode::kNumberToInt32: { |
966 // Just change representation if necessary. | 971 // Just change representation if necessary. |
967 VisitUnop(node, UseInfo::TruncatingWord32(), | 972 VisitUnop(node, UseInfo::TruncatingWord32(), |
968 MachineRepresentation::kWord32); | 973 MachineRepresentation::kWord32); |
969 if (lower()) DeferReplacement(node, node->InputAt(0)); | 974 if (lower()) DeferReplacement(node, node->InputAt(0)); |
970 break; | 975 break; |
971 } | 976 } |
972 case IrOpcode::kNumberToUint32: { | 977 case IrOpcode::kNumberToUint32: { |
973 // Just change representation if necessary. | 978 // Just change representation if necessary. |
974 VisitUnop(node, UseInfo::TruncatingWord32(), | 979 VisitUnop(node, UseInfo::TruncatingWord32(), |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 } | 1517 } |
1513 | 1518 |
1514 | 1519 |
1515 void SimplifiedLowering::DoStoreBuffer(Node* node) { | 1520 void SimplifiedLowering::DoStoreBuffer(Node* node) { |
1516 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); | 1521 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); |
1517 MachineRepresentation const rep = | 1522 MachineRepresentation const rep = |
1518 BufferAccessOf(node->op()).machine_type().representation(); | 1523 BufferAccessOf(node->op()).machine_type().representation(); |
1519 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep)); | 1524 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep)); |
1520 } | 1525 } |
1521 | 1526 |
| 1527 Node* SimplifiedLowering::Float64Floor(Node* const node) { |
| 1528 Node* const one = jsgraph()->Float64Constant(1.0); |
| 1529 Node* const zero = jsgraph()->Float64Constant(0.0); |
| 1530 Node* const minus_one = jsgraph()->Float64Constant(-1.0); |
| 1531 Node* const minus_zero = jsgraph()->Float64Constant(-0.0); |
| 1532 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0); |
| 1533 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0); |
| 1534 Node* const input = node->InputAt(0); |
| 1535 |
| 1536 // Use fast hardware instruction if available. |
| 1537 if (machine()->Float64RoundDown().IsSupported()) { |
| 1538 return graph()->NewNode(machine()->Float64RoundDown().op(), input); |
| 1539 } |
| 1540 |
| 1541 // General case for floor. |
| 1542 // |
| 1543 // if 0.0 < input then |
| 1544 // if 2^52 <= input then |
| 1545 // input |
| 1546 // else |
| 1547 // let temp1 = (2^52 + input) - 2^52 in |
| 1548 // if input < temp1 then |
| 1549 // temp1 - 1 |
| 1550 // else |
| 1551 // temp1 |
| 1552 // else |
| 1553 // if input == 0 then |
| 1554 // input |
| 1555 // else |
| 1556 // if input <= -2^52 then |
| 1557 // input |
| 1558 // else |
| 1559 // let temp1 = -0 - input in |
| 1560 // let temp2 = (2^52 + temp1) - 2^52 in |
| 1561 // if temp2 < temp1 then |
| 1562 // -1 - temp2 |
| 1563 // else |
| 1564 // -0 - temp2 |
| 1565 // |
| 1566 // Note: We do not use the Diamond helper class here, because it really hurts |
| 1567 // readability with nested diamonds. |
| 1568 |
| 1569 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); |
| 1570 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, |
| 1571 graph()->start()); |
| 1572 |
| 1573 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1574 Node* vtrue0; |
| 1575 { |
| 1576 Node* check1 = |
| 1577 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); |
| 1578 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); |
| 1579 |
| 1580 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1581 Node* vtrue1 = input; |
| 1582 |
| 1583 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1584 Node* vfalse1; |
| 1585 { |
| 1586 Node* temp1 = graph()->NewNode( |
| 1587 machine()->Float64Sub(), |
| 1588 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); |
| 1589 vfalse1 = graph()->NewNode( |
| 1590 common()->Select(MachineRepresentation::kFloat64), |
| 1591 graph()->NewNode(machine()->Float64LessThan(), input, temp1), |
| 1592 graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1); |
| 1593 } |
| 1594 |
| 1595 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1596 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 1597 vtrue1, vfalse1, if_true0); |
| 1598 } |
| 1599 |
| 1600 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1601 Node* vfalse0; |
| 1602 { |
| 1603 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); |
| 1604 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 1605 check1, if_false0); |
| 1606 |
| 1607 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1608 Node* vtrue1 = input; |
| 1609 |
| 1610 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1611 Node* vfalse1; |
| 1612 { |
| 1613 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), |
| 1614 input, minus_two_52); |
| 1615 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 1616 check2, if_false1); |
| 1617 |
| 1618 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
| 1619 Node* vtrue2 = input; |
| 1620 |
| 1621 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
| 1622 Node* vfalse2; |
| 1623 { |
| 1624 Node* temp1 = |
| 1625 graph()->NewNode(machine()->Float64Sub(), minus_zero, input); |
| 1626 Node* temp2 = graph()->NewNode( |
| 1627 machine()->Float64Sub(), |
| 1628 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52); |
| 1629 vfalse2 = graph()->NewNode( |
| 1630 common()->Select(MachineRepresentation::kFloat64), |
| 1631 graph()->NewNode(machine()->Float64LessThan(), temp2, temp1), |
| 1632 graph()->NewNode(machine()->Float64Sub(), minus_one, temp2), |
| 1633 graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2)); |
| 1634 } |
| 1635 |
| 1636 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
| 1637 vfalse1 = |
| 1638 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 1639 vtrue2, vfalse2, if_false1); |
| 1640 } |
| 1641 |
| 1642 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1643 vfalse0 = |
| 1644 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 1645 vtrue1, vfalse1, if_false0); |
| 1646 } |
| 1647 |
| 1648 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1649 return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 1650 vtrue0, vfalse0, merge0); |
| 1651 } |
| 1652 |
1522 Node* SimplifiedLowering::Int32Div(Node* const node) { | 1653 Node* SimplifiedLowering::Int32Div(Node* const node) { |
1523 Int32BinopMatcher m(node); | 1654 Int32BinopMatcher m(node); |
1524 Node* const zero = jsgraph()->Int32Constant(0); | 1655 Node* const zero = jsgraph()->Int32Constant(0); |
1525 Node* const minus_one = jsgraph()->Int32Constant(-1); | 1656 Node* const minus_one = jsgraph()->Int32Constant(-1); |
1526 Node* const lhs = m.left().node(); | 1657 Node* const lhs = m.left().node(); |
1527 Node* const rhs = m.right().node(); | 1658 Node* const rhs = m.right().node(); |
1528 | 1659 |
1529 if (m.right().Is(-1)) { | 1660 if (m.right().Is(-1)) { |
1530 return graph()->NewNode(machine()->Int32Sub(), zero, lhs); | 1661 return graph()->NewNode(machine()->Int32Sub(), zero, lhs); |
1531 } else if (m.right().Is(0)) { | 1662 } else if (m.right().Is(0)) { |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { | 1908 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { |
1778 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, | 1909 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, |
1779 jsgraph()->Int32Constant(0x1f))); | 1910 jsgraph()->Int32Constant(0x1f))); |
1780 } | 1911 } |
1781 NodeProperties::ChangeOp(node, op); | 1912 NodeProperties::ChangeOp(node, op); |
1782 } | 1913 } |
1783 | 1914 |
1784 } // namespace compiler | 1915 } // namespace compiler |
1785 } // namespace internal | 1916 } // namespace internal |
1786 } // namespace v8 | 1917 } // namespace v8 |
OLD | NEW |