Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(776)

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 615483003: [turbofan] x64 lea multiplication matching (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/x64/instruction-codes-x64.h ('k') | src/compiler/x64/instruction-selector-x64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698