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