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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 X64OperandGenerator g(selector); | 1574 X64OperandGenerator g(selector); |
1575 if (commutative && g.CanBeBetterLeftOperand(right)) { | 1575 if (commutative && g.CanBeBetterLeftOperand(right)) { |
1576 std::swap(left, right); | 1576 std::swap(left, right); |
1577 } | 1577 } |
1578 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); | 1578 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); |
1579 } | 1579 } |
1580 | 1580 |
1581 // Tries to match the size of the given opcode to that of the operands, if | 1581 // Tries to match the size of the given opcode to that of the operands, if |
1582 // possible. | 1582 // possible. |
1583 InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, | 1583 InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, |
1584 Node* right) { | 1584 Node* right, FlagsContinuation* cont) { |
1585 if (opcode != kX64Cmp32 && opcode != kX64Test32) { | |
1586 return opcode; | |
1587 } | |
1588 // Currently, if one of the two operands is not a Load, we don't know what its | 1585 // Currently, if one of the two operands is not a Load, we don't know what its |
1589 // machine representation is, so we bail out. | 1586 // machine representation is, so we bail out. |
1590 // TODO(epertoso): we can probably get some size information out of immediates | 1587 // TODO(epertoso): we can probably get some size information out of immediates |
1591 // and phi nodes. | 1588 // and phi nodes. |
1592 if (left->opcode() != IrOpcode::kLoad || right->opcode() != IrOpcode::kLoad) { | 1589 if (left->opcode() != IrOpcode::kLoad || right->opcode() != IrOpcode::kLoad) { |
1593 return opcode; | 1590 return opcode; |
1594 } | 1591 } |
1595 // If the load representations don't match, both operands will be | 1592 // If the load representations don't match, both operands will be |
1596 // zero/sign-extended to 32bit. | 1593 // zero/sign-extended to 32bit. |
1597 LoadRepresentation left_representation = LoadRepresentationOf(left->op()); | 1594 MachineType left_type = LoadRepresentationOf(left->op()); |
1598 if (left_representation != LoadRepresentationOf(right->op())) { | 1595 MachineType right_type = LoadRepresentationOf(right->op()); |
1599 return opcode; | 1596 if (left_type == right_type) { |
| 1597 switch (left_type.representation()) { |
| 1598 case MachineRepresentation::kBit: |
| 1599 case MachineRepresentation::kWord8: { |
| 1600 if (opcode == kX64Test32) return kX64Test8; |
| 1601 if (opcode == kX64Cmp32) { |
| 1602 if (left_type.semantic() == MachineSemantic::kUint32) { |
| 1603 cont->OverwriteUnsignedIfSigned(); |
| 1604 } else { |
| 1605 CHECK_EQ(MachineSemantic::kInt32, left_type.semantic()); |
| 1606 } |
| 1607 return kX64Cmp8; |
| 1608 } |
| 1609 break; |
| 1610 } |
| 1611 case MachineRepresentation::kWord16: |
| 1612 if (opcode == kX64Test32) return kX64Test16; |
| 1613 if (opcode == kX64Cmp32) { |
| 1614 if (left_type.semantic() == MachineSemantic::kUint32) { |
| 1615 cont->OverwriteUnsignedIfSigned(); |
| 1616 } else { |
| 1617 CHECK_EQ(MachineSemantic::kInt32, left_type.semantic()); |
| 1618 } |
| 1619 return kX64Cmp16; |
| 1620 } |
| 1621 break; |
| 1622 default: |
| 1623 break; |
| 1624 } |
1600 } | 1625 } |
1601 switch (left_representation.representation()) { | 1626 return opcode; |
1602 case MachineRepresentation::kBit: | |
1603 case MachineRepresentation::kWord8: | |
1604 return opcode == kX64Cmp32 ? kX64Cmp8 : kX64Test8; | |
1605 case MachineRepresentation::kWord16: | |
1606 return opcode == kX64Cmp32 ? kX64Cmp16 : kX64Test16; | |
1607 default: | |
1608 return opcode; | |
1609 } | |
1610 } | 1627 } |
1611 | 1628 |
1612 // Shared routine for multiple word compare operations. | 1629 // Shared routine for multiple word compare operations. |
1613 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1630 void VisitWordCompare(InstructionSelector* selector, Node* node, |
1614 InstructionCode opcode, FlagsContinuation* cont) { | 1631 InstructionCode opcode, FlagsContinuation* cont) { |
1615 X64OperandGenerator g(selector); | 1632 X64OperandGenerator g(selector); |
1616 Node* left = node->InputAt(0); | 1633 Node* left = node->InputAt(0); |
1617 Node* right = node->InputAt(1); | 1634 Node* right = node->InputAt(1); |
1618 | 1635 |
1619 opcode = TryNarrowOpcodeSize(opcode, left, right); | 1636 opcode = TryNarrowOpcodeSize(opcode, left, right, cont); |
1620 | 1637 |
1621 // If one of the two inputs is an immediate, make sure it's on the right, or | 1638 // If one of the two inputs is an immediate, make sure it's on the right, or |
1622 // if one of the two inputs is a memory operand, make sure it's on the left. | 1639 // if one of the two inputs is a memory operand, make sure it's on the left. |
1623 int effect_level = selector->GetEffectLevel(node); | 1640 int effect_level = selector->GetEffectLevel(node); |
1624 if (cont->IsBranch()) { | 1641 if (cont->IsBranch()) { |
1625 effect_level = selector->GetEffectLevel( | 1642 effect_level = selector->GetEffectLevel( |
1626 cont->true_block()->PredecessorAt(0)->control_input()); | 1643 cont->true_block()->PredecessorAt(0)->control_input()); |
1627 } | 1644 } |
1628 | 1645 |
1629 if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || | 1646 if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 // static | 2203 // static |
2187 MachineOperatorBuilder::AlignmentRequirements | 2204 MachineOperatorBuilder::AlignmentRequirements |
2188 InstructionSelector::AlignmentRequirements() { | 2205 InstructionSelector::AlignmentRequirements() { |
2189 return MachineOperatorBuilder::AlignmentRequirements:: | 2206 return MachineOperatorBuilder::AlignmentRequirements:: |
2190 FullUnalignedAccessSupport(); | 2207 FullUnalignedAccessSupport(); |
2191 } | 2208 } |
2192 | 2209 |
2193 } // namespace compiler | 2210 } // namespace compiler |
2194 } // namespace internal | 2211 } // namespace internal |
2195 } // namespace v8 | 2212 } // namespace v8 |
OLD | NEW |