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

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

Issue 644973003: MIPS: [turbofan] Make VisitBranch and friends to backend specific. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add VisitBranch() with UNIMPLEMTED() body 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 | « src/compiler/instruction-selector.cc ('k') | no next file » | 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/base/bits.h" 5 #include "src/base/bits.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 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 Emit(kMipsModD, g.DefineAsFixed(node, f0), g.UseFixed(node->InputAt(0), f12), 394 Emit(kMipsModD, g.DefineAsFixed(node, f0), g.UseFixed(node->InputAt(0), f12),
395 g.UseFixed(node->InputAt(1), f14))->MarkAsCall(); 395 g.UseFixed(node->InputAt(1), f14))->MarkAsCall();
396 } 396 }
397 397
398 398
399 void InstructionSelector::VisitFloat64Sqrt(Node* node) { 399 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
400 MipsOperandGenerator g(this); 400 MipsOperandGenerator g(this);
401 Emit(kMipsSqrtD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); 401 Emit(kMipsSqrtD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
402 } 402 }
403 403
404 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, 404
405 BasicBlock* deoptimization) { 405 void InstructionSelector::VisitCall(Node* node) {
406 MipsOperandGenerator g(this); 406 MipsOperandGenerator g(this);
407 CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call); 407 CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node);
408 408
409 FrameStateDescriptor* frame_state_descriptor = NULL; 409 FrameStateDescriptor* frame_state_descriptor = NULL;
410 if (descriptor->NeedsFrameState()) { 410 if (descriptor->NeedsFrameState()) {
411 frame_state_descriptor = 411 frame_state_descriptor =
412 GetFrameStateDescriptor(call->InputAt(descriptor->InputCount())); 412 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
413 } 413 }
414 414
415 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); 415 CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
416 416
417 // Compute InstructionOperands for inputs and outputs. 417 // Compute InstructionOperands for inputs and outputs.
418 InitializeCallBuffer(call, &buffer, true, false); 418 InitializeCallBuffer(node, &buffer, true, false);
419 419
420 // TODO(dcarney): might be possible to use claim/poke instead 420 // TODO(dcarney): might be possible to use claim/poke instead
421 // Push any stack arguments. 421 // Push any stack arguments.
422 for (NodeVectorRIter input = buffer.pushed_nodes.rbegin(); 422 for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
423 input != buffer.pushed_nodes.rend(); input++) { 423 input != buffer.pushed_nodes.rend(); input++) {
424 // TODO(plind): inefficient for MIPS, use MultiPush here. 424 // TODO(plind): inefficient for MIPS, use MultiPush here.
425 // - Also need to align the stack. See arm64. 425 // - Also need to align the stack. See arm64.
426 // - Maybe combine with arg slot stuff in DirectCEntry stub. 426 // - Maybe combine with arg slot stuff in DirectCEntry stub.
427 Emit(kMipsPush, NULL, g.UseRegister(*input)); 427 Emit(kMipsPush, NULL, g.UseRegister(*input));
428 } 428 }
(...skipping 11 matching lines...) Expand all
440 default: 440 default:
441 UNREACHABLE(); 441 UNREACHABLE();
442 return; 442 return;
443 } 443 }
444 opcode |= MiscField::encode(descriptor->flags()); 444 opcode |= MiscField::encode(descriptor->flags());
445 445
446 // Emit the call instruction. 446 // Emit the call instruction.
447 Instruction* call_instr = 447 Instruction* call_instr =
448 Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(), 448 Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
449 buffer.instruction_args.size(), &buffer.instruction_args.front()); 449 buffer.instruction_args.size(), &buffer.instruction_args.front());
450
451 call_instr->MarkAsCall(); 450 call_instr->MarkAsCall();
452 if (deoptimization != NULL) {
453 DCHECK(continuation != NULL);
454 call_instr->MarkAsControl();
455 }
456 } 451 }
457 452
458 453
459 void InstructionSelector::VisitInt32AddWithOverflow(Node* node, 454 namespace {
460 FlagsContinuation* cont) {
461 VisitBinop(this, node, kMipsAddOvf, cont);
462 }
463
464
465 void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
466 FlagsContinuation* cont) {
467 VisitBinop(this, node, kMipsSubOvf, cont);
468 }
469
470 455
471 // Shared routine for multiple compare operations. 456 // Shared routine for multiple compare operations.
472 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 457 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
473 InstructionOperand* left, InstructionOperand* right, 458 InstructionOperand* left, InstructionOperand* right,
474 FlagsContinuation* cont) { 459 FlagsContinuation* cont) {
475 MipsOperandGenerator g(selector); 460 MipsOperandGenerator g(selector);
476 opcode = cont->Encode(opcode); 461 opcode = cont->Encode(opcode);
477 if (cont->IsBranch()) { 462 if (cont->IsBranch()) {
478 selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), 463 selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
479 g.Label(cont->false_block()))->MarkAsControl(); 464 g.Label(cont->false_block()))->MarkAsControl();
480 } else { 465 } else {
481 DCHECK(cont->IsSet()); 466 DCHECK(cont->IsSet());
482 // TODO(plind): Revisit and test this path. 467 // TODO(plind): Revisit and test this path.
483 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); 468 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
484 } 469 }
485 } 470 }
486 471
487 472
473 // Shared routine for multiple float compare operations.
474 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
475 FlagsContinuation* cont) {
476 MipsOperandGenerator g(selector);
477 Node* left = node->InputAt(0);
478 Node* right = node->InputAt(1);
479 VisitCompare(selector, kMipsCmpD, g.UseRegister(left), g.UseRegister(right),
480 cont);
481 }
482
483
488 // Shared routine for multiple word compare operations. 484 // Shared routine for multiple word compare operations.
489 static void VisitWordCompare(InstructionSelector* selector, Node* node, 485 void VisitWordCompare(InstructionSelector* selector, Node* node,
490 InstructionCode opcode, FlagsContinuation* cont, 486 InstructionCode opcode, FlagsContinuation* cont,
491 bool commutative) { 487 bool commutative) {
492 MipsOperandGenerator g(selector); 488 MipsOperandGenerator g(selector);
493 Node* left = node->InputAt(0); 489 Node* left = node->InputAt(0);
494 Node* right = node->InputAt(1); 490 Node* right = node->InputAt(1);
495 491
496 // Match immediates on left or right side of comparison. 492 // Match immediates on left or right side of comparison.
497 if (g.CanBeImmediate(right, opcode)) { 493 if (g.CanBeImmediate(right, opcode)) {
498 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), 494 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
499 cont); 495 cont);
500 } else if (g.CanBeImmediate(left, opcode)) { 496 } else if (g.CanBeImmediate(left, opcode)) {
501 if (!commutative) cont->Commute(); 497 if (!commutative) cont->Commute();
502 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), 498 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
503 cont); 499 cont);
504 } else { 500 } else {
505 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), 501 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
506 cont); 502 cont);
507 } 503 }
508 } 504 }
509 505
510 506
511 void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) { 507 void VisitWordCompare(InstructionSelector* selector, Node* node,
512 switch (node->opcode()) { 508 FlagsContinuation* cont) {
513 case IrOpcode::kWord32And: 509 VisitWordCompare(selector, node, kMipsCmp, cont, false);
514 // TODO(plind): understand the significance of 'IR and' special case.
515 return VisitWordCompare(this, node, kMipsTst, cont, true);
516 default:
517 break;
518 }
519
520 MipsOperandGenerator g(this);
521 // kMipsTst is a pseudo-instruction to do logical 'and' and leave the result
522 // in a dedicated tmp register.
523 VisitCompare(this, kMipsTst, g.UseRegister(node), g.UseRegister(node), cont);
524 } 510 }
525 511
526 512
527 void InstructionSelector::VisitWord32Compare(Node* node, 513 void VisitWordTest(InstructionSelector* selector, Node* node,
528 FlagsContinuation* cont) { 514 FlagsContinuation* cont) {
529 VisitWordCompare(this, node, kMipsCmp, cont, false); 515 MipsOperandGenerator g(selector);
516 // kMipsTst is a pseudo-instruction to do logical 'and' and leave the result
517 // in a dedicated tmp register.
518 VisitCompare(selector, kMipsTst, g.UseRegister(node), g.UseRegister(node),
519 cont);
520 }
521
522 } // namespace
523
524
525 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
526 BasicBlock* fbranch) {
527 MipsOperandGenerator g(this);
528 Node* user = branch;
529 Node* value = branch->InputAt(0);
530
531 FlagsContinuation cont(kNotEqual, tbranch, fbranch);
532
533 // If we can fall through to the true block, invert the branch.
534 if (IsNextInAssemblyOrder(tbranch)) {
535 cont.Negate();
536 cont.SwapBlocks();
537 }
538
539 // Try to combine with comparisons against 0 by simply inverting the branch.
540 while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
541 Int32BinopMatcher m(value);
542 if (m.right().Is(0)) {
543 user = value;
544 value = m.left().node();
545 cont.Negate();
546 } else {
547 break;
548 }
549 }
550
551 // Try to combine the branch with a comparison.
552 if (CanCover(user, value)) {
553 switch (value->opcode()) {
554 case IrOpcode::kWord32And:
555 // TODO(plind): understand the significance of 'IR and' special case.
556 return VisitWordCompare(this, value, kMipsTst, &cont, true);
557 default:
558 break;
559 }
560 }
561
562 // Branch could not be combined with a compare, emit compare against 0.
563 return VisitWordTest(this, value, &cont);
530 } 564 }
531 565
532 566
533 void InstructionSelector::VisitFloat64Compare(Node* node, 567 void InstructionSelector::VisitWord32Equal(Node* const node) {
534 FlagsContinuation* cont) { 568 Node* const user = node;
535 MipsOperandGenerator g(this); 569 FlagsContinuation cont(kEqual, node);
536 Node* left = node->InputAt(0); 570 Int32BinopMatcher m(user);
537 Node* right = node->InputAt(1); 571 VisitWordCompare(this, node, &cont);
538 VisitCompare(this, kMipsCmpD, g.UseRegister(left), g.UseRegister(right), 572 }
539 cont); 573
574
575 void InstructionSelector::VisitInt32LessThan(Node* node) {
576 FlagsContinuation cont(kSignedLessThan, node);
577 VisitWordCompare(this, node, &cont);
578 }
579
580
581 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
582 FlagsContinuation cont(kSignedLessThanOrEqual, node);
583 VisitWordCompare(this, node, &cont);
584 }
585
586
587 void InstructionSelector::VisitUint32LessThan(Node* node) {
588 FlagsContinuation cont(kUnsignedLessThan, node);
589 VisitWordCompare(this, node, &cont);
590 }
591
592
593 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
594 FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
595 VisitWordCompare(this, node, &cont);
596 }
597
598
599 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
600 if (Node* ovf = node->FindProjection(1)) {
601 FlagsContinuation cont(kOverflow, ovf);
602 return VisitBinop(this, node, kMipsAddOvf, &cont);
603 }
604 FlagsContinuation cont;
605 VisitBinop(this, node, kMipsAdd, &cont);
606 }
607
608
609 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
610 if (Node* ovf = node->FindProjection(1)) {
611 FlagsContinuation cont(kOverflow, ovf);
612 return VisitBinop(this, node, kMipsSubOvf, &cont);
613 }
614 FlagsContinuation cont;
615 VisitBinop(this, node, kMipsSub, &cont);
616 }
617
618
619 void InstructionSelector::VisitFloat64Equal(Node* node) {
620 FlagsContinuation cont(kUnorderedEqual, node);
621 VisitFloat64Compare(this, node, &cont);
622 }
623
624
625 void InstructionSelector::VisitFloat64LessThan(Node* node) {
626 FlagsContinuation cont(kUnorderedLessThan, node);
627 VisitFloat64Compare(this, node, &cont);
628 }
629
630
631 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
632 FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
633 VisitFloat64Compare(this, node, &cont);
540 } 634 }
541 635
542 } // namespace compiler 636 } // namespace compiler
543 } // namespace internal 637 } // namespace internal
544 } // namespace v8 638 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698