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/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 | 1336 |
1337 | 1337 |
1338 void InstructionSelector::VisitFloat64Mod(Node* node) { | 1338 void InstructionSelector::VisitFloat64Mod(Node* node) { |
1339 Arm64OperandGenerator g(this); | 1339 Arm64OperandGenerator g(this); |
1340 Emit(kArm64Float64Mod, g.DefineAsFixed(node, d0), | 1340 Emit(kArm64Float64Mod, g.DefineAsFixed(node, d0), |
1341 g.UseFixed(node->InputAt(0), d0), | 1341 g.UseFixed(node->InputAt(0), d0), |
1342 g.UseFixed(node->InputAt(1), d1))->MarkAsCall(); | 1342 g.UseFixed(node->InputAt(1), d1))->MarkAsCall(); |
1343 } | 1343 } |
1344 | 1344 |
1345 | 1345 |
1346 void InstructionSelector::VisitFloat32Max(Node* node) { UNREACHABLE(); } | |
1347 | |
1348 | |
1349 void InstructionSelector::VisitFloat64Max(Node* node) { UNREACHABLE(); } | |
1350 | |
1351 | |
1352 void InstructionSelector::VisitFloat32Min(Node* node) { UNREACHABLE(); } | |
1353 | |
1354 | |
1355 void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); } | |
1356 | |
1357 | |
1358 void InstructionSelector::VisitFloat32Abs(Node* node) { | 1346 void InstructionSelector::VisitFloat32Abs(Node* node) { |
1359 VisitRR(this, kArm64Float32Abs, node); | 1347 VisitRR(this, kArm64Float32Abs, node); |
1360 } | 1348 } |
1361 | 1349 |
1362 | 1350 |
1363 void InstructionSelector::VisitFloat64Abs(Node* node) { | 1351 void InstructionSelector::VisitFloat64Abs(Node* node) { |
1364 VisitRR(this, kArm64Float64Abs, node); | 1352 VisitRR(this, kArm64Float64Abs, node); |
1365 } | 1353 } |
1366 | 1354 |
1367 | 1355 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 if (cont->IsBranch()) { | 1582 if (cont->IsBranch()) { |
1595 selector->Emit(opcode, g.NoOutput(), left, right, | 1583 selector->Emit(opcode, g.NoOutput(), left, right, |
1596 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1584 g.Label(cont->true_block()), g.Label(cont->false_block())); |
1597 } else { | 1585 } else { |
1598 DCHECK(cont->IsSet()); | 1586 DCHECK(cont->IsSet()); |
1599 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 1587 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
1600 } | 1588 } |
1601 } | 1589 } |
1602 | 1590 |
1603 | 1591 |
| 1592 // Shared routine for multiple compare-and-select operations. |
| 1593 void VisitCompareAndSelect(InstructionSelector* selector, |
| 1594 InstructionCode opcode, InstructionOperand cmp_left, |
| 1595 InstructionOperand cmp_right, |
| 1596 InstructionOperand if_true, |
| 1597 InstructionOperand if_false, |
| 1598 FlagsContinuation* cont) { |
| 1599 Arm64OperandGenerator g(selector); |
| 1600 opcode = cont->Encode(opcode); |
| 1601 DCHECK(cont->IsSelect()); |
| 1602 selector->Emit(opcode, g.DefineAsRegister(cont->result()), cmp_left, |
| 1603 cmp_right, if_true, if_false); |
| 1604 } |
| 1605 |
| 1606 |
1604 // Shared routine for multiple word compare operations. | 1607 // Shared routine for multiple word compare operations. |
1605 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1608 void VisitWordCompare(InstructionSelector* selector, Node* node, |
1606 InstructionCode opcode, FlagsContinuation* cont, | 1609 InstructionCode opcode, FlagsContinuation* cont, |
1607 bool commutative, ImmediateMode immediate_mode) { | 1610 bool commutative, ImmediateMode immediate_mode) { |
1608 Arm64OperandGenerator g(selector); | 1611 Arm64OperandGenerator g(selector); |
1609 Node* left = node->InputAt(0); | 1612 Node* left = node->InputAt(0); |
1610 Node* right = node->InputAt(1); | 1613 Node* right = node->InputAt(1); |
1611 | 1614 |
1612 // Match immediates on left or right side of comparison. | 1615 // Match immediates on left or right side of comparison. |
1613 if (g.CanBeImmediate(right, immediate_mode)) { | 1616 if (g.CanBeImmediate(right, immediate_mode)) { |
(...skipping 30 matching lines...) Expand all Loading... |
1644 VisitWordTest(selector, node, kArm64Tst32, cont); | 1647 VisitWordTest(selector, node, kArm64Tst32, cont); |
1645 } | 1648 } |
1646 | 1649 |
1647 | 1650 |
1648 void VisitWord64Test(InstructionSelector* selector, Node* node, | 1651 void VisitWord64Test(InstructionSelector* selector, Node* node, |
1649 FlagsContinuation* cont) { | 1652 FlagsContinuation* cont) { |
1650 VisitWordTest(selector, node, kArm64Tst, cont); | 1653 VisitWordTest(selector, node, kArm64Tst, cont); |
1651 } | 1654 } |
1652 | 1655 |
1653 | 1656 |
1654 // Shared routine for multiple float64 compare operations. | 1657 // Shared routine for multiple float32 compare operations. |
1655 void VisitFloat32Compare(InstructionSelector* selector, Node* node, | 1658 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
1656 FlagsContinuation* cont) { | 1659 FlagsContinuation* cont) { |
1657 Arm64OperandGenerator g(selector); | 1660 Arm64OperandGenerator g(selector); |
1658 Float32BinopMatcher m(node); | 1661 Float32BinopMatcher m(node); |
1659 if (m.right().Is(0.0f)) { | 1662 if (m.right().Is(0.0f)) { |
1660 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()), | 1663 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()), |
1661 g.UseImmediate(m.right().node()), cont); | 1664 g.UseImmediate(m.right().node()), cont); |
1662 } else { | 1665 } else { |
1663 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()), | 1666 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()), |
1664 g.UseRegister(m.right().node()), cont); | 1667 g.UseRegister(m.right().node()), cont); |
1665 } | 1668 } |
1666 } | 1669 } |
1667 | 1670 |
1668 | 1671 |
| 1672 void VisitFloat32CompareAndSelect(InstructionSelector* selector, Node* node, |
| 1673 InstructionCode opcode, Node* cmp_left, |
| 1674 Node* cmp_right, Node* sel_true, |
| 1675 Node* sel_false, FlagsContinuation* cont) { |
| 1676 // (cmp_left <op> cmp_right) ? sel_true : sel_false |
| 1677 Arm64OperandGenerator g(selector); |
| 1678 if (Float32Matcher(cmp_right).Is(0.0f)) { |
| 1679 VisitCompareAndSelect(selector, opcode, g.UseRegister(cmp_left), |
| 1680 g.UseImmediate(cmp_right), g.UseRegister(sel_true), |
| 1681 g.UseRegister(sel_false), cont); |
| 1682 } else { |
| 1683 VisitCompareAndSelect(selector, opcode, g.UseRegister(cmp_left), |
| 1684 g.UseRegister(cmp_right), g.UseRegister(sel_true), |
| 1685 g.UseRegister(sel_false), cont); |
| 1686 } |
| 1687 } |
| 1688 |
| 1689 |
1669 // Shared routine for multiple float64 compare operations. | 1690 // Shared routine for multiple float64 compare operations. |
1670 void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1691 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
1671 FlagsContinuation* cont) { | 1692 FlagsContinuation* cont) { |
1672 Arm64OperandGenerator g(selector); | 1693 Arm64OperandGenerator g(selector); |
1673 Float64BinopMatcher m(node); | 1694 Float64BinopMatcher m(node); |
1674 if (m.right().Is(0.0)) { | 1695 if (m.right().Is(0.0)) { |
1675 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), | 1696 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), |
1676 g.UseImmediate(m.right().node()), cont); | 1697 g.UseImmediate(m.right().node()), cont); |
1677 } else { | 1698 } else { |
1678 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), | 1699 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), |
1679 g.UseRegister(m.right().node()), cont); | 1700 g.UseRegister(m.right().node()), cont); |
1680 } | 1701 } |
1681 } | 1702 } |
1682 | 1703 |
| 1704 |
| 1705 void VisitFloat64CompareAndSelect(InstructionSelector* selector, Node* node, |
| 1706 InstructionCode opcode, Node* cmp_left, |
| 1707 Node* cmp_right, Node* sel_true, |
| 1708 Node* sel_false, FlagsContinuation* cont) { |
| 1709 // (cmp_left <op> cmp_right) ? sel_true : sel_false |
| 1710 Arm64OperandGenerator g(selector); |
| 1711 if (Float64Matcher(cmp_right).Is(0.0)) { |
| 1712 VisitCompareAndSelect(selector, opcode, g.UseRegister(cmp_left), |
| 1713 g.UseImmediate(cmp_right), g.UseRegister(sel_true), |
| 1714 g.UseRegister(sel_false), cont); |
| 1715 } else { |
| 1716 VisitCompareAndSelect(selector, opcode, g.UseRegister(cmp_left), |
| 1717 g.UseRegister(cmp_right), g.UseRegister(sel_true), |
| 1718 g.UseRegister(sel_false), cont); |
| 1719 } |
| 1720 } |
| 1721 |
1683 } // namespace | 1722 } // namespace |
1684 | 1723 |
1685 | 1724 |
1686 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1725 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
1687 BasicBlock* fbranch) { | 1726 BasicBlock* fbranch) { |
1688 OperandGenerator g(this); | 1727 OperandGenerator g(this); |
1689 Node* user = branch; | 1728 Node* user = branch; |
1690 Node* value = branch->InputAt(0); | 1729 Node* value = branch->InputAt(0); |
1691 | 1730 |
1692 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 1731 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2020 VisitFloat64Compare(this, node, &cont); | 2059 VisitFloat64Compare(this, node, &cont); |
2021 } | 2060 } |
2022 | 2061 |
2023 | 2062 |
2024 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { | 2063 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
2025 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); | 2064 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); |
2026 VisitFloat64Compare(this, node, &cont); | 2065 VisitFloat64Compare(this, node, &cont); |
2027 } | 2066 } |
2028 | 2067 |
2029 | 2068 |
| 2069 void InstructionSelector::VisitFloat32Max(Node* node) { |
| 2070 // (b < a) ? a : b |
| 2071 FlagsContinuation cont(kUnsignedLessThan, node, kFlags_select); |
| 2072 VisitFloat32CompareAndSelect(this, node, kArm64Float32CmpAndFloat32Sel, |
| 2073 node->InputAt(1), node->InputAt(0), |
| 2074 node->InputAt(0), node->InputAt(1), &cont); |
| 2075 } |
| 2076 |
| 2077 |
| 2078 void InstructionSelector::VisitFloat32Min(Node* node) { |
| 2079 // (a < b) ? a : b |
| 2080 FlagsContinuation cont(kUnsignedLessThan, node, kFlags_select); |
| 2081 VisitFloat32CompareAndSelect(this, node, kArm64Float32CmpAndFloat32Sel, |
| 2082 node->InputAt(0), node->InputAt(1), |
| 2083 node->InputAt(0), node->InputAt(1), &cont); |
| 2084 } |
| 2085 |
| 2086 |
| 2087 void InstructionSelector::VisitFloat64Max(Node* node) { |
| 2088 // (b < a) ? a : b |
| 2089 FlagsContinuation cont(kUnsignedLessThan, node, kFlags_select); |
| 2090 VisitFloat64CompareAndSelect(this, node, kArm64Float64CmpAndFloat64Sel, |
| 2091 node->InputAt(1), node->InputAt(0), |
| 2092 node->InputAt(0), node->InputAt(1), &cont); |
| 2093 } |
| 2094 |
| 2095 |
| 2096 void InstructionSelector::VisitFloat64Min(Node* node) { |
| 2097 // (a < b) ? a : b |
| 2098 FlagsContinuation cont(kUnsignedLessThan, node, kFlags_select); |
| 2099 VisitFloat64CompareAndSelect(this, node, kArm64Float64CmpAndFloat64Sel, |
| 2100 node->InputAt(0), node->InputAt(1), |
| 2101 node->InputAt(0), node->InputAt(1), &cont); |
| 2102 } |
| 2103 |
| 2104 |
2030 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { | 2105 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
2031 Arm64OperandGenerator g(this); | 2106 Arm64OperandGenerator g(this); |
2032 Emit(kArm64Float64ExtractLowWord32, g.DefineAsRegister(node), | 2107 Emit(kArm64Float64ExtractLowWord32, g.DefineAsRegister(node), |
2033 g.UseRegister(node->InputAt(0))); | 2108 g.UseRegister(node->InputAt(0))); |
2034 } | 2109 } |
2035 | 2110 |
2036 | 2111 |
2037 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { | 2112 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { |
2038 Arm64OperandGenerator g(this); | 2113 Arm64OperandGenerator g(this); |
2039 Emit(kArm64Float64ExtractHighWord32, g.DefineAsRegister(node), | 2114 Emit(kArm64Float64ExtractHighWord32, g.DefineAsRegister(node), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 return; | 2147 return; |
2073 } | 2148 } |
2074 Emit(kArm64Float64InsertHighWord32, g.DefineAsRegister(node), | 2149 Emit(kArm64Float64InsertHighWord32, g.DefineAsRegister(node), |
2075 g.UseRegister(left), g.UseRegister(right)); | 2150 g.UseRegister(left), g.UseRegister(right)); |
2076 } | 2151 } |
2077 | 2152 |
2078 | 2153 |
2079 // static | 2154 // static |
2080 MachineOperatorBuilder::Flags | 2155 MachineOperatorBuilder::Flags |
2081 InstructionSelector::SupportedMachineOperatorFlags() { | 2156 InstructionSelector::SupportedMachineOperatorFlags() { |
2082 return MachineOperatorBuilder::kFloat64RoundDown | | 2157 return MachineOperatorBuilder::kFloat32Max | |
| 2158 MachineOperatorBuilder::kFloat32Min | |
| 2159 MachineOperatorBuilder::kFloat64Max | |
| 2160 MachineOperatorBuilder::kFloat64Min | |
| 2161 MachineOperatorBuilder::kFloat64RoundDown | |
2083 MachineOperatorBuilder::kFloat64RoundTruncate | | 2162 MachineOperatorBuilder::kFloat64RoundTruncate | |
2084 MachineOperatorBuilder::kFloat64RoundTiesAway | | 2163 MachineOperatorBuilder::kFloat64RoundTiesAway | |
2085 MachineOperatorBuilder::kWord32ShiftIsSafe | | 2164 MachineOperatorBuilder::kWord32ShiftIsSafe | |
2086 MachineOperatorBuilder::kInt32DivIsSafe | | 2165 MachineOperatorBuilder::kInt32DivIsSafe | |
2087 MachineOperatorBuilder::kUint32DivIsSafe; | 2166 MachineOperatorBuilder::kUint32DivIsSafe; |
2088 } | 2167 } |
2089 | 2168 |
2090 } // namespace compiler | 2169 } // namespace compiler |
2091 } // namespace internal | 2170 } // namespace internal |
2092 } // namespace v8 | 2171 } // namespace v8 |
OLD | NEW |