Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(602)

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 1360603003: [arm64] Implement Float(32|64)(Min|Max) using fcsel. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698