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

Side by Side Diff: runtime/vm/intermediate_language_x64.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
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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 case ABOVE: return BELOW; 403 case ABOVE: return BELOW;
404 case ABOVE_EQUAL: return BELOW_EQUAL; 404 case ABOVE_EQUAL: return BELOW_EQUAL;
405 default: 405 default:
406 UNIMPLEMENTED(); 406 UNIMPLEMENTED();
407 return EQUAL; 407 return EQUAL;
408 } 408 }
409 } 409 }
410 410
411 411
412 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, 412 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
413 TargetEntryInstr* true_successor, 413 Condition true_condition,
414 TargetEntryInstr* false_successor, 414 BranchLabels labels) {
415 Condition true_condition) { 415 if (labels.fall_through == labels.false_label) {
416 if (compiler->CanFallThroughTo(false_successor)) {
417 // If the next block is the false successor, fall through to it. 416 // If the next block is the false successor, fall through to it.
418 __ j(true_condition, compiler->GetJumpLabel(true_successor)); 417 __ j(true_condition, labels.true_label);
419 } else { 418 } else {
420 // If the next block is not the false successor, branch to it. 419 // If the next block is not the false successor, branch to it.
421 Condition false_condition = NegateCondition(true_condition); 420 Condition false_condition = NegateCondition(true_condition);
422 __ j(false_condition, compiler->GetJumpLabel(false_successor)); 421 __ j(false_condition, labels.false_label);
423 422
424 // Fall through or jump to the true successor. 423 // Fall through or jump to the true successor.
425 if (!compiler->CanFallThroughTo(true_successor)) { 424 if (labels.fall_through != labels.true_label) {
426 __ jmp(compiler->GetJumpLabel(true_successor)); 425 __ jmp(labels.true_label);
427 } 426 }
428 } 427 }
429 } 428 }
430 429
431 430
432 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 431 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
433 const LocationSummary& locs, 432 const LocationSummary& locs,
434 Token::Kind kind, 433 Token::Kind kind,
435 BranchInstr* branch) { 434 BranchLabels labels) {
436 Location left = locs.in(0); 435 Location left = locs.in(0);
437 Location right = locs.in(1); 436 Location right = locs.in(1);
438 ASSERT(!left.IsConstant() || !right.IsConstant()); 437 ASSERT(!left.IsConstant() || !right.IsConstant());
439 438
440 Condition true_condition = TokenKindToSmiCondition(kind); 439 Condition true_condition = TokenKindToSmiCondition(kind);
441 440
442 if (left.IsConstant()) { 441 if (left.IsConstant()) {
443 __ CompareObject(right.reg(), left.constant(), PP); 442 __ CompareObject(right.reg(), left.constant(), PP);
444 true_condition = FlipCondition(true_condition); 443 true_condition = FlipCondition(true_condition);
445 } else if (right.IsConstant()) { 444 } else if (right.IsConstant()) {
446 __ CompareObject(left.reg(), right.constant(), PP); 445 __ CompareObject(left.reg(), right.constant(), PP);
447 } else if (right.IsStackSlot()) { 446 } else if (right.IsStackSlot()) {
448 __ cmpq(left.reg(), right.ToStackSlotAddress()); 447 __ cmpq(left.reg(), right.ToStackSlotAddress());
449 } else { 448 } else {
450 __ cmpq(left.reg(), right.reg()); 449 __ cmpq(left.reg(), right.reg());
451 } 450 }
452 451 EmitBranchOnCondition(compiler, true_condition, labels);
453 if (branch != NULL) {
454 EmitBranchOnCondition(compiler,
455 branch->true_successor(),
456 branch->false_successor(),
457 true_condition);
458 } else {
459 Register result = locs.out().reg();
460 Label done, is_true;
461 __ j(true_condition, &is_true);
462 __ LoadObject(result, Bool::False(), PP);
463 __ jmp(&done);
464 __ Bind(&is_true);
465 __ LoadObject(result, Bool::True(), PP);
466 __ Bind(&done);
467 }
468 } 452 }
469 453
470 454
471 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 455 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
472 switch (kind) { 456 switch (kind) {
473 case Token::kEQ: return EQUAL; 457 case Token::kEQ: return EQUAL;
474 case Token::kNE: return NOT_EQUAL; 458 case Token::kNE: return NOT_EQUAL;
475 case Token::kLT: return BELOW; 459 case Token::kLT: return BELOW;
476 case Token::kGT: return ABOVE; 460 case Token::kGT: return ABOVE;
477 case Token::kLTE: return BELOW_EQUAL; 461 case Token::kLTE: return BELOW_EQUAL;
478 case Token::kGTE: return ABOVE_EQUAL; 462 case Token::kGTE: return ABOVE_EQUAL;
479 default: 463 default:
480 UNREACHABLE(); 464 UNREACHABLE();
481 return OVERFLOW; 465 return OVERFLOW;
482 } 466 }
483 } 467 }
484 468
485 469
486 static void EmitDoubleCompareBranch(FlowGraphCompiler* compiler, 470 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
487 Condition true_condition, 471 const LocationSummary& locs,
488 FpuRegister left, 472 Token::Kind kind,
489 FpuRegister right, 473 BranchLabels labels) {
490 BranchInstr* branch) { 474 XmmRegister left = locs.in(0).fpu_reg();
491 ASSERT(branch != NULL); 475 XmmRegister right = locs.in(1).fpu_reg();
476
492 __ comisd(left, right); 477 __ comisd(left, right);
493 BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ? 478
494 branch->true_successor() : branch->false_successor(); 479 Condition true_condition = TokenKindToDoubleCondition(kind);
495 __ j(PARITY_EVEN, compiler->GetJumpLabel(nan_result)); 480 Label* nan_result = (true_condition == NOT_EQUAL)
496 EmitBranchOnCondition(compiler, 481 ? labels.true_label : labels.false_label;
497 branch->true_successor(), 482 __ j(PARITY_EVEN, nan_result);
498 branch->false_successor(), 483 EmitBranchOnCondition(compiler, true_condition, labels);
499 true_condition);
500 } 484 }
501 485
502 486
503 static void EmitDoubleCompareBool(FlowGraphCompiler* compiler, 487 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
504 Condition true_condition, 488 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
505 FpuRegister left, 489
506 FpuRegister right, 490 Label is_true, is_false;
507 Register result) { 491 BranchLabels labels = { &is_true, &is_false, &is_false };
508 __ comisd(left, right); 492
509 Label is_false, is_true, done; 493 if (operation_cid() == kSmiCid) {
510 // x == NaN -> false, x != NaN -> true. 494 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
511 Label* nan_label = (true_condition == NOT_EQUAL) ? &is_true : &is_false; 495 } else {
512 __ j(PARITY_EVEN, nan_label, Assembler::kNearJump); 496 ASSERT(operation_cid() == kDoubleCid);
513 __ j(true_condition, &is_true, Assembler::kNearJump); 497 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
498 }
499 Register result = locs()->out().reg();
500 Label done;
514 __ Bind(&is_false); 501 __ Bind(&is_false);
515 __ LoadObject(result, Bool::False(), PP); 502 __ LoadObject(result, Bool::False(), PP);
516 __ jmp(&done); 503 __ jmp(&done);
517 __ Bind(&is_true); 504 __ Bind(&is_true);
518 __ LoadObject(result, Bool::True(), PP); 505 __ LoadObject(result, Bool::True(), PP);
519 __ Bind(&done); 506 __ Bind(&done);
520 } 507 }
521 508
522 509
523 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 510 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
524 const LocationSummary& locs, 511 BranchInstr* branch) {
525 Token::Kind kind, 512 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
526 BranchInstr* branch) {
527 XmmRegister left = locs.in(0).fpu_reg();
528 XmmRegister right = locs.in(1).fpu_reg();
529 513
530 Condition true_condition = TokenKindToDoubleCondition(kind); 514 BranchLabels labels = compiler->CreateBranchLabels(branch);
531 if (branch != NULL) { 515
532 EmitDoubleCompareBranch(compiler, true_condition, left, right, branch); 516 if (operation_cid() == kSmiCid) {
533 } else { 517 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
534 EmitDoubleCompareBool(compiler, true_condition, 518 } else {
535 left, right, locs.out().reg()); 519 ASSERT(operation_cid() == kDoubleCid);
520 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
536 } 521 }
537 } 522 }
538 523
539 524
540 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
541 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
542 BranchInstr* kNoBranch = NULL;
543 if (operation_cid() == kSmiCid) {
544 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
545 return;
546 }
547 if (operation_cid() == kDoubleCid) {
548 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
549 return;
550 }
551 UNREACHABLE();
552 }
553
554
555 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
556 BranchInstr* branch) {
557 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
558 if (operation_cid() == kSmiCid) {
559 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
560 return;
561 }
562 if (operation_cid() == kDoubleCid) {
563 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
564 return;
565 }
566 UNREACHABLE();
567 }
568
569
570 LocationSummary* TestSmiInstr::MakeLocationSummary() const { 525 LocationSummary* TestSmiInstr::MakeLocationSummary() const {
571 const intptr_t kNumInputs = 2; 526 const intptr_t kNumInputs = 2;
572 const intptr_t kNumTemps = 0; 527 const intptr_t kNumTemps = 0;
573 LocationSummary* locs = 528 LocationSummary* locs =
574 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 529 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
575 locs->set_in(0, Location::RequiresRegister()); 530 locs->set_in(0, Location::RequiresRegister());
576 // Only one input can be a constant operand. The case of two constant 531 // Only one input can be a constant operand. The case of two constant
577 // operands should be handled by constant propagation. 532 // operands should be handled by constant propagation.
578 locs->set_in(1, Location::RegisterOrConstant(right())); 533 locs->set_in(1, Location::RegisterOrConstant(right()));
579 return locs; 534 return locs;
580 } 535 }
581 536
582 537
583 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 538 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
584 // Never emitted outside of the BranchInstr. 539 // Never emitted outside of the BranchInstr.
585 UNREACHABLE(); 540 UNREACHABLE();
586 } 541 }
587 542
588 543
589 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, 544 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
590 BranchInstr* branch) { 545 BranchInstr* branch) {
546 BranchLabels labels = compiler->CreateBranchLabels(branch);
547
591 Condition branch_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; 548 Condition branch_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
592 Register left_reg = locs()->in(0).reg(); 549 Register left_reg = locs()->in(0).reg();
593 Location right = locs()->in(1); 550 Location right = locs()->in(1);
594 if (right.IsConstant()) { 551 if (right.IsConstant()) {
595 ASSERT(right.constant().IsSmi()); 552 ASSERT(right.constant().IsSmi());
596 const int64_t imm = 553 const int64_t imm =
597 reinterpret_cast<int64_t>(right.constant().raw()); 554 reinterpret_cast<int64_t>(right.constant().raw());
598 __ TestImmediate(left_reg, Immediate(imm), PP); 555 __ TestImmediate(left_reg, Immediate(imm), PP);
599 } else { 556 } else {
600 __ testq(left_reg, right.reg()); 557 __ testq(left_reg, right.reg());
601 } 558 }
602 EmitBranchOnCondition(compiler, 559 EmitBranchOnCondition(compiler, branch_condition, labels);
603 branch->true_successor(),
604 branch->false_successor(),
605 branch_condition);
606 } 560 }
607 561
608 562
609 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 563 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
610 const intptr_t kNumInputs = 2; 564 const intptr_t kNumInputs = 2;
611 const intptr_t kNumTemps = 0; 565 const intptr_t kNumTemps = 0;
612 if (operation_cid() == kDoubleCid) { 566 if (operation_cid() == kDoubleCid) {
613 LocationSummary* summary = 567 LocationSummary* summary =
614 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 568 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
615 summary->set_in(0, Location::RequiresFpuRegister()); 569 summary->set_in(0, Location::RequiresFpuRegister());
616 summary->set_in(1, Location::RequiresFpuRegister()); 570 summary->set_in(1, Location::RequiresFpuRegister());
617 summary->set_out(Location::RequiresRegister()); 571 summary->set_out(Location::RequiresRegister());
618 return summary; 572 return summary;
619 } 573 }
620 ASSERT(operation_cid() == kSmiCid); 574 ASSERT(operation_cid() == kSmiCid);
621 LocationSummary* summary = 575 LocationSummary* summary =
622 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 576 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
623 summary->set_in(0, Location::RegisterOrConstant(left())); 577 summary->set_in(0, Location::RegisterOrConstant(left()));
624 // Only one input can be a constant operand. The case of two constant 578 // Only one input can be a constant operand. The case of two constant
625 // operands should be handled by constant propagation. 579 // operands should be handled by constant propagation.
626 summary->set_in(1, summary->in(0).IsConstant() 580 summary->set_in(1, summary->in(0).IsConstant()
627 ? Location::RequiresRegister() 581 ? Location::RequiresRegister()
628 : Location::RegisterOrConstant(right())); 582 : Location::RegisterOrConstant(right()));
629 summary->set_out(Location::RequiresRegister()); 583 summary->set_out(Location::RequiresRegister());
630 return summary; 584 return summary;
631 } 585 }
632 586
633 587
634 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 588 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
589 Label is_true, is_false;
590 BranchLabels labels = { &is_true, &is_false, &is_false };
591
635 if (operation_cid() == kSmiCid) { 592 if (operation_cid() == kSmiCid) {
636 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 593 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
637 return; 594 } else {
595 ASSERT(operation_cid() == kDoubleCid);
596 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
638 } 597 }
639 ASSERT(operation_cid() == kDoubleCid); 598 Register result = locs()->out().reg();
640 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); 599 Label done;
600 __ Bind(&is_false);
601 __ LoadObject(result, Bool::False(), PP);
602 __ jmp(&done);
603 __ Bind(&is_true);
604 __ LoadObject(result, Bool::True(), PP);
605 __ Bind(&done);
641 } 606 }
642 607
643 608
644 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 609 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
645 BranchInstr* branch) { 610 BranchInstr* branch) {
611 BranchLabels labels = compiler->CreateBranchLabels(branch);
612
646 if (operation_cid() == kSmiCid) { 613 if (operation_cid() == kSmiCid) {
647 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 614 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
648 return; 615 } else {
616 ASSERT(operation_cid() == kDoubleCid);
617 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
649 } 618 }
650 ASSERT(operation_cid() == kDoubleCid);
651 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
652 } 619 }
653 620
654 621
655 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 622 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
656 const intptr_t kNumInputs = 0; 623 const intptr_t kNumInputs = 0;
657 const intptr_t kNumTemps = 3; 624 const intptr_t kNumTemps = 3;
658 LocationSummary* locs = 625 LocationSummary* locs =
659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 626 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
660 locs->set_temp(0, Location::RegisterLocation(RAX)); 627 locs->set_temp(0, Location::RegisterLocation(RAX));
661 locs->set_temp(1, Location::RegisterLocation(RBX)); 628 locs->set_temp(1, Location::RegisterLocation(RBX));
(...skipping 3774 matching lines...) Expand 10 before | Expand all | Expand 10 after
4436 // Only one of the inputs can be a constant. Choose register if the first one 4403 // Only one of the inputs can be a constant. Choose register if the first one
4437 // is a constant. 4404 // is a constant.
4438 locs->set_in(1, locs->in(0).IsConstant() 4405 locs->set_in(1, locs->in(0).IsConstant()
4439 ? Location::RequiresRegister() 4406 ? Location::RequiresRegister()
4440 : Location::RegisterOrConstant(right())); 4407 : Location::RegisterOrConstant(right()));
4441 locs->set_out(Location::RequiresRegister()); 4408 locs->set_out(Location::RequiresRegister());
4442 return locs; 4409 return locs;
4443 } 4410 }
4444 4411
4445 4412
4413 static void EmitStrictComparison(FlowGraphCompiler* compiler,
4414 StrictCompareInstr* compare,
4415 BranchLabels labels) {
4416 LocationSummary* locs = compare->locs();
4417 bool needs_number_check = compare->needs_number_check();
4418 intptr_t token_pos = compare->token_pos();
4419 Token::Kind kind = compare->kind();
4420 Location left = locs->in(0);
4421 Location right = locs->in(1);
4422 ASSERT(!left.IsConstant() || !right.IsConstant());
4423 if (left.IsConstant()) {
4424 compiler->EmitEqualityRegConstCompare(right.reg(),
4425 left.constant(),
4426 needs_number_check,
4427 token_pos);
4428 } else if (right.IsConstant()) {
4429 compiler->EmitEqualityRegConstCompare(left.reg(),
4430 right.constant(),
4431 needs_number_check,
4432 token_pos);
4433 } else {
4434 compiler->EmitEqualityRegRegCompare(left.reg(),
4435 right.reg(),
4436 needs_number_check,
4437 token_pos);
4438 }
4439
4440 Condition true_condition = (kind == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
4441 EmitBranchOnCondition(compiler, true_condition, labels);
4442 }
4443
4444
4446 // Special code for numbers (compare values instead of references.) 4445 // Special code for numbers (compare values instead of references.)
4447 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4446 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4448 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4447 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4449 Location left = locs()->in(0); 4448
4450 Location right = locs()->in(1); 4449 Label is_true, is_false;
4451 ASSERT(!left.IsConstant() || !right.IsConstant()); 4450 BranchLabels labels = { &is_true, &is_false, &is_false };
4452 if (left.IsConstant()) { 4451
4453 compiler->EmitEqualityRegConstCompare(right.reg(), 4452 EmitStrictComparison(compiler, this, labels);
4454 left.constant(),
4455 needs_number_check(),
4456 token_pos());
4457 } else if (right.IsConstant()) {
4458 compiler->EmitEqualityRegConstCompare(left.reg(),
4459 right.constant(),
4460 needs_number_check(),
4461 token_pos());
4462 } else {
4463 compiler->EmitEqualityRegRegCompare(left.reg(),
4464 right.reg(),
4465 needs_number_check(),
4466 token_pos());
4467 }
4468 4453
4469 Register result = locs()->out().reg(); 4454 Register result = locs()->out().reg();
4470 Label load_true, done; 4455 Label done;
4471 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 4456 __ Bind(&is_false);
4472 __ j(true_condition, &load_true, Assembler::kNearJump);
4473 __ LoadObject(result, Bool::False(), PP); 4457 __ LoadObject(result, Bool::False(), PP);
4474 __ jmp(&done, Assembler::kNearJump); 4458 __ jmp(&done);
4475 __ Bind(&load_true); 4459 __ Bind(&is_true);
4476 __ LoadObject(result, Bool::True(), PP); 4460 __ LoadObject(result, Bool::True(), PP);
4477 __ Bind(&done); 4461 __ Bind(&done);
4478 } 4462 }
4479 4463
4480 4464
4481 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 4465 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
4482 BranchInstr* branch) { 4466 BranchInstr* branch) {
4483 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4467 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4484 Location left = locs()->in(0);
4485 Location right = locs()->in(1);
4486 ASSERT(!left.IsConstant() || !right.IsConstant());
4487 if (left.IsConstant()) {
4488 compiler->EmitEqualityRegConstCompare(right.reg(),
4489 left.constant(),
4490 needs_number_check(),
4491 token_pos());
4492 } else if (right.IsConstant()) {
4493 compiler->EmitEqualityRegConstCompare(left.reg(),
4494 right.constant(),
4495 needs_number_check(),
4496 token_pos());
4497 } else {
4498 compiler->EmitEqualityRegRegCompare(left.reg(),
4499 right.reg(),
4500 needs_number_check(),
4501 token_pos());
4502 }
4503 4468
4504 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 4469 BranchLabels labels = compiler->CreateBranchLabels(branch);
4505 EmitBranchOnCondition(compiler, 4470
4506 branch->true_successor(), 4471 EmitStrictComparison(compiler, this, labels);
4507 branch->false_successor(),
4508 true_condition);
4509 } 4472 }
4510 4473
4511 4474
4512 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { 4475 LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
4513 const intptr_t kNumInputs = 0; 4476 const intptr_t kNumInputs = 0;
4514 const intptr_t kNumTemps = 1; 4477 const intptr_t kNumTemps = 1;
4515 LocationSummary* result = 4478 LocationSummary* result =
4516 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4479 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4517 result->set_out(Location::RegisterLocation(RAX)); 4480 result->set_out(Location::RegisterLocation(RAX));
4518 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. 4481 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
4617 PcDescriptors::kOther, 4580 PcDescriptors::kOther,
4618 locs()); 4581 locs());
4619 __ Drop(2); // Discard type arguments and receiver. 4582 __ Drop(2); // Discard type arguments and receiver.
4620 } 4583 }
4621 4584
4622 } // namespace dart 4585 } // namespace dart
4623 4586
4624 #undef __ 4587 #undef __
4625 4588
4626 #endif // defined TARGET_ARCH_X64 4589 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/intermediate_language_arm.cc ('K') | « runtime/vm/intermediate_language_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698