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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.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
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 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 void InstructionSelector::VisitWord32Ror(Node* node) { 427 void InstructionSelector::VisitWord32Ror(Node* node) {
428 VisitWord32Shift(this, node, kX64Ror32); 428 VisitWord32Shift(this, node, kX64Ror32);
429 } 429 }
430 430
431 431
432 void InstructionSelector::VisitWord64Ror(Node* node) { 432 void InstructionSelector::VisitWord64Ror(Node* node) {
433 VisitWord64Shift(this, node, kX64Ror); 433 VisitWord64Shift(this, node, kX64Ror);
434 } 434 }
435 435
436 436
437 static bool TryEmitLeaMultAdd(InstructionSelector* selector, Node* node,
438 ArchOpcode opcode) {
439 int32_t displacement_value;
440 Node* left;
441 {
442 Int32BinopMatcher m32(node);
443 left = m32.left().node();
444 if (m32.right().HasValue()) {
445 displacement_value = m32.right().Value();
446 } else {
447 Int64BinopMatcher m64(node);
448 if (!m64.right().HasValue()) {
449 return false;
450 }
451 int64_t value_64 = m64.right().Value();
452 displacement_value = static_cast<int32_t>(value_64);
453 if (displacement_value != value_64) return false;
454 }
455 }
456 LeaMultiplyMatcher lmm(left);
457 if (!lmm.Matches()) return false;
458 AddressingMode mode;
459 size_t input_count;
460 X64OperandGenerator g(selector);
461 InstructionOperand* index = g.UseRegister(lmm.Left());
462 InstructionOperand* displacement = g.TempImmediate(displacement_value);
463 InstructionOperand* inputs[] = {index, displacement, displacement};
464 if (lmm.Displacement() != 0) {
465 input_count = 3;
466 inputs[1] = index;
467 mode = kMode_MR1I;
468 } else {
469 input_count = 2;
470 mode = kMode_M1I;
471 }
472 mode = AdjustAddressingMode(mode, lmm.Power());
473 InstructionOperand* outputs[] = {g.DefineAsRegister(node)};
474 selector->Emit(opcode | AddressingModeField::encode(mode), 1, outputs,
475 input_count, inputs);
476 return true;
477 }
478
479
437 void InstructionSelector::VisitInt32Add(Node* node) { 480 void InstructionSelector::VisitInt32Add(Node* node) {
481 if (TryEmitLeaMultAdd(this, node, kX64Lea32)) return;
438 VisitBinop(this, node, kX64Add32); 482 VisitBinop(this, node, kX64Add32);
439 } 483 }
440 484
441 485
442 void InstructionSelector::VisitInt64Add(Node* node) { 486 void InstructionSelector::VisitInt64Add(Node* node) {
487 if (TryEmitLeaMultAdd(this, node, kX64Lea)) return;
443 VisitBinop(this, node, kX64Add); 488 VisitBinop(this, node, kX64Add);
444 } 489 }
445 490
446 491
447 void InstructionSelector::VisitInt32Sub(Node* node) { 492 void InstructionSelector::VisitInt32Sub(Node* node) {
448 X64OperandGenerator g(this); 493 X64OperandGenerator g(this);
449 Int32BinopMatcher m(node); 494 Int32BinopMatcher m(node);
450 if (m.left().Is(0)) { 495 if (m.left().Is(0)) {
451 Emit(kX64Neg32, g.DefineSameAsFirst(node), g.Use(m.right().node())); 496 Emit(kX64Neg32, g.DefineSameAsFirst(node), g.Use(m.right().node()));
452 } else { 497 } else {
453 VisitBinop(this, node, kX64Sub32); 498 VisitBinop(this, node, kX64Sub32);
454 } 499 }
455 } 500 }
456 501
457 502
458 void InstructionSelector::VisitInt64Sub(Node* node) { 503 void InstructionSelector::VisitInt64Sub(Node* node) {
459 X64OperandGenerator g(this); 504 X64OperandGenerator g(this);
460 Int64BinopMatcher m(node); 505 Int64BinopMatcher m(node);
461 if (m.left().Is(0)) { 506 if (m.left().Is(0)) {
462 Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); 507 Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node()));
463 } else { 508 } else {
464 VisitBinop(this, node, kX64Sub); 509 VisitBinop(this, node, kX64Sub);
465 } 510 }
466 } 511 }
467 512
468 513
514 static bool TryEmitLeaMult(InstructionSelector* selector, Node* node,
515 ArchOpcode opcode) {
516 LeaMultiplyMatcher lea(node);
517 // Try to match lea.
518 if (!lea.Matches()) return false;
519 AddressingMode mode;
520 size_t input_count;
521 X64OperandGenerator g(selector);
522 InstructionOperand* left = g.UseRegister(lea.Left());
523 InstructionOperand* inputs[] = {left, left};
524 if (lea.Displacement() != 0) {
525 input_count = 2;
526 mode = kMode_MR1;
527 } else {
528 input_count = 1;
529 mode = kMode_M1;
530 }
531 mode = AdjustAddressingMode(mode, lea.Power());
532 InstructionOperand* outputs[] = {g.DefineAsRegister(node)};
533 selector->Emit(opcode | AddressingModeField::encode(mode), 1, outputs,
534 input_count, inputs);
535 return true;
536 }
537
538
469 static void VisitMul(InstructionSelector* selector, Node* node, 539 static void VisitMul(InstructionSelector* selector, Node* node,
470 ArchOpcode opcode) { 540 ArchOpcode opcode) {
471 X64OperandGenerator g(selector); 541 X64OperandGenerator g(selector);
472 LeaMultiplyMatcher lea(node); 542 Int32BinopMatcher m(node);
473 // Try to match lea. 543 Node* left = m.left().node();
474 if (lea.Matches()) { 544 Node* right = m.right().node();
475 switch (opcode) { 545 if (g.CanBeImmediate(right)) {
476 case kX64Imul32: 546 selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left),
477 opcode = kX64Lea32; 547 g.UseImmediate(right));
478 break; 548 } else {
479 case kX64Imul: 549 if (g.CanBeBetterLeftOperand(right)) {
480 opcode = kX64Lea; 550 std::swap(left, right);
481 break;
482 default:
483 UNREACHABLE();
484 } 551 }
485 AddressingMode mode; 552 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
486 size_t input_count; 553 g.Use(right));
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);
500 } else {
501 Int32BinopMatcher m(node);
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));
513 }
514 } 554 }
515 } 555 }
516 556
517 557
518 void InstructionSelector::VisitInt32Mul(Node* node) { 558 void InstructionSelector::VisitInt32Mul(Node* node) {
559 if (TryEmitLeaMult(this, node, kX64Lea32)) return;
519 VisitMul(this, node, kX64Imul32); 560 VisitMul(this, node, kX64Imul32);
520 } 561 }
521 562
522 563
523 void InstructionSelector::VisitInt64Mul(Node* node) { 564 void InstructionSelector::VisitInt64Mul(Node* node) {
565 if (TryEmitLeaMult(this, node, kX64Lea)) return;
524 VisitMul(this, node, kX64Imul); 566 VisitMul(this, node, kX64Imul);
525 } 567 }
526 568
527 569
528 static void VisitDiv(InstructionSelector* selector, Node* node, 570 static void VisitDiv(InstructionSelector* selector, Node* node,
529 ArchOpcode opcode) { 571 ArchOpcode opcode) {
530 X64OperandGenerator g(selector); 572 X64OperandGenerator g(selector);
531 InstructionOperand* temps[] = {g.TempRegister(rdx)}; 573 InstructionOperand* temps[] = {g.TempRegister(rdx)};
532 selector->Emit( 574 selector->Emit(
533 opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax), 575 opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax),
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 call_instr->MarkAsCall(); 873 call_instr->MarkAsCall();
832 if (deoptimization != NULL) { 874 if (deoptimization != NULL) {
833 DCHECK(continuation != NULL); 875 DCHECK(continuation != NULL);
834 call_instr->MarkAsControl(); 876 call_instr->MarkAsControl();
835 } 877 }
836 } 878 }
837 879
838 } // namespace compiler 880 } // namespace compiler
839 } // namespace internal 881 } // namespace internal
840 } // namespace v8 882 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ia32/instruction-selector-ia32.cc ('k') | test/cctest/compiler/test-run-machops.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698