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 | 7 |
8 namespace v8 { | 8 namespace v8 { |
9 namespace internal { | 9 namespace internal { |
10 namespace compiler { | 10 namespace compiler { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 return false; | 47 return false; |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 bool CanBeBetterLeftOperand(Node* node) const { | 51 bool CanBeBetterLeftOperand(Node* node) const { |
52 return !selector()->IsLive(node); | 52 return !selector()->IsLive(node); |
53 } | 53 } |
54 }; | 54 }; |
55 | 55 |
56 | 56 |
| 57 // Get the AddressingMode of scale factor N from the AddressingMode of scale |
| 58 // factor 1. |
| 59 static AddressingMode AdjustAddressingMode(AddressingMode base_mode, |
| 60 int power) { |
| 61 DCHECK(0 <= power && power < 4); |
| 62 return static_cast<AddressingMode>(static_cast<int>(base_mode) + power); |
| 63 } |
| 64 |
| 65 |
57 class AddressingModeMatcher { | 66 class AddressingModeMatcher { |
58 public: | 67 public: |
59 AddressingModeMatcher(X64OperandGenerator* g, Node* base, Node* index) | 68 AddressingModeMatcher(X64OperandGenerator* g, Node* base, Node* index) |
60 : base_operand_(NULL), | 69 : base_operand_(NULL), |
61 index_operand_(NULL), | 70 index_operand_(NULL), |
62 displacement_operand_(NULL), | 71 displacement_operand_(NULL), |
63 mode_(kMode_None) { | 72 mode_(kMode_None) { |
64 Int32Matcher index_imm(index); | 73 Int32Matcher index_imm(index); |
65 if (index_imm.HasValue()) { | 74 if (index_imm.HasValue()) { |
66 int32_t value = index_imm.Value(); | 75 int32_t value = index_imm.Value(); |
(...skipping 24 matching lines...) Expand all Loading... |
91 mode_ = kMode_M1I; | 100 mode_ = kMode_M1I; |
92 } | 101 } |
93 } else { | 102 } else { |
94 if (displacement_operand_ == NULL) { | 103 if (displacement_operand_ == NULL) { |
95 mode_ = kMode_MR1; | 104 mode_ = kMode_MR1; |
96 } else { | 105 } else { |
97 mode_ = kMode_MR1I; | 106 mode_ = kMode_MR1I; |
98 } | 107 } |
99 } | 108 } |
100 // Adjust mode to actual scale factor. | 109 // Adjust mode to actual scale factor. |
101 mode_ = GetMode(mode_, matcher.power()); | 110 mode_ = AdjustAddressingMode(mode_, matcher.power()); |
102 } | 111 } |
103 DCHECK_NE(kMode_None, mode_); | 112 DCHECK_NE(kMode_None, mode_); |
104 } | 113 } |
105 | 114 |
106 AddressingMode GetMode(AddressingMode one, int power) { | |
107 return static_cast<AddressingMode>(static_cast<int>(one) + power); | |
108 } | |
109 | |
110 size_t SetInputs(InstructionOperand** inputs) { | 115 size_t SetInputs(InstructionOperand** inputs) { |
111 size_t input_count = 0; | 116 size_t input_count = 0; |
112 // Compute inputs_ and input_count. | 117 // Compute inputs_ and input_count. |
113 if (base_operand_ != NULL) { | 118 if (base_operand_ != NULL) { |
114 inputs[input_count++] = base_operand_; | 119 inputs[input_count++] = base_operand_; |
115 } | 120 } |
116 if (index_operand_ != NULL) { | 121 if (index_operand_ != NULL) { |
117 inputs[input_count++] = index_operand_; | 122 inputs[input_count++] = index_operand_; |
118 } | 123 } |
119 if (displacement_operand_ != NULL) { | 124 if (displacement_operand_ != NULL) { |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); | 461 Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); |
457 } else { | 462 } else { |
458 VisitBinop(this, node, kX64Sub); | 463 VisitBinop(this, node, kX64Sub); |
459 } | 464 } |
460 } | 465 } |
461 | 466 |
462 | 467 |
463 static void VisitMul(InstructionSelector* selector, Node* node, | 468 static void VisitMul(InstructionSelector* selector, Node* node, |
464 ArchOpcode opcode) { | 469 ArchOpcode opcode) { |
465 X64OperandGenerator g(selector); | 470 X64OperandGenerator g(selector); |
466 Int32BinopMatcher m(node); | 471 LeaMultiplyMatcher lea(node); |
467 Node* left = m.left().node(); | 472 // Try to match lea. |
468 Node* right = m.right().node(); | 473 if (lea.Matches()) { |
469 if (g.CanBeImmediate(right)) { | 474 switch (opcode) { |
470 selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left), | 475 case kX64Imul32: |
471 g.UseImmediate(right)); | 476 opcode = kX64Lea32; |
| 477 break; |
| 478 case kX64Imul: |
| 479 opcode = kX64Lea; |
| 480 break; |
| 481 default: |
| 482 UNREACHABLE(); |
| 483 } |
| 484 AddressingMode mode; |
| 485 if (lea.Displacement() != 0) { |
| 486 mode = kMode_MX1; |
| 487 } else { |
| 488 mode = kMode_M1; |
| 489 } |
| 490 mode = AdjustAddressingMode(mode, lea.Power()); |
| 491 selector->Emit(opcode | AddressingModeField::encode(mode), |
| 492 g.DefineAsRegister(node), g.UseRegister(lea.Left())); |
472 } else { | 493 } else { |
473 if (g.CanBeBetterLeftOperand(right)) { | 494 Int32BinopMatcher m(node); |
474 std::swap(left, right); | 495 Node* left = m.left().node(); |
| 496 Node* right = m.right().node(); |
| 497 if (g.CanBeImmediate(right)) { |
| 498 selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left), |
| 499 g.UseImmediate(right)); |
| 500 } else { |
| 501 if (g.CanBeBetterLeftOperand(right)) { |
| 502 std::swap(left, right); |
| 503 } |
| 504 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), |
| 505 g.Use(right)); |
475 } | 506 } |
476 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | |
477 g.Use(right)); | |
478 } | 507 } |
479 } | 508 } |
480 | 509 |
481 | 510 |
482 void InstructionSelector::VisitInt32Mul(Node* node) { | 511 void InstructionSelector::VisitInt32Mul(Node* node) { |
483 VisitMul(this, node, kX64Imul32); | 512 VisitMul(this, node, kX64Imul32); |
484 } | 513 } |
485 | 514 |
486 | 515 |
487 void InstructionSelector::VisitInt64Mul(Node* node) { | 516 void InstructionSelector::VisitInt64Mul(Node* node) { |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 call_instr->MarkAsCall(); | 826 call_instr->MarkAsCall(); |
798 if (deoptimization != NULL) { | 827 if (deoptimization != NULL) { |
799 DCHECK(continuation != NULL); | 828 DCHECK(continuation != NULL); |
800 call_instr->MarkAsControl(); | 829 call_instr->MarkAsControl(); |
801 } | 830 } |
802 } | 831 } |
803 | 832 |
804 } // namespace compiler | 833 } // namespace compiler |
805 } // namespace internal | 834 } // namespace internal |
806 } // namespace v8 | 835 } // namespace v8 |
OLD | NEW |