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