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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 21 matching lines...) Expand all Loading... |
32 if (input->opcode() != IrOpcode::kLoad || | 32 if (input->opcode() != IrOpcode::kLoad || |
33 !selector()->CanCover(node, input)) { | 33 !selector()->CanCover(node, input)) { |
34 return false; | 34 return false; |
35 } | 35 } |
36 if (effect_level != selector()->GetEffectLevel(input)) { | 36 if (effect_level != selector()->GetEffectLevel(input)) { |
37 return false; | 37 return false; |
38 } | 38 } |
39 MachineRepresentation rep = | 39 MachineRepresentation rep = |
40 LoadRepresentationOf(input->op()).representation(); | 40 LoadRepresentationOf(input->op()).representation(); |
41 switch (opcode) { | 41 switch (opcode) { |
| 42 case kIA32And: |
| 43 case kIA32Or: |
| 44 case kIA32Xor: |
| 45 case kIA32Add: |
| 46 case kIA32Sub: |
42 case kIA32Cmp: | 47 case kIA32Cmp: |
43 case kIA32Test: | 48 case kIA32Test: |
44 return rep == MachineRepresentation::kWord32 || | 49 return rep == MachineRepresentation::kWord32 || |
45 rep == MachineRepresentation::kTagged; | 50 rep == MachineRepresentation::kTagged; |
46 case kIA32Cmp16: | 51 case kIA32Cmp16: |
47 case kIA32Test16: | 52 case kIA32Test16: |
48 return rep == MachineRepresentation::kWord16; | 53 return rep == MachineRepresentation::kWord16; |
49 case kIA32Cmp8: | 54 case kIA32Cmp8: |
50 case kIA32Test8: | 55 case kIA32Test8: |
51 return rep == MachineRepresentation::kWord8; | 56 return rep == MachineRepresentation::kWord8; |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 | 531 |
527 namespace { | 532 namespace { |
528 | 533 |
529 // Shared routine for multiple binary operations. | 534 // Shared routine for multiple binary operations. |
530 void VisitBinop(InstructionSelector* selector, Node* node, | 535 void VisitBinop(InstructionSelector* selector, Node* node, |
531 InstructionCode opcode, FlagsContinuation* cont) { | 536 InstructionCode opcode, FlagsContinuation* cont) { |
532 IA32OperandGenerator g(selector); | 537 IA32OperandGenerator g(selector); |
533 Int32BinopMatcher m(node); | 538 Int32BinopMatcher m(node); |
534 Node* left = m.left().node(); | 539 Node* left = m.left().node(); |
535 Node* right = m.right().node(); | 540 Node* right = m.right().node(); |
536 InstructionOperand inputs[4]; | 541 InstructionOperand inputs[6]; |
537 size_t input_count = 0; | 542 size_t input_count = 0; |
538 InstructionOperand outputs[2]; | 543 InstructionOperand outputs[2]; |
539 size_t output_count = 0; | 544 size_t output_count = 0; |
540 | 545 |
541 // TODO(turbofan): match complex addressing modes. | 546 // TODO(turbofan): match complex addressing modes. |
542 if (left == right) { | 547 if (left == right) { |
543 // If both inputs refer to the same operand, enforce allocating a register | 548 // If both inputs refer to the same operand, enforce allocating a register |
544 // for both of them to ensure that we don't end up generating code like | 549 // for both of them to ensure that we don't end up generating code like |
545 // this: | 550 // this: |
546 // | 551 // |
547 // mov eax, [ebp-0x10] | 552 // mov eax, [ebp-0x10] |
548 // add eax, [ebp-0x10] | 553 // add eax, [ebp-0x10] |
549 // jo label | 554 // jo label |
550 InstructionOperand const input = g.UseRegister(left); | 555 InstructionOperand const input = g.UseRegister(left); |
551 inputs[input_count++] = input; | 556 inputs[input_count++] = input; |
552 inputs[input_count++] = input; | 557 inputs[input_count++] = input; |
553 } else if (g.CanBeImmediate(right)) { | 558 } else if (g.CanBeImmediate(right)) { |
554 inputs[input_count++] = g.UseRegister(left); | 559 inputs[input_count++] = g.UseRegister(left); |
555 inputs[input_count++] = g.UseImmediate(right); | 560 inputs[input_count++] = g.UseImmediate(right); |
556 } else { | 561 } else { |
| 562 int effect_level = selector->GetEffectLevel(node); |
| 563 if (cont->IsBranch()) { |
| 564 effect_level = selector->GetEffectLevel( |
| 565 cont->true_block()->PredecessorAt(0)->control_input()); |
| 566 } |
557 if (node->op()->HasProperty(Operator::kCommutative) && | 567 if (node->op()->HasProperty(Operator::kCommutative) && |
558 g.CanBeBetterLeftOperand(right)) { | 568 g.CanBeBetterLeftOperand(right) && |
| 569 (!g.CanBeBetterLeftOperand(left) || |
| 570 !g.CanBeMemoryOperand(opcode, node, right, effect_level))) { |
559 std::swap(left, right); | 571 std::swap(left, right); |
560 } | 572 } |
561 inputs[input_count++] = g.UseRegister(left); | 573 if (g.CanBeMemoryOperand(opcode, node, right, effect_level)) { |
562 inputs[input_count++] = g.Use(right); | 574 inputs[input_count++] = g.UseRegister(left); |
| 575 AddressingMode addressing_mode = |
| 576 g.GetEffectiveAddressMemoryOperand(right, inputs, &input_count); |
| 577 opcode |= AddressingModeField::encode(addressing_mode); |
| 578 } else { |
| 579 inputs[input_count++] = g.UseRegister(left); |
| 580 inputs[input_count++] = g.Use(right); |
| 581 } |
563 } | 582 } |
564 | 583 |
565 if (cont->IsBranch()) { | 584 if (cont->IsBranch()) { |
566 inputs[input_count++] = g.Label(cont->true_block()); | 585 inputs[input_count++] = g.Label(cont->true_block()); |
567 inputs[input_count++] = g.Label(cont->false_block()); | 586 inputs[input_count++] = g.Label(cont->false_block()); |
568 } | 587 } |
569 | 588 |
570 outputs[output_count++] = g.DefineSameAsFirst(node); | 589 outputs[output_count++] = g.DefineSameAsFirst(node); |
571 if (cont->IsSet()) { | 590 if (cont->IsSet()) { |
572 outputs[output_count++] = g.DefineAsByteRegister(cont->result()); | 591 outputs[output_count++] = g.DefineAsByteRegister(cont->result()); |
(...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1802 // static | 1821 // static |
1803 MachineOperatorBuilder::AlignmentRequirements | 1822 MachineOperatorBuilder::AlignmentRequirements |
1804 InstructionSelector::AlignmentRequirements() { | 1823 InstructionSelector::AlignmentRequirements() { |
1805 return MachineOperatorBuilder::AlignmentRequirements:: | 1824 return MachineOperatorBuilder::AlignmentRequirements:: |
1806 FullUnalignedAccessSupport(); | 1825 FullUnalignedAccessSupport(); |
1807 } | 1826 } |
1808 | 1827 |
1809 } // namespace compiler | 1828 } // namespace compiler |
1810 } // namespace internal | 1829 } // namespace internal |
1811 } // namespace v8 | 1830 } // namespace v8 |
OLD | NEW |