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

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

Issue 614013002: [turbofan] intel lea add multiply matchers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase 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
« no previous file with comments | « no previous file | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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 #include "src/compiler/node-properties-inl.h" 7 #include "src/compiler/node-properties-inl.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 void InstructionSelector::VisitWord32Sar(Node* node) { 360 void InstructionSelector::VisitWord32Sar(Node* node) {
361 VisitShift(this, node, kIA32Sar); 361 VisitShift(this, node, kIA32Sar);
362 } 362 }
363 363
364 364
365 void InstructionSelector::VisitWord32Ror(Node* node) { 365 void InstructionSelector::VisitWord32Ror(Node* node) {
366 VisitShift(this, node, kIA32Ror); 366 VisitShift(this, node, kIA32Ror);
367 } 367 }
368 368
369 369
370 static bool TryEmitLeaMultAdd(InstructionSelector* selector, Node* node) {
371 Int32BinopMatcher m(node);
372 if (!m.right().HasValue()) return false;
373 int32_t displacement_value = m.right().Value();
374 Node* left = m.left().node();
375 LeaMultiplyMatcher lmm(left);
376 if (!lmm.Matches()) return false;
377 AddressingMode mode;
378 size_t input_count;
379 IA32OperandGenerator g(selector);
380 InstructionOperand* index = g.UseRegister(lmm.Left());
381 InstructionOperand* displacement = g.TempImmediate(displacement_value);
382 InstructionOperand* inputs[] = {index, displacement, displacement};
383 if (lmm.Displacement() != 0) {
384 input_count = 3;
385 inputs[1] = index;
386 mode = kMode_MR1I;
387 } else {
388 input_count = 2;
389 mode = kMode_M1I;
390 }
391 mode = AdjustAddressingMode(mode, lmm.Power());
392 InstructionOperand* outputs[] = {g.DefineAsRegister(node)};
393 selector->Emit(kIA32Lea | AddressingModeField::encode(mode), 1, outputs,
394 input_count, inputs);
395 return true;
396 }
397
398
370 void InstructionSelector::VisitInt32Add(Node* node) { 399 void InstructionSelector::VisitInt32Add(Node* node) {
400 if (TryEmitLeaMultAdd(this, node)) return;
371 VisitBinop(this, node, kIA32Add); 401 VisitBinop(this, node, kIA32Add);
372 } 402 }
373 403
374 404
375 void InstructionSelector::VisitInt32Sub(Node* node) { 405 void InstructionSelector::VisitInt32Sub(Node* node) {
376 IA32OperandGenerator g(this); 406 IA32OperandGenerator g(this);
377 Int32BinopMatcher m(node); 407 Int32BinopMatcher m(node);
378 if (m.left().Is(0)) { 408 if (m.left().Is(0)) {
379 Emit(kIA32Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); 409 Emit(kIA32Neg, g.DefineSameAsFirst(node), g.Use(m.right().node()));
380 } else { 410 } else {
381 VisitBinop(this, node, kIA32Sub); 411 VisitBinop(this, node, kIA32Sub);
382 } 412 }
383 } 413 }
384 414
385 415
416 static bool TryEmitLeaMult(InstructionSelector* selector, Node* node) {
417 LeaMultiplyMatcher lea(node);
418 // Try to match lea.
419 if (!lea.Matches()) return false;
420 AddressingMode mode;
421 size_t input_count;
422 IA32OperandGenerator g(selector);
423 InstructionOperand* left = g.UseRegister(lea.Left());
424 InstructionOperand* inputs[] = {left, left};
425 if (lea.Displacement() != 0) {
426 input_count = 2;
427 mode = kMode_MR1;
428 } else {
429 input_count = 1;
430 mode = kMode_M1;
431 }
432 mode = AdjustAddressingMode(mode, lea.Power());
433 InstructionOperand* outputs[] = {g.DefineAsRegister(node)};
434 selector->Emit(kIA32Lea | AddressingModeField::encode(mode), 1, outputs,
435 input_count, inputs);
436 return true;
437 }
438
439
386 void InstructionSelector::VisitInt32Mul(Node* node) { 440 void InstructionSelector::VisitInt32Mul(Node* node) {
441 if (TryEmitLeaMult(this, node)) return;
387 IA32OperandGenerator g(this); 442 IA32OperandGenerator g(this);
388 LeaMultiplyMatcher lea(node); 443 Int32BinopMatcher m(node);
389 // Try to match lea. 444 Node* left = m.left().node();
390 if (lea.Matches()) { 445 Node* right = m.right().node();
391 ArchOpcode opcode = kIA32Lea; 446 if (g.CanBeImmediate(right)) {
392 AddressingMode mode; 447 Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left),
393 size_t input_count; 448 g.UseImmediate(right));
394 InstructionOperand* left = g.UseRegister(lea.Left()); 449 } else {
395 InstructionOperand* inputs[] = {left, left}; 450 if (g.CanBeBetterLeftOperand(right)) {
396 if (lea.Displacement() != 0) { 451 std::swap(left, right);
397 input_count = 2;
398 mode = kMode_MR1;
399 } else {
400 input_count = 1;
401 mode = kMode_M1;
402 } 452 }
403 mode = AdjustAddressingMode(mode, lea.Power()); 453 Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left),
404 InstructionOperand* outputs[] = {g.DefineAsRegister(node)}; 454 g.Use(right));
405 Emit(opcode | AddressingModeField::encode(mode), 1, outputs, input_count,
406 inputs);
407 } else {
408 Int32BinopMatcher m(node);
409 Node* left = m.left().node();
410 Node* right = m.right().node();
411 if (g.CanBeImmediate(right)) {
412 Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left),
413 g.UseImmediate(right));
414 } else {
415 if (g.CanBeBetterLeftOperand(right)) {
416 std::swap(left, right);
417 }
418 Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left),
419 g.Use(right));
420 }
421 } 455 }
422 } 456 }
423 457
424 458
425 static inline void VisitDiv(InstructionSelector* selector, Node* node, 459 static inline void VisitDiv(InstructionSelector* selector, Node* node,
426 ArchOpcode opcode) { 460 ArchOpcode opcode) {
427 IA32OperandGenerator g(selector); 461 IA32OperandGenerator g(selector);
428 InstructionOperand* temps[] = {g.TempRegister(edx)}; 462 InstructionOperand* temps[] = {g.TempRegister(edx)};
429 size_t temp_count = arraysize(temps); 463 size_t temp_count = arraysize(temps);
430 selector->Emit(opcode, g.DefineAsFixed(node, eax), 464 selector->Emit(opcode, g.DefineAsFixed(node, eax),
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 call_instr->MarkAsCall(); 710 call_instr->MarkAsCall();
677 if (deoptimization != NULL) { 711 if (deoptimization != NULL) {
678 DCHECK(continuation != NULL); 712 DCHECK(continuation != NULL);
679 call_instr->MarkAsControl(); 713 call_instr->MarkAsControl();
680 } 714 }
681 } 715 }
682 716
683 } // namespace compiler 717 } // namespace compiler
684 } // namespace internal 718 } // namespace internal
685 } // namespace v8 719 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698