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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), | 473 Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), |
474 g.DefineAsRegister(node), g.UseRegister(m.left().node())); | 474 g.DefineAsRegister(node), g.UseRegister(m.left().node())); |
475 return; | 475 return; |
476 } | 476 } |
477 VisitBinop(this, node, kArmEor, kArmEor); | 477 VisitBinop(this, node, kArmEor, kArmEor); |
478 } | 478 } |
479 | 479 |
480 | 480 |
481 template <typename TryMatchShift> | 481 template <typename TryMatchShift> |
482 static inline void VisitShift(InstructionSelector* selector, Node* node, | 482 static inline void VisitShift(InstructionSelector* selector, Node* node, |
| 483 TryMatchShift try_match_shift, |
| 484 FlagsContinuation* cont) { |
| 485 ArmOperandGenerator g(selector); |
| 486 InstructionCode opcode = kArmMov; |
| 487 InstructionOperand* inputs[4]; |
| 488 size_t input_count = 2; |
| 489 InstructionOperand* outputs[2]; |
| 490 size_t output_count = 0; |
| 491 |
| 492 CHECK(try_match_shift(selector, &opcode, node, &inputs[0], &inputs[1])); |
| 493 |
| 494 if (cont->IsBranch()) { |
| 495 inputs[input_count++] = g.Label(cont->true_block()); |
| 496 inputs[input_count++] = g.Label(cont->false_block()); |
| 497 } |
| 498 |
| 499 outputs[output_count++] = g.DefineAsRegister(node); |
| 500 if (cont->IsSet()) { |
| 501 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
| 502 } |
| 503 |
| 504 DCHECK_NE(0, input_count); |
| 505 DCHECK_NE(0, output_count); |
| 506 DCHECK_GE(ARRAY_SIZE(inputs), input_count); |
| 507 DCHECK_GE(ARRAY_SIZE(outputs), output_count); |
| 508 DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); |
| 509 |
| 510 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, |
| 511 outputs, input_count, inputs); |
| 512 if (cont->IsBranch()) instr->MarkAsControl(); |
| 513 } |
| 514 |
| 515 |
| 516 template <typename TryMatchShift> |
| 517 static inline void VisitShift(InstructionSelector* selector, Node* node, |
483 TryMatchShift try_match_shift) { | 518 TryMatchShift try_match_shift) { |
484 ArmOperandGenerator g(selector); | 519 FlagsContinuation cont; |
485 InstructionCode opcode = kArmMov; | 520 VisitShift(selector, node, try_match_shift, &cont); |
486 InstructionOperand* value_operand = NULL; | |
487 InstructionOperand* shift_operand = NULL; | |
488 CHECK( | |
489 try_match_shift(selector, &opcode, node, &value_operand, &shift_operand)); | |
490 selector->Emit(opcode, g.DefineAsRegister(node), value_operand, | |
491 shift_operand); | |
492 } | 521 } |
493 | 522 |
494 | 523 |
495 void InstructionSelector::VisitWord32Shl(Node* node) { | 524 void InstructionSelector::VisitWord32Shl(Node* node) { |
496 VisitShift(this, node, TryMatchLSL); | 525 VisitShift(this, node, TryMatchLSL); |
497 } | 526 } |
498 | 527 |
499 | 528 |
500 void InstructionSelector::VisitWord32Shr(Node* node) { | 529 void InstructionSelector::VisitWord32Shr(Node* node) { |
501 ArmOperandGenerator g(this); | 530 ArmOperandGenerator g(this); |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 case IrOpcode::kInt32Add: | 900 case IrOpcode::kInt32Add: |
872 return VisitWordCompare(this, node, kArmCmn, cont, true); | 901 return VisitWordCompare(this, node, kArmCmn, cont, true); |
873 case IrOpcode::kInt32Sub: | 902 case IrOpcode::kInt32Sub: |
874 return VisitWordCompare(this, node, kArmCmp, cont, false); | 903 return VisitWordCompare(this, node, kArmCmp, cont, false); |
875 case IrOpcode::kWord32And: | 904 case IrOpcode::kWord32And: |
876 return VisitWordCompare(this, node, kArmTst, cont, true); | 905 return VisitWordCompare(this, node, kArmTst, cont, true); |
877 case IrOpcode::kWord32Or: | 906 case IrOpcode::kWord32Or: |
878 return VisitBinop(this, node, kArmOrr, kArmOrr, cont); | 907 return VisitBinop(this, node, kArmOrr, kArmOrr, cont); |
879 case IrOpcode::kWord32Xor: | 908 case IrOpcode::kWord32Xor: |
880 return VisitWordCompare(this, node, kArmTeq, cont, true); | 909 return VisitWordCompare(this, node, kArmTeq, cont, true); |
| 910 case IrOpcode::kWord32Sar: |
| 911 return VisitShift(this, node, TryMatchASR, cont); |
| 912 case IrOpcode::kWord32Shl: |
| 913 return VisitShift(this, node, TryMatchLSL, cont); |
| 914 case IrOpcode::kWord32Shr: |
| 915 return VisitShift(this, node, TryMatchLSR, cont); |
| 916 case IrOpcode::kWord32Ror: |
| 917 return VisitShift(this, node, TryMatchROR, cont); |
881 default: | 918 default: |
882 break; | 919 break; |
883 } | 920 } |
884 | 921 |
885 ArmOperandGenerator g(this); | 922 ArmOperandGenerator g(this); |
886 InstructionCode opcode = | 923 InstructionCode opcode = |
887 cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R); | 924 cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R); |
888 if (cont->IsBranch()) { | 925 if (cont->IsBranch()) { |
889 Emit(opcode, NULL, g.UseRegister(node), g.UseRegister(node), | 926 Emit(opcode, NULL, g.UseRegister(node), g.UseRegister(node), |
890 g.Label(cont->true_block()), | 927 g.Label(cont->true_block()), |
(...skipping 23 matching lines...) Expand all Loading... |
914 DCHECK(cont->IsSet()); | 951 DCHECK(cont->IsSet()); |
915 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 952 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
916 g.UseDoubleRegister(m.left().node()), | 953 g.UseDoubleRegister(m.left().node()), |
917 g.UseDoubleRegister(m.right().node())); | 954 g.UseDoubleRegister(m.right().node())); |
918 } | 955 } |
919 } | 956 } |
920 | 957 |
921 } // namespace compiler | 958 } // namespace compiler |
922 } // namespace internal | 959 } // namespace internal |
923 } // namespace v8 | 960 } // namespace v8 |
OLD | NEW |