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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_I); | 210 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_I); |
211 *shift_return = g.UseImmediate(m.right().node()); | 211 *shift_return = g.UseImmediate(m.right().node()); |
212 } else { | 212 } else { |
213 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_R); | 213 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_R); |
214 *shift_return = g.UseRegister(m.right().node()); | 214 *shift_return = g.UseRegister(m.right().node()); |
215 } | 215 } |
216 return true; | 216 return true; |
217 } | 217 } |
218 | 218 |
219 | 219 |
220 static inline bool TryMatchShift(InstructionSelector* selector, | |
titzer
2014/08/01 11:12:33
s/inline//
| |
221 InstructionCode* opcode_return, Node* node, | |
222 InstructionOperand** value_return, | |
223 InstructionOperand** shift_return) { | |
224 return ( | |
225 TryMatchASR(selector, opcode_return, node, value_return, shift_return) || | |
226 TryMatchLSL(selector, opcode_return, node, value_return, shift_return) || | |
227 TryMatchLSR(selector, opcode_return, node, value_return, shift_return) || | |
228 TryMatchROR(selector, opcode_return, node, value_return, shift_return)); | |
229 } | |
230 | |
231 | |
220 static inline bool TryMatchImmediateOrShift(InstructionSelector* selector, | 232 static inline bool TryMatchImmediateOrShift(InstructionSelector* selector, |
221 InstructionCode* opcode_return, | 233 InstructionCode* opcode_return, |
222 Node* node, | 234 Node* node, |
223 size_t* input_count_return, | 235 size_t* input_count_return, |
224 InstructionOperand** inputs) { | 236 InstructionOperand** inputs) { |
225 ArmOperandGenerator g(selector); | 237 ArmOperandGenerator g(selector); |
226 if (g.CanBeImmediate(node, *opcode_return)) { | 238 if (g.CanBeImmediate(node, *opcode_return)) { |
227 *opcode_return |= AddressingModeField::encode(kMode_Operand2_I); | 239 *opcode_return |= AddressingModeField::encode(kMode_Operand2_I); |
228 inputs[0] = g.UseImmediate(node); | 240 inputs[0] = g.UseImmediate(node); |
229 *input_count_return = 1; | 241 *input_count_return = 1; |
230 return true; | 242 return true; |
231 } | 243 } |
232 if (TryMatchASR(selector, opcode_return, node, &inputs[0], &inputs[1]) || | 244 if (TryMatchShift(selector, opcode_return, node, &inputs[0], &inputs[1])) { |
233 TryMatchLSL(selector, opcode_return, node, &inputs[0], &inputs[1]) || | |
234 TryMatchLSR(selector, opcode_return, node, &inputs[0], &inputs[1]) || | |
235 TryMatchROR(selector, opcode_return, node, &inputs[0], &inputs[1])) { | |
236 *input_count_return = 2; | 245 *input_count_return = 2; |
237 return true; | 246 return true; |
238 } | 247 } |
239 return false; | 248 return false; |
240 } | 249 } |
241 | 250 |
242 | 251 |
243 // Shared routine for multiple binary operations. | 252 // Shared routine for multiple binary operations. |
244 static void VisitBinop(InstructionSelector* selector, Node* node, | 253 static void VisitBinop(InstructionSelector* selector, Node* node, |
245 InstructionCode opcode, InstructionCode reverse_opcode) { | 254 InstructionCode opcode, InstructionCode reverse_opcode) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL, | 427 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL, |
419 g.UseRegister(base), g.UseRegister(index), val); | 428 g.UseRegister(base), g.UseRegister(index), val); |
420 } | 429 } |
421 } | 430 } |
422 | 431 |
423 | 432 |
424 static inline void EmitBic(InstructionSelector* selector, Node* node, | 433 static inline void EmitBic(InstructionSelector* selector, Node* node, |
425 Node* left, Node* right) { | 434 Node* left, Node* right) { |
426 ArmOperandGenerator g(selector); | 435 ArmOperandGenerator g(selector); |
427 InstructionCode opcode = kArmBic; | 436 InstructionCode opcode = kArmBic; |
428 InstructionOperand* inputs[3]; | 437 InstructionOperand* value_operand; |
429 size_t input_count = 0; | 438 InstructionOperand* shift_operand; |
430 InstructionOperand* outputs[1] = {g.DefineAsRegister(node)}; | 439 if (TryMatchShift(selector, &opcode, right, &value_operand, &shift_operand)) { |
431 const size_t output_count = ARRAY_SIZE(outputs); | 440 selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), |
432 | 441 value_operand, shift_operand); |
433 inputs[input_count++] = g.UseRegister(left); | 442 return; |
434 if (!TryMatchImmediateOrShift(selector, &opcode, right, &input_count, | |
435 &inputs[input_count])) { | |
436 opcode |= AddressingModeField::encode(kMode_Operand2_R); | |
437 inputs[input_count++] = g.UseRegister(right); | |
438 } | 443 } |
439 | 444 selector->Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), |
440 ASSERT_NE(0, input_count); | 445 g.DefineAsRegister(node), g.UseRegister(left), |
441 ASSERT_GE(ARRAY_SIZE(inputs), input_count); | 446 g.UseRegister(right)); |
442 ASSERT_NE(kMode_None, AddressingModeField::decode(opcode)); | |
443 | |
444 selector->Emit(opcode, output_count, outputs, input_count, inputs); | |
445 } | 447 } |
446 | 448 |
447 | 449 |
448 void InstructionSelector::VisitWord32And(Node* node) { | 450 void InstructionSelector::VisitWord32And(Node* node) { |
449 ArmOperandGenerator g(this); | 451 ArmOperandGenerator g(this); |
450 Int32BinopMatcher m(node); | 452 Int32BinopMatcher m(node); |
451 if (m.left().IsWord32Xor() && CanCover(node, m.left().node())) { | 453 if (m.left().IsWord32Xor() && CanCover(node, m.left().node())) { |
452 Int32BinopMatcher mleft(m.left().node()); | 454 Int32BinopMatcher mleft(m.left().node()); |
453 if (mleft.right().Is(-1)) { | 455 if (mleft.right().Is(-1)) { |
454 EmitBic(this, node, m.right().node(), mleft.left().node()); | 456 EmitBic(this, node, m.right().node(), mleft.left().node()); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 return; | 507 return; |
506 } | 508 } |
507 VisitBinop(this, node, kArmOrr, kArmOrr); | 509 VisitBinop(this, node, kArmOrr, kArmOrr); |
508 } | 510 } |
509 | 511 |
510 | 512 |
511 void InstructionSelector::VisitWord32Xor(Node* node) { | 513 void InstructionSelector::VisitWord32Xor(Node* node) { |
512 ArmOperandGenerator g(this); | 514 ArmOperandGenerator g(this); |
513 Int32BinopMatcher m(node); | 515 Int32BinopMatcher m(node); |
514 if (m.right().Is(-1)) { | 516 if (m.right().Is(-1)) { |
515 Emit(kArmMvn | AddressingModeField::encode(kMode_Operand2_R), | 517 InstructionCode opcode = kArmMvn; |
516 g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); | 518 InstructionOperand* value_operand; |
517 } else { | 519 InstructionOperand* shift_operand; |
518 VisitBinop(this, node, kArmEor, kArmEor); | 520 if (TryMatchShift(this, &opcode, m.left().node(), &value_operand, |
521 &shift_operand)) { | |
522 Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand); | |
523 return; | |
524 } | |
525 Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), | |
526 g.DefineAsRegister(node), g.UseRegister(m.left().node())); | |
527 return; | |
519 } | 528 } |
529 VisitBinop(this, node, kArmEor, kArmEor); | |
520 } | 530 } |
521 | 531 |
522 | 532 |
523 template <typename TryMatchShift> | 533 template <typename TryMatchShift> |
524 static inline void VisitShift(InstructionSelector* selector, Node* node, | 534 static inline void VisitShift(InstructionSelector* selector, Node* node, |
525 TryMatchShift try_match_shift) { | 535 TryMatchShift try_match_shift) { |
526 ArmOperandGenerator g(selector); | 536 ArmOperandGenerator g(selector); |
527 InstructionCode opcode = kArmMov; | 537 InstructionCode opcode = kArmMov; |
528 InstructionOperand* value_operand = NULL; | 538 InstructionOperand* value_operand = NULL; |
529 InstructionOperand* shift_operand = NULL; | 539 InstructionOperand* shift_operand = NULL; |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 ASSERT(cont->IsSet()); | 957 ASSERT(cont->IsSet()); |
948 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 958 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
949 g.UseDoubleRegister(m.left().node()), | 959 g.UseDoubleRegister(m.left().node()), |
950 g.UseDoubleRegister(m.right().node())); | 960 g.UseDoubleRegister(m.right().node())); |
951 } | 961 } |
952 } | 962 } |
953 | 963 |
954 } // namespace compiler | 964 } // namespace compiler |
955 } // namespace internal | 965 } // namespace internal |
956 } // namespace v8 | 966 } // namespace v8 |
OLD | NEW |