| 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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   216 template <typename Matcher> |   216 template <typename Matcher> | 
|   217 void VisitBinop(InstructionSelector* selector, Node* node, |   217 void VisitBinop(InstructionSelector* selector, Node* node, | 
|   218                 InstructionCode opcode, ImmediateMode operand_mode, |   218                 InstructionCode opcode, ImmediateMode operand_mode, | 
|   219                 FlagsContinuation* cont) { |   219                 FlagsContinuation* cont) { | 
|   220   Arm64OperandGenerator g(selector); |   220   Arm64OperandGenerator g(selector); | 
|   221   Matcher m(node); |   221   Matcher m(node); | 
|   222   InstructionOperand inputs[5]; |   222   InstructionOperand inputs[5]; | 
|   223   size_t input_count = 0; |   223   size_t input_count = 0; | 
|   224   InstructionOperand outputs[2]; |   224   InstructionOperand outputs[2]; | 
|   225   size_t output_count = 0; |   225   size_t output_count = 0; | 
|   226   bool is_cmp = opcode == kArm64Cmp32; |   226   bool is_cmp = (opcode == kArm64Cmp32) || (opcode == kArm64Cmn32); | 
|   227  |   227  | 
|   228   // We can commute cmp by switching the inputs and commuting the flags |   228   // We can commute cmp by switching the inputs and commuting the flags | 
|   229   // continuation. |   229   // continuation. | 
|   230   bool can_commute = m.HasProperty(Operator::kCommutative) || is_cmp; |   230   bool can_commute = m.HasProperty(Operator::kCommutative) || is_cmp; | 
|   231  |   231  | 
|   232   // The cmp instruction is encoded as sub with zero output register, and |   232   // The cmp and cmn instructions are encoded as sub or add with zero output | 
|   233   // therefore supports the same operand modes. |   233   // register, and therefore support the same operand modes. | 
|   234   bool is_add_sub = m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || |   234   bool is_add_sub = m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || | 
|   235                     m.IsInt64Sub() || is_cmp; |   235                     m.IsInt64Sub() || is_cmp; | 
|   236  |   236  | 
|   237   Node* left_node = m.left().node(); |   237   Node* left_node = m.left().node(); | 
|   238   Node* right_node = m.right().node(); |   238   Node* right_node = m.right().node(); | 
|   239  |   239  | 
|   240   if (g.CanBeImmediate(right_node, operand_mode)) { |   240   if (g.CanBeImmediate(right_node, operand_mode)) { | 
|   241     inputs[input_count++] = g.UseRegister(left_node); |   241     inputs[input_count++] = g.UseRegister(left_node); | 
|   242     inputs[input_count++] = g.UseImmediate(right_node); |   242     inputs[input_count++] = g.UseImmediate(right_node); | 
|   243   } else if (is_cmp && g.CanBeImmediate(left_node, operand_mode)) { |   243   } else if (is_cmp && g.CanBeImmediate(left_node, operand_mode)) { | 
| (...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1503                  cont); |  1503                  cont); | 
|  1504   } else { |  1504   } else { | 
|  1505     VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), |  1505     VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), | 
|  1506                  cont); |  1506                  cont); | 
|  1507   } |  1507   } | 
|  1508 } |  1508 } | 
|  1509  |  1509  | 
|  1510  |  1510  | 
|  1511 void VisitWord32Compare(InstructionSelector* selector, Node* node, |  1511 void VisitWord32Compare(InstructionSelector* selector, Node* node, | 
|  1512                         FlagsContinuation* cont) { |  1512                         FlagsContinuation* cont) { | 
|  1513   VisitBinop<Int32BinopMatcher>(selector, node, kArm64Cmp32, kArithmeticImm, |  1513   Int32BinopMatcher m(node); | 
|  1514                                 cont); |  1514   ArchOpcode opcode = kArm64Cmp32; | 
 |  1515  | 
 |  1516   // Select negated compare for comparisons with negated right input. | 
 |  1517   if (m.right().IsInt32Sub()) { | 
 |  1518     Node* sub = m.right().node(); | 
 |  1519     Int32BinopMatcher msub(sub); | 
 |  1520     if (msub.left().Is(0)) { | 
 |  1521       bool can_cover = selector->CanCover(node, sub); | 
 |  1522       node->ReplaceInput(1, msub.right().node()); | 
 |  1523       // Even if the comparison node covers the subtraction, after the input | 
 |  1524       // replacement above, the node still won't cover the input to the | 
 |  1525       // subtraction; the subtraction still uses it. | 
 |  1526       // In order to get shifted operations to work, we must remove the rhs | 
 |  1527       // input to the subtraction, as TryMatchAnyShift requires this node to | 
 |  1528       // cover the input shift. We do this by setting it to the lhs input, | 
 |  1529       // as we know it's zero, and the result of the subtraction isn't used by | 
 |  1530       // any other node. | 
 |  1531       if (can_cover) sub->ReplaceInput(1, msub.left().node()); | 
 |  1532       opcode = kArm64Cmn32; | 
 |  1533     } | 
 |  1534   } | 
 |  1535   VisitBinop<Int32BinopMatcher>(selector, node, opcode, kArithmeticImm, cont); | 
|  1515 } |  1536 } | 
|  1516  |  1537  | 
|  1517  |  1538  | 
|  1518 void VisitWordTest(InstructionSelector* selector, Node* node, |  1539 void VisitWordTest(InstructionSelector* selector, Node* node, | 
|  1519                    InstructionCode opcode, FlagsContinuation* cont) { |  1540                    InstructionCode opcode, FlagsContinuation* cont) { | 
|  1520   Arm64OperandGenerator g(selector); |  1541   Arm64OperandGenerator g(selector); | 
|  1521   VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node), |  1542   VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node), | 
|  1522                cont); |  1543                cont); | 
|  1523 } |  1544 } | 
|  1524  |  1545  | 
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1979          MachineOperatorBuilder::kFloat64RoundTruncate | |  2000          MachineOperatorBuilder::kFloat64RoundTruncate | | 
|  1980          MachineOperatorBuilder::kFloat64RoundTiesAway | |  2001          MachineOperatorBuilder::kFloat64RoundTiesAway | | 
|  1981          MachineOperatorBuilder::kWord32ShiftIsSafe | |  2002          MachineOperatorBuilder::kWord32ShiftIsSafe | | 
|  1982          MachineOperatorBuilder::kInt32DivIsSafe | |  2003          MachineOperatorBuilder::kInt32DivIsSafe | | 
|  1983          MachineOperatorBuilder::kUint32DivIsSafe; |  2004          MachineOperatorBuilder::kUint32DivIsSafe; | 
|  1984 } |  2005 } | 
|  1985  |  2006  | 
|  1986 }  // namespace compiler |  2007 }  // namespace compiler | 
|  1987 }  // namespace internal |  2008 }  // namespace internal | 
|  1988 }  // namespace v8 |  2009 }  // namespace v8 | 
| OLD | NEW |