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