| 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 |