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 |