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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 if (input->opcode() != IrOpcode::kLoad || | 51 if (input->opcode() != IrOpcode::kLoad || |
52 !selector()->CanCover(node, input)) { | 52 !selector()->CanCover(node, input)) { |
53 return false; | 53 return false; |
54 } | 54 } |
55 if (effect_level != selector()->GetEffectLevel(input)) { | 55 if (effect_level != selector()->GetEffectLevel(input)) { |
56 return false; | 56 return false; |
57 } | 57 } |
58 MachineRepresentation rep = | 58 MachineRepresentation rep = |
59 LoadRepresentationOf(input->op()).representation(); | 59 LoadRepresentationOf(input->op()).representation(); |
60 switch (opcode) { | 60 switch (opcode) { |
| 61 case kX64And: |
| 62 case kX64Or: |
| 63 case kX64Xor: |
| 64 case kX64Add: |
| 65 case kX64Sub: |
61 case kX64Push: | 66 case kX64Push: |
62 case kX64Cmp: | 67 case kX64Cmp: |
63 case kX64Test: | 68 case kX64Test: |
64 return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep); | 69 return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep); |
| 70 case kX64And32: |
| 71 case kX64Or32: |
| 72 case kX64Xor32: |
| 73 case kX64Add32: |
| 74 case kX64Sub32: |
65 case kX64Cmp32: | 75 case kX64Cmp32: |
66 case kX64Test32: | 76 case kX64Test32: |
67 return rep == MachineRepresentation::kWord32; | 77 return rep == MachineRepresentation::kWord32; |
68 case kX64Cmp16: | 78 case kX64Cmp16: |
69 case kX64Test16: | 79 case kX64Test16: |
70 return rep == MachineRepresentation::kWord16; | 80 return rep == MachineRepresentation::kWord16; |
71 case kX64Cmp8: | 81 case kX64Cmp8: |
72 case kX64Test8: | 82 case kX64Test8: |
73 return rep == MachineRepresentation::kWord8; | 83 return rep == MachineRepresentation::kWord8; |
74 default: | 84 default: |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 } | 510 } |
501 | 511 |
502 | 512 |
503 // Shared routine for multiple binary operations. | 513 // Shared routine for multiple binary operations. |
504 static void VisitBinop(InstructionSelector* selector, Node* node, | 514 static void VisitBinop(InstructionSelector* selector, Node* node, |
505 InstructionCode opcode, FlagsContinuation* cont) { | 515 InstructionCode opcode, FlagsContinuation* cont) { |
506 X64OperandGenerator g(selector); | 516 X64OperandGenerator g(selector); |
507 Int32BinopMatcher m(node); | 517 Int32BinopMatcher m(node); |
508 Node* left = m.left().node(); | 518 Node* left = m.left().node(); |
509 Node* right = m.right().node(); | 519 Node* right = m.right().node(); |
510 InstructionOperand inputs[4]; | 520 InstructionOperand inputs[6]; |
511 size_t input_count = 0; | 521 size_t input_count = 0; |
512 InstructionOperand outputs[2]; | 522 InstructionOperand outputs[2]; |
513 size_t output_count = 0; | 523 size_t output_count = 0; |
514 | 524 |
515 // TODO(turbofan): match complex addressing modes. | 525 // TODO(turbofan): match complex addressing modes. |
516 if (left == right) { | 526 if (left == right) { |
517 // If both inputs refer to the same operand, enforce allocating a register | 527 // If both inputs refer to the same operand, enforce allocating a register |
518 // for both of them to ensure that we don't end up generating code like | 528 // for both of them to ensure that we don't end up generating code like |
519 // this: | 529 // this: |
520 // | 530 // |
521 // mov rax, [rbp-0x10] | 531 // mov rax, [rbp-0x10] |
522 // add rax, [rbp-0x10] | 532 // add rax, [rbp-0x10] |
523 // jo label | 533 // jo label |
524 InstructionOperand const input = g.UseRegister(left); | 534 InstructionOperand const input = g.UseRegister(left); |
525 inputs[input_count++] = input; | 535 inputs[input_count++] = input; |
526 inputs[input_count++] = input; | 536 inputs[input_count++] = input; |
527 } else if (g.CanBeImmediate(right)) { | 537 } else if (g.CanBeImmediate(right)) { |
528 inputs[input_count++] = g.UseRegister(left); | 538 inputs[input_count++] = g.UseRegister(left); |
529 inputs[input_count++] = g.UseImmediate(right); | 539 inputs[input_count++] = g.UseImmediate(right); |
530 } else { | 540 } else { |
| 541 int effect_level = selector->GetEffectLevel(node); |
| 542 if (cont->IsBranch()) { |
| 543 effect_level = selector->GetEffectLevel( |
| 544 cont->true_block()->PredecessorAt(0)->control_input()); |
| 545 } |
531 if (node->op()->HasProperty(Operator::kCommutative) && | 546 if (node->op()->HasProperty(Operator::kCommutative) && |
532 g.CanBeBetterLeftOperand(right)) { | 547 g.CanBeBetterLeftOperand(right) && |
| 548 (!g.CanBeBetterLeftOperand(left) || |
| 549 !g.CanBeMemoryOperand(opcode, node, right, effect_level))) { |
533 std::swap(left, right); | 550 std::swap(left, right); |
534 } | 551 } |
535 inputs[input_count++] = g.UseRegister(left); | 552 if (g.CanBeMemoryOperand(opcode, node, right, effect_level)) { |
536 inputs[input_count++] = g.Use(right); | 553 inputs[input_count++] = g.UseRegister(left); |
| 554 AddressingMode addressing_mode = |
| 555 g.GetEffectiveAddressMemoryOperand(right, inputs, &input_count); |
| 556 opcode |= AddressingModeField::encode(addressing_mode); |
| 557 } else { |
| 558 inputs[input_count++] = g.UseRegister(left); |
| 559 inputs[input_count++] = g.Use(right); |
| 560 } |
537 } | 561 } |
538 | 562 |
539 if (cont->IsBranch()) { | 563 if (cont->IsBranch()) { |
540 inputs[input_count++] = g.Label(cont->true_block()); | 564 inputs[input_count++] = g.Label(cont->true_block()); |
541 inputs[input_count++] = g.Label(cont->false_block()); | 565 inputs[input_count++] = g.Label(cont->false_block()); |
542 } | 566 } |
543 | 567 |
544 outputs[output_count++] = g.DefineSameAsFirst(node); | 568 outputs[output_count++] = g.DefineSameAsFirst(node); |
545 if (cont->IsSet()) { | 569 if (cont->IsSet()) { |
546 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 570 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
(...skipping 1845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2392 // static | 2416 // static |
2393 MachineOperatorBuilder::AlignmentRequirements | 2417 MachineOperatorBuilder::AlignmentRequirements |
2394 InstructionSelector::AlignmentRequirements() { | 2418 InstructionSelector::AlignmentRequirements() { |
2395 return MachineOperatorBuilder::AlignmentRequirements:: | 2419 return MachineOperatorBuilder::AlignmentRequirements:: |
2396 FullUnalignedAccessSupport(); | 2420 FullUnalignedAccessSupport(); |
2397 } | 2421 } |
2398 | 2422 |
2399 } // namespace compiler | 2423 } // namespace compiler |
2400 } // namespace internal | 2424 } // namespace internal |
2401 } // namespace v8 | 2425 } // namespace v8 |
OLD | NEW |