| 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-intrinsics.h" | 7 #include "src/compiler-intrinsics.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 g.UseDoubleRegister(node->InputAt(0)), | 119 g.UseDoubleRegister(node->InputAt(0)), |
| 120 g.UseDoubleRegister(node->InputAt(1))); | 120 g.UseDoubleRegister(node->InputAt(1))); |
| 121 } | 121 } |
| 122 | 122 |
| 123 | 123 |
| 124 static bool TryMatchROR(InstructionSelector* selector, | 124 static bool TryMatchROR(InstructionSelector* selector, |
| 125 InstructionCode* opcode_return, Node* node, | 125 InstructionCode* opcode_return, Node* node, |
| 126 InstructionOperand** value_return, | 126 InstructionOperand** value_return, |
| 127 InstructionOperand** shift_return) { | 127 InstructionOperand** shift_return) { |
| 128 ArmOperandGenerator g(selector); | 128 ArmOperandGenerator g(selector); |
| 129 if (node->opcode() != IrOpcode::kWord32Or) return false; | 129 if (node->opcode() != IrOpcode::kWord32Ror) return false; |
| 130 Int32BinopMatcher m(node); | 130 Int32BinopMatcher m(node); |
| 131 Node* shl = m.left().node(); | 131 *value_return = g.UseRegister(m.left().node()); |
| 132 Node* shr = m.right().node(); | 132 if (m.right().IsInRange(1, 31)) { |
| 133 if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { | 133 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I); |
| 134 std::swap(shl, shr); | 134 *shift_return = g.UseImmediate(m.right().node()); |
| 135 } else if (!m.left().IsWord32Shl() || !m.right().IsWord32Shr()) { | 135 } else { |
| 136 return false; | 136 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_R); |
| 137 *shift_return = g.UseRegister(m.right().node()); |
| 137 } | 138 } |
| 138 Int32BinopMatcher mshr(shr); | 139 return true; |
| 139 Int32BinopMatcher mshl(shl); | |
| 140 Node* value = mshr.left().node(); | |
| 141 if (value != mshl.left().node()) return false; | |
| 142 Node* shift = mshr.right().node(); | |
| 143 Int32Matcher mshift(shift); | |
| 144 if (mshift.IsInRange(1, 31)) { | |
| 145 if (mshl.right().Is(32 - mshift.Value())) { | |
| 146 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I); | |
| 147 *value_return = g.UseRegister(value); | |
| 148 *shift_return = g.UseImmediate(shift); | |
| 149 return true; | |
| 150 } | |
| 151 if (mshl.right().IsInt32Sub()) { | |
| 152 Int32BinopMatcher mshlright(mshl.right().node()); | |
| 153 if (mshlright.left().Is(32) && mshlright.right().Is(mshift.Value())) { | |
| 154 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I); | |
| 155 *value_return = g.UseRegister(value); | |
| 156 *shift_return = g.UseImmediate(shift); | |
| 157 return true; | |
| 158 } | |
| 159 } | |
| 160 } | |
| 161 if (mshl.right().IsInt32Sub()) { | |
| 162 Int32BinopMatcher mshlright(mshl.right().node()); | |
| 163 if (!mshlright.left().Is(32)) return false; | |
| 164 if (mshlright.right().node() != shift) return false; | |
| 165 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_R); | |
| 166 *value_return = g.UseRegister(value); | |
| 167 *shift_return = g.UseRegister(shift); | |
| 168 return true; | |
| 169 } | |
| 170 return false; | |
| 171 } | 140 } |
| 172 | 141 |
| 173 | 142 |
| 174 static inline bool TryMatchASR(InstructionSelector* selector, | 143 static inline bool TryMatchASR(InstructionSelector* selector, |
| 175 InstructionCode* opcode_return, Node* node, | 144 InstructionCode* opcode_return, Node* node, |
| 176 InstructionOperand** value_return, | 145 InstructionOperand** value_return, |
| 177 InstructionOperand** shift_return) { | 146 InstructionOperand** shift_return) { |
| 178 ArmOperandGenerator g(selector); | 147 ArmOperandGenerator g(selector); |
| 179 if (node->opcode() != IrOpcode::kWord32Sar) return false; | 148 if (node->opcode() != IrOpcode::kWord32Sar) return false; |
| 180 Int32BinopMatcher m(node); | 149 Int32BinopMatcher m(node); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), | 444 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), |
| 476 g.TempImmediate(lsb), g.TempImmediate(width)); | 445 g.TempImmediate(lsb), g.TempImmediate(width)); |
| 477 return; | 446 return; |
| 478 } | 447 } |
| 479 } | 448 } |
| 480 VisitBinop(this, node, kArmAnd, kArmAnd); | 449 VisitBinop(this, node, kArmAnd, kArmAnd); |
| 481 } | 450 } |
| 482 | 451 |
| 483 | 452 |
| 484 void InstructionSelector::VisitWord32Or(Node* node) { | 453 void InstructionSelector::VisitWord32Or(Node* node) { |
| 485 ArmOperandGenerator g(this); | |
| 486 InstructionCode opcode = kArmMov; | |
| 487 InstructionOperand* value_operand; | |
| 488 InstructionOperand* shift_operand; | |
| 489 if (TryMatchROR(this, &opcode, node, &value_operand, &shift_operand)) { | |
| 490 Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand); | |
| 491 return; | |
| 492 } | |
| 493 VisitBinop(this, node, kArmOrr, kArmOrr); | 454 VisitBinop(this, node, kArmOrr, kArmOrr); |
| 494 } | 455 } |
| 495 | 456 |
| 496 | 457 |
| 497 void InstructionSelector::VisitWord32Xor(Node* node) { | 458 void InstructionSelector::VisitWord32Xor(Node* node) { |
| 498 ArmOperandGenerator g(this); | 459 ArmOperandGenerator g(this); |
| 499 Int32BinopMatcher m(node); | 460 Int32BinopMatcher m(node); |
| 500 if (m.right().Is(-1)) { | 461 if (m.right().Is(-1)) { |
| 501 InstructionCode opcode = kArmMvn; | 462 InstructionCode opcode = kArmMvn; |
| 502 InstructionOperand* value_operand; | 463 InstructionOperand* value_operand; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 } | 516 } |
| 556 VisitShift(this, node, TryMatchLSR); | 517 VisitShift(this, node, TryMatchLSR); |
| 557 } | 518 } |
| 558 | 519 |
| 559 | 520 |
| 560 void InstructionSelector::VisitWord32Sar(Node* node) { | 521 void InstructionSelector::VisitWord32Sar(Node* node) { |
| 561 VisitShift(this, node, TryMatchASR); | 522 VisitShift(this, node, TryMatchASR); |
| 562 } | 523 } |
| 563 | 524 |
| 564 | 525 |
| 526 void InstructionSelector::VisitWord32Ror(Node* node) { |
| 527 VisitShift(this, node, TryMatchROR); |
| 528 } |
| 529 |
| 530 |
| 565 void InstructionSelector::VisitInt32Add(Node* node) { | 531 void InstructionSelector::VisitInt32Add(Node* node) { |
| 566 ArmOperandGenerator g(this); | 532 ArmOperandGenerator g(this); |
| 567 Int32BinopMatcher m(node); | 533 Int32BinopMatcher m(node); |
| 568 if (m.left().IsInt32Mul() && CanCover(node, m.left().node())) { | 534 if (m.left().IsInt32Mul() && CanCover(node, m.left().node())) { |
| 569 Int32BinopMatcher mleft(m.left().node()); | 535 Int32BinopMatcher mleft(m.left().node()); |
| 570 Emit(kArmMla, g.DefineAsRegister(node), g.UseRegister(mleft.left().node()), | 536 Emit(kArmMla, g.DefineAsRegister(node), g.UseRegister(mleft.left().node()), |
| 571 g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node())); | 537 g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node())); |
| 572 return; | 538 return; |
| 573 } | 539 } |
| 574 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) { | 540 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) { |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 DCHECK(cont->IsSet()); | 911 DCHECK(cont->IsSet()); |
| 946 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 912 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
| 947 g.UseDoubleRegister(m.left().node()), | 913 g.UseDoubleRegister(m.left().node()), |
| 948 g.UseDoubleRegister(m.right().node())); | 914 g.UseDoubleRegister(m.right().node())); |
| 949 } | 915 } |
| 950 } | 916 } |
| 951 | 917 |
| 952 } // namespace compiler | 918 } // namespace compiler |
| 953 } // namespace internal | 919 } // namespace internal |
| 954 } // namespace v8 | 920 } // namespace v8 |
| OLD | NEW |