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

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 64483002: Streamline code generator for branches and comparisons. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: added other platformd, comments addressed Created 7 years, 1 month 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 | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/intermediate_language_ia32.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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 case HI: return CC; 441 case HI: return CC;
442 case CS: return LS; 442 case CS: return LS;
443 default: 443 default:
444 UNREACHABLE(); 444 UNREACHABLE();
445 return EQ; 445 return EQ;
446 } 446 }
447 } 447 }
448 448
449 449
450 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, 450 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
451 TargetEntryInstr* true_successor, 451 Condition true_condition,
452 TargetEntryInstr* false_successor, 452 BranchLabels labels) {
453 Condition true_condition) { 453 if (labels.fall_through == labels.false_label) {
454 if (compiler->CanFallThroughTo(false_successor)) {
455 // If the next block is the false successor we will fall through to it. 454 // If the next block is the false successor we will fall through to it.
456 __ b(compiler->GetJumpLabel(true_successor), true_condition); 455 __ b(labels.true_label, true_condition);
457 } else { 456 } else {
458 // If the next block is not the false successor we will branch to it. 457 // If the next block is not the false successor we will branch to it.
459 Condition false_condition = NegateCondition(true_condition); 458 Condition false_condition = NegateCondition(true_condition);
460 __ b(compiler->GetJumpLabel(false_successor), false_condition); 459 __ b(labels.false_label, false_condition);
461 460
462 // Fall through or jump to the true successor. 461 // Fall through or jump to the true successor.
463 if (!compiler->CanFallThroughTo(true_successor)) { 462 if (labels.fall_through != labels.true_label) {
464 __ b(compiler->GetJumpLabel(true_successor)); 463 __ b(labels.true_label);
465 } 464 }
466 } 465 }
467 } 466 }
468 467
469 468
470 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 469 static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
471 const LocationSummary& locs, 470 LocationSummary* locs,
472 Token::Kind kind, 471 Token::Kind kind) {
473 BranchInstr* branch) { 472 Location left = locs->in(0);
474 Location left = locs.in(0); 473 Location right = locs->in(1);
475 Location right = locs.in(1);
476 ASSERT(!left.IsConstant() || !right.IsConstant()); 474 ASSERT(!left.IsConstant() || !right.IsConstant());
477 475
478 Condition true_condition = TokenKindToSmiCondition(kind); 476 Condition true_condition = TokenKindToSmiCondition(kind);
479 477
480 if (left.IsConstant()) { 478 if (left.IsConstant()) {
481 __ CompareObject(right.reg(), left.constant()); 479 __ CompareObject(right.reg(), left.constant());
482 true_condition = FlipCondition(true_condition); 480 true_condition = FlipCondition(true_condition);
483 } else if (right.IsConstant()) { 481 } else if (right.IsConstant()) {
484 __ CompareObject(left.reg(), right.constant()); 482 __ CompareObject(left.reg(), right.constant());
485 } else { 483 } else {
486 __ cmp(left.reg(), ShifterOperand(right.reg())); 484 __ cmp(left.reg(), ShifterOperand(right.reg()));
487 } 485 }
488 486 return true_condition;
489 if (branch != NULL) {
490 EmitBranchOnCondition(compiler,
491 branch->true_successor(),
492 branch->false_successor(),
493 true_condition);
494 } else {
495 Register result = locs.out().reg();
496 __ LoadObject(result, Bool::True(), true_condition);
497 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
498 }
499 }
500
501
502 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
503 const LocationSummary& locs,
504 Token::Kind kind,
505 BranchInstr* branch) {
506 UNIMPLEMENTED();
507 }
508
509
510 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
511 const LocationSummary& locs,
512 Token::Kind kind,
513 BranchInstr* branch) {
514 UNIMPLEMENTED();
515 } 487 }
516 488
517 489
518 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 490 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
519 switch (kind) { 491 switch (kind) {
520 case Token::kEQ: return EQ; 492 case Token::kEQ: return EQ;
521 case Token::kNE: return NE; 493 case Token::kNE: return NE;
522 case Token::kLT: return LT; 494 case Token::kLT: return LT;
523 case Token::kGT: return GT; 495 case Token::kGT: return GT;
524 case Token::kLTE: return LE; 496 case Token::kLTE: return LE;
525 case Token::kGTE: return GE; 497 case Token::kGTE: return GE;
526 default: 498 default:
527 UNREACHABLE(); 499 UNREACHABLE();
528 return VS; 500 return VS;
529 } 501 }
530 } 502 }
531 503
532 504
533 static void EmitDoubleCompareBranch(FlowGraphCompiler* compiler, 505 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
534 Condition true_condition, 506 LocationSummary* locs) {
535 FpuRegister left, 507 QRegister left = locs->in(0).fpu_reg();
536 FpuRegister right, 508 QRegister right = locs->in(1).fpu_reg();
537 BranchInstr* branch) {
538 ASSERT(branch != NULL);
539 DRegister dleft = EvenDRegisterOf(left); 509 DRegister dleft = EvenDRegisterOf(left);
540 DRegister dright = EvenDRegisterOf(right); 510 DRegister dright = EvenDRegisterOf(right);
541 __ vcmpd(dleft, dright); 511 __ vcmpd(dleft, dright);
542 __ vmstat(); 512 __ vmstat();
543 BlockEntryInstr* nan_result = (true_condition == NE) ?
544 branch->true_successor() : branch->false_successor();
545 __ b(compiler->GetJumpLabel(nan_result), VS);
546 EmitBranchOnCondition(compiler,
547 branch->true_successor(),
548 branch->false_successor(),
549 true_condition);
550 }
551
552
553 static void EmitDoubleCompareBool(FlowGraphCompiler* compiler,
554 Condition true_condition,
555 FpuRegister left,
556 FpuRegister right,
557 Register result) {
558 DRegister dleft = EvenDRegisterOf(left);
559 DRegister dright = EvenDRegisterOf(right);
560 __ vcmpd(dleft, dright);
561 __ vmstat();
562 __ LoadObject(result, Bool::False());
563 Label done;
564 if (true_condition != NE) {
565 __ b(&done, VS); // x == NaN -> false, x != NaN -> true.
566 }
567 __ LoadObject(result, Bool::True(), true_condition);
568 __ Bind(&done);
569 }
570
571
572 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
573 const LocationSummary& locs,
574 Token::Kind kind,
575 BranchInstr* branch) {
576 QRegister left = locs.in(0).fpu_reg();
577 QRegister right = locs.in(1).fpu_reg();
578
579 Condition true_condition = TokenKindToDoubleCondition(kind);
580 if (branch != NULL) {
581 EmitDoubleCompareBranch(compiler, true_condition, left, right, branch);
582 } else {
583 EmitDoubleCompareBool(compiler, true_condition,
584 left, right, locs.out().reg());
585 }
586 } 513 }
587 514
588 515
589 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 516 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
590 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 517 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
591 BranchInstr* kNoBranch = NULL; 518
592 if (operation_cid() == kSmiCid) { 519 if (operation_cid() == kSmiCid) {
593 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); 520 Condition true_condition = EmitSmiComparisonOp(compiler, locs(), kind());
594 return; 521 Register result = locs()->out().reg();
522 __ LoadObject(result, Bool::True(), true_condition);
Florian Schneider 2013/11/11 13:30:42 The ARM code differs slightly from the other platf
523 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
524 } else {
525 ASSERT(operation_cid() == kDoubleCid);
526 EmitDoubleComparisonOp(compiler, locs());
527
528 Register result = locs()->out().reg();
529 Condition true_condition = TokenKindToDoubleCondition(kind());
530 Label done;
531 __ LoadObject(result, Bool::False());
532 if (true_condition != NE) {
533 __ b(&done, VS); // x == NaN -> false, x != NaN -> true.
534 }
535 __ LoadObject(result, Bool::True(), true_condition);
536 __ Bind(&done);
595 } 537 }
596 if (operation_cid() == kMintCid) {
597 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch);
598 return;
599 }
600 if (operation_cid() == kDoubleCid) {
601 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
602 return;
603 }
604 UNREACHABLE();
605 } 538 }
606 539
607 540
608 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 541 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
609 BranchInstr* branch) { 542 BranchInstr* branch) {
610 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 543 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
544
545 BranchLabels labels = compiler->CreateBranchLabels(branch);
546
547 Condition true_condition = kNoCondition;
611 if (operation_cid() == kSmiCid) { 548 if (operation_cid() == kSmiCid) {
612 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 549 true_condition = EmitSmiComparisonOp(compiler, locs(), kind());
613 return; 550 } else {
551 ASSERT(operation_cid() == kDoubleCid);
552 true_condition = TokenKindToDoubleCondition(kind());
553 EmitDoubleComparisonOp(compiler, locs());
554
555 Label* nan_result = (true_condition == NE) ?
556 labels.true_label : labels.false_label;
557 __ b(nan_result, VS);
614 } 558 }
615 if (operation_cid() == kMintCid) { 559 EmitBranchOnCondition(compiler, true_condition, labels);
616 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
617 return;
618 }
619 if (operation_cid() == kDoubleCid) {
620 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
621 return;
622 }
623 UNREACHABLE();
624 } 560 }
625 561
626 562
627 LocationSummary* TestSmiInstr::MakeLocationSummary() const { 563 LocationSummary* TestSmiInstr::MakeLocationSummary() const {
628 const intptr_t kNumInputs = 2; 564 const intptr_t kNumInputs = 2;
629 const intptr_t kNumTemps = 0; 565 const intptr_t kNumTemps = 0;
630 LocationSummary* locs = 566 LocationSummary* locs =
631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 567 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
632 locs->set_in(0, Location::RequiresRegister()); 568 locs->set_in(0, Location::RequiresRegister());
633 // Only one input can be a constant operand. The case of two constant 569 // Only one input can be a constant operand. The case of two constant
634 // operands should be handled by constant propagation. 570 // operands should be handled by constant propagation.
635 locs->set_in(1, Location::RegisterOrConstant(right())); 571 locs->set_in(1, Location::RegisterOrConstant(right()));
636 return locs; 572 return locs;
637 } 573 }
638 574
639 575
640 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 576 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
641 // Never emitted outside of the BranchInstr. 577 // Never emitted outside of the BranchInstr.
642 UNREACHABLE(); 578 UNREACHABLE();
643 } 579 }
644 580
645 581
646 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, 582 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
647 BranchInstr* branch) { 583 BranchInstr* branch) {
648 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; 584 BranchLabels labels = compiler->CreateBranchLabels(branch);
585
586 Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
649 Register left = locs()->in(0).reg(); 587 Register left = locs()->in(0).reg();
650 Location right = locs()->in(1); 588 Location right = locs()->in(1);
651 if (right.IsConstant()) { 589 if (right.IsConstant()) {
652 ASSERT(right.constant().IsSmi()); 590 ASSERT(right.constant().IsSmi());
653 const int32_t imm = 591 const int32_t imm =
654 reinterpret_cast<int32_t>(right.constant().raw()); 592 reinterpret_cast<int32_t>(right.constant().raw());
655 __ TestImmediate(left, imm); 593 __ TestImmediate(left, imm);
656 } else { 594 } else {
657 __ tst(left, ShifterOperand(right.reg())); 595 __ tst(left, ShifterOperand(right.reg()));
658 } 596 }
659 EmitBranchOnCondition(compiler, 597 EmitBranchOnCondition(compiler, true_condition, labels);
660 branch->true_successor(),
661 branch->false_successor(),
662 branch_condition);
663 } 598 }
664 599
665 600
666 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 601 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
667 const intptr_t kNumInputs = 2; 602 const intptr_t kNumInputs = 2;
668 const intptr_t kNumTemps = 0; 603 const intptr_t kNumTemps = 0;
669 if (operation_cid() == kMintCid) { 604 if (operation_cid() == kMintCid) {
670 const intptr_t kNumTemps = 2; 605 const intptr_t kNumTemps = 2;
671 LocationSummary* locs = 606 LocationSummary* locs =
672 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 607 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 21 matching lines...) Expand all
694 summary->set_in(1, summary->in(0).IsConstant() 629 summary->set_in(1, summary->in(0).IsConstant()
695 ? Location::RequiresRegister() 630 ? Location::RequiresRegister()
696 : Location::RegisterOrConstant(right())); 631 : Location::RegisterOrConstant(right()));
697 summary->set_out(Location::RequiresRegister()); 632 summary->set_out(Location::RequiresRegister());
698 return summary; 633 return summary;
699 } 634 }
700 635
701 636
702 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 637 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
703 if (operation_cid() == kSmiCid) { 638 if (operation_cid() == kSmiCid) {
704 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 639 Condition true_condition = EmitSmiComparisonOp(compiler, locs(), kind());
705 return; 640 Register result = locs()->out().reg();
641 __ LoadObject(result, Bool::True(), true_condition);
642 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
643 } else {
644 ASSERT(operation_cid() == kDoubleCid);
645 EmitDoubleComparisonOp(compiler, locs());
646
647 Register result = locs()->out().reg();
648 Condition true_condition = TokenKindToDoubleCondition(kind());
649 Label done;
650 __ LoadObject(result, Bool::False());
651 if (true_condition != NE) {
652 __ b(&done, VS); // x == NaN -> false, x != NaN -> true.
653 }
654 __ LoadObject(result, Bool::True(), true_condition);
655 __ Bind(&done);
706 } 656 }
707 if (operation_cid() == kMintCid) {
708 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
709 return;
710 }
711 ASSERT(operation_cid() == kDoubleCid);
712 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
713 } 657 }
714 658
715 659
716 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 660 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
717 BranchInstr* branch) { 661 BranchInstr* branch) {
662 BranchLabels labels = compiler->CreateBranchLabels(branch);
663
664 Condition true_condition = kNoCondition;
718 if (operation_cid() == kSmiCid) { 665 if (operation_cid() == kSmiCid) {
719 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 666 true_condition = EmitSmiComparisonOp(compiler, locs(), kind());
720 return; 667 } else {
668 ASSERT(operation_cid() == kDoubleCid);
669 true_condition = TokenKindToDoubleCondition(kind());
670 EmitDoubleComparisonOp(compiler, locs());
671
672 Label* nan_result = (true_condition == NE) ?
673 labels.true_label : labels.false_label;
674 __ b(nan_result, VS);
721 } 675 }
722 if (operation_cid() == kMintCid) { 676 EmitBranchOnCondition(compiler, true_condition, labels);
723 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
724 return;
725 }
726 ASSERT(operation_cid() == kDoubleCid);
727 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
728 } 677 }
729 678
730 679
731 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 680 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
732 const intptr_t kNumInputs = 0; 681 const intptr_t kNumInputs = 0;
733 const intptr_t kNumTemps = 3; 682 const intptr_t kNumTemps = 3;
734 LocationSummary* locs = 683 LocationSummary* locs =
735 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 684 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
736 locs->set_temp(0, Location::RegisterLocation(R1)); 685 locs->set_temp(0, Location::RegisterLocation(R1));
737 locs->set_temp(1, Location::RegisterLocation(R2)); 686 locs->set_temp(1, Location::RegisterLocation(R2));
(...skipping 3734 matching lines...) Expand 10 before | Expand all | Expand 10 after
4472 // Only one of the inputs can be a constant. Choose register if the first one 4421 // Only one of the inputs can be a constant. Choose register if the first one
4473 // is a constant. 4422 // is a constant.
4474 locs->set_in(1, locs->in(0).IsConstant() 4423 locs->set_in(1, locs->in(0).IsConstant()
4475 ? Location::RequiresRegister() 4424 ? Location::RequiresRegister()
4476 : Location::RegisterOrConstant(right())); 4425 : Location::RegisterOrConstant(right()));
4477 locs->set_out(Location::RequiresRegister()); 4426 locs->set_out(Location::RequiresRegister());
4478 return locs; 4427 return locs;
4479 } 4428 }
4480 4429
4481 4430
4431 static void EmitStrictComparison(FlowGraphCompiler* compiler,
4432 StrictCompareInstr* compare) {
4433 LocationSummary* locs = compare->locs();
4434 bool needs_number_check = compare->needs_number_check();
4435 intptr_t token_pos = compare->token_pos();
4436 Location left = locs->in(0);
4437 Location right = locs->in(1);
4438 ASSERT(!left.IsConstant() || !right.IsConstant());
4439 if (left.IsConstant()) {
4440 compiler->EmitEqualityRegConstCompare(right.reg(),
4441 left.constant(),
4442 needs_number_check,
4443 token_pos);
4444 } else if (right.IsConstant()) {
4445 compiler->EmitEqualityRegConstCompare(left.reg(),
4446 right.constant(),
4447 needs_number_check,
4448 token_pos);
4449 } else {
4450 compiler->EmitEqualityRegRegCompare(left.reg(),
4451 right.reg(),
4452 needs_number_check,
4453 token_pos);
4454 }
4455 }
4456
4457
4482 // Special code for numbers (compare values instead of references.) 4458 // Special code for numbers (compare values instead of references.)
4483 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4459 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4484 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4460 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4485 Location left = locs()->in(0); 4461
4486 Location right = locs()->in(1); 4462 EmitStrictComparison(compiler, this);
4487 ASSERT(!left.IsConstant() || !right.IsConstant());
4488 if (left.IsConstant()) {
4489 compiler->EmitEqualityRegConstCompare(right.reg(),
4490 left.constant(),
4491 needs_number_check(),
4492 token_pos());
4493 } else if (right.IsConstant()) {
4494 compiler->EmitEqualityRegConstCompare(left.reg(),
4495 right.constant(),
4496 needs_number_check(),
4497 token_pos());
4498 } else {
4499 compiler->EmitEqualityRegRegCompare(left.reg(),
4500 right.reg(),
4501 needs_number_check(),
4502 token_pos());
4503 }
4504 4463
4505 Register result = locs()->out().reg(); 4464 Register result = locs()->out().reg();
4506 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; 4465 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
4507 __ LoadObject(result, Bool::True(), true_condition); 4466 __ LoadObject(result, Bool::True(), true_condition);
4508 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); 4467 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
4509 } 4468 }
4510 4469
4511 4470
4512 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 4471 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
4513 BranchInstr* branch) { 4472 BranchInstr* branch) {
4514 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4473 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4515 Location left = locs()->in(0);
4516 Location right = locs()->in(1);
4517 ASSERT(!left.IsConstant() || !right.IsConstant());
4518 if (left.IsConstant()) {
4519 compiler->EmitEqualityRegConstCompare(right.reg(),
4520 left.constant(),
4521 needs_number_check(),
4522 token_pos());
4523 } else if (right.IsConstant()) {
4524 compiler->EmitEqualityRegConstCompare(left.reg(),
4525 right.constant(),
4526 needs_number_check(),
4527 token_pos());
4528 } else {
4529 compiler->EmitEqualityRegRegCompare(left.reg(),
4530 right.reg(),
4531 needs_number_check(),
4532 token_pos());
4533 }
4534 4474
4475 EmitStrictComparison(compiler, this);
4476
4477 BranchLabels labels = compiler->CreateBranchLabels(branch);
4535 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; 4478 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
4536 EmitBranchOnCondition(compiler, 4479 EmitBranchOnCondition(compiler, true_condition, labels);
4537 branch->true_successor(),
4538 branch->false_successor(),
4539 true_condition);
4540 } 4480 }
4541 4481
4542 4482
4543 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 4483 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
4544 return LocationSummary::Make(1, 4484 return LocationSummary::Make(1,
4545 Location::RequiresRegister(), 4485 Location::RequiresRegister(),
4546 LocationSummary::kNoCall); 4486 LocationSummary::kNoCall);
4547 } 4487 }
4548 4488
4549 4489
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
4613 compiler->GenerateCall(token_pos(), 4553 compiler->GenerateCall(token_pos(),
4614 &label, 4554 &label,
4615 PcDescriptors::kOther, 4555 PcDescriptors::kOther,
4616 locs()); 4556 locs());
4617 __ Drop(2); // Discard type arguments and receiver. 4557 __ Drop(2); // Discard type arguments and receiver.
4618 } 4558 }
4619 4559
4620 } // namespace dart 4560 } // namespace dart
4621 4561
4622 #endif // defined TARGET_ARCH_ARM 4562 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698