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

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

Issue 78733002: Generalize if-conversion to arbitrary smi comparisons. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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/intermediate_language_mips.cc ('k') | tests/language/vm/if_conversion_vm_test.dart » ('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_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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 124
125 125
126 // Detect pattern when one value is zero and another is a power of 2. 126 // Detect pattern when one value is zero and another is a power of 2.
127 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 127 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
128 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 128 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
129 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 129 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
130 } 130 }
131 131
132 132
133 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { 133 LocationSummary* IfThenElseInstr::MakeLocationSummary() const {
134 const intptr_t kNumInputs = 2; 134 LocationSummary* locs = comparison()->MakeLocationSummary();
135 const intptr_t kNumTemps = 0;
136 LocationSummary* locs =
137 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
138 locs->set_in(0, Location::RegisterOrConstant(left()));
139 // Only one of the inputs can be a constant. Choose register if the first one
140 // is a constant.
141 locs->set_in(1, locs->in(0).IsConstant()
142 ? Location::RequiresRegister()
143 : Location::RegisterOrConstant(right()));
144 // TODO(vegorov): support byte register constraints in the register allocator. 135 // TODO(vegorov): support byte register constraints in the register allocator.
145 locs->set_out(Location::RegisterLocation(RDX)); 136 locs->set_out(Location::RegisterLocation(RDX));
146 return locs; 137 return locs;
147 } 138 }
148 139
149 140
150 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 141 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
151 ASSERT(locs()->out().reg() == RDX); 142 ASSERT(locs()->out().reg() == RDX);
152 ASSERT(Token::IsEqualityOperator(kind()));
153
154 Location left = locs()->in(0);
155 Location right = locs()->in(1);
156 ASSERT(!left.IsConstant() || !right.IsConstant());
157 143
158 // Clear upper part of the out register. We are going to use setcc on it 144 // Clear upper part of the out register. We are going to use setcc on it
159 // which is a byte move. 145 // which is a byte move.
160 __ xorq(RDX, RDX); 146 __ xorq(RDX, RDX);
161 147
162 // Compare left and right. For now only equality comparison is supported. 148 // Emit comparison code. This must not overwrite the result register.
163 // TODO(vegorov): reuse code from the other comparison instructions instead of 149 BranchLabels labels = { NULL, NULL, NULL };
164 // generating it inline here. 150 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
165 if (left.IsConstant()) {
166 __ CompareObject(right.reg(), left.constant(), PP);
167 } else if (right.IsConstant()) {
168 __ CompareObject(left.reg(), right.constant(), PP);
169 } else {
170 __ cmpq(left.reg(), right.reg());
171 }
172
173 Condition true_condition =
174 ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQUAL
175 : NOT_EQUAL;
176 151
177 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); 152 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
178 153
179 intptr_t true_value = if_true_; 154 intptr_t true_value = if_true_;
180 intptr_t false_value = if_false_; 155 intptr_t false_value = if_false_;
181 156
182 if (is_power_of_two_kind) { 157 if (is_power_of_two_kind) {
183 if (true_value == 0) { 158 if (true_value == 0) {
184 // We need to have zero in RDX on true_condition. 159 // We need to have zero in RDX on true_condition.
185 true_condition = NegateCondition(true_condition); 160 true_condition = NegateCondition(true_condition);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 __ j(false_condition, labels.false_label); 388 __ j(false_condition, labels.false_label);
414 389
415 // Fall through or jump to the true successor. 390 // Fall through or jump to the true successor.
416 if (labels.fall_through != labels.true_label) { 391 if (labels.fall_through != labels.true_label) {
417 __ jmp(labels.true_label); 392 __ jmp(labels.true_label);
418 } 393 }
419 } 394 }
420 } 395 }
421 396
422 397
423 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 398 static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
424 const LocationSummary& locs, 399 const LocationSummary& locs,
425 Token::Kind kind, 400 Token::Kind kind,
426 BranchLabels labels) { 401 BranchLabels labels) {
427 Location left = locs.in(0); 402 Location left = locs.in(0);
428 Location right = locs.in(1); 403 Location right = locs.in(1);
429 ASSERT(!left.IsConstant() || !right.IsConstant()); 404 ASSERT(!left.IsConstant() || !right.IsConstant());
430 405
431 Condition true_condition = TokenKindToSmiCondition(kind); 406 Condition true_condition = TokenKindToSmiCondition(kind);
432 407
433 if (left.IsConstant()) { 408 if (left.IsConstant()) {
434 __ CompareObject(right.reg(), left.constant(), PP); 409 __ CompareObject(right.reg(), left.constant(), PP);
435 true_condition = FlipCondition(true_condition); 410 true_condition = FlipCondition(true_condition);
436 } else if (right.IsConstant()) { 411 } else if (right.IsConstant()) {
437 __ CompareObject(left.reg(), right.constant(), PP); 412 __ CompareObject(left.reg(), right.constant(), PP);
438 } else if (right.IsStackSlot()) { 413 } else if (right.IsStackSlot()) {
439 __ cmpq(left.reg(), right.ToStackSlotAddress()); 414 __ cmpq(left.reg(), right.ToStackSlotAddress());
440 } else { 415 } else {
441 __ cmpq(left.reg(), right.reg()); 416 __ cmpq(left.reg(), right.reg());
442 } 417 }
443 EmitBranchOnCondition(compiler, true_condition, labels); 418 return true_condition;
444 } 419 }
445 420
446 421
447 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 422 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
448 switch (kind) { 423 switch (kind) {
449 case Token::kEQ: return EQUAL; 424 case Token::kEQ: return EQUAL;
450 case Token::kNE: return NOT_EQUAL; 425 case Token::kNE: return NOT_EQUAL;
451 case Token::kLT: return BELOW; 426 case Token::kLT: return BELOW;
452 case Token::kGT: return ABOVE; 427 case Token::kGT: return ABOVE;
453 case Token::kLTE: return BELOW_EQUAL; 428 case Token::kLTE: return BELOW_EQUAL;
454 case Token::kGTE: return ABOVE_EQUAL; 429 case Token::kGTE: return ABOVE_EQUAL;
455 default: 430 default:
456 UNREACHABLE(); 431 UNREACHABLE();
457 return OVERFLOW; 432 return OVERFLOW;
458 } 433 }
459 } 434 }
460 435
461 436
462 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 437 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
463 const LocationSummary& locs, 438 const LocationSummary& locs,
464 Token::Kind kind, 439 Token::Kind kind,
465 BranchLabels labels) { 440 BranchLabels labels) {
466 XmmRegister left = locs.in(0).fpu_reg(); 441 XmmRegister left = locs.in(0).fpu_reg();
467 XmmRegister right = locs.in(1).fpu_reg(); 442 XmmRegister right = locs.in(1).fpu_reg();
468 443
469 __ comisd(left, right); 444 __ comisd(left, right);
470 445
471 Condition true_condition = TokenKindToDoubleCondition(kind); 446 Condition true_condition = TokenKindToDoubleCondition(kind);
472 Label* nan_result = (true_condition == NOT_EQUAL) 447 Label* nan_result = (true_condition == NOT_EQUAL)
473 ? labels.true_label : labels.false_label; 448 ? labels.true_label : labels.false_label;
474 __ j(PARITY_EVEN, nan_result); 449 __ j(PARITY_EVEN, nan_result);
475 EmitBranchOnCondition(compiler, true_condition, labels); 450 return true_condition;
451 }
452
453
454 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
455 BranchLabels labels) {
456 if (operation_cid() == kSmiCid) {
457 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
458 } else {
459 ASSERT(operation_cid() == kDoubleCid);
460 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
461 }
476 } 462 }
477 463
478 464
479 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 465 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
480 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 466 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
481 467
482 Label is_true, is_false; 468 Label is_true, is_false;
483 BranchLabels labels = { &is_true, &is_false, &is_false }; 469 BranchLabels labels = { &is_true, &is_false, &is_false };
470 Condition true_condition = EmitComparisonCode(compiler, labels);
471 EmitBranchOnCondition(compiler, true_condition, labels);
484 472
485 if (operation_cid() == kSmiCid) {
486 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
487 } else {
488 ASSERT(operation_cid() == kDoubleCid);
489 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
490 }
491 Register result = locs()->out().reg(); 473 Register result = locs()->out().reg();
492 Label done; 474 Label done;
493 __ Bind(&is_false); 475 __ Bind(&is_false);
494 __ LoadObject(result, Bool::False(), PP); 476 __ LoadObject(result, Bool::False(), PP);
495 __ jmp(&done); 477 __ jmp(&done);
496 __ Bind(&is_true); 478 __ Bind(&is_true);
497 __ LoadObject(result, Bool::True(), PP); 479 __ LoadObject(result, Bool::True(), PP);
498 __ Bind(&done); 480 __ Bind(&done);
499 } 481 }
500 482
501 483
502 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 484 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
503 BranchInstr* branch) { 485 BranchInstr* branch) {
504 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 486 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
505 487
506 BranchLabels labels = compiler->CreateBranchLabels(branch); 488 BranchLabels labels = compiler->CreateBranchLabels(branch);
507 489 Condition true_condition = EmitComparisonCode(compiler, labels);
508 if (operation_cid() == kSmiCid) { 490 EmitBranchOnCondition(compiler, true_condition, labels);
509 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
510 } else {
511 ASSERT(operation_cid() == kDoubleCid);
512 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
513 }
514 } 491 }
515 492
516 493
517 LocationSummary* TestSmiInstr::MakeLocationSummary() const { 494 LocationSummary* TestSmiInstr::MakeLocationSummary() const {
518 const intptr_t kNumInputs = 2; 495 const intptr_t kNumInputs = 2;
519 const intptr_t kNumTemps = 0; 496 const intptr_t kNumTemps = 0;
520 LocationSummary* locs = 497 LocationSummary* locs =
521 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 498 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
522 locs->set_in(0, Location::RequiresRegister()); 499 locs->set_in(0, Location::RequiresRegister());
523 // Only one input can be a constant operand. The case of two constant 500 // Only one input can be a constant operand. The case of two constant
524 // operands should be handled by constant propagation. 501 // operands should be handled by constant propagation.
525 locs->set_in(1, Location::RegisterOrConstant(right())); 502 locs->set_in(1, Location::RegisterOrConstant(right()));
526 return locs; 503 return locs;
527 } 504 }
528 505
529 506
530 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 507 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
531 // Never emitted outside of the BranchInstr. 508 BranchLabels labels) {
532 UNREACHABLE();
533 }
534
535
536 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
537 BranchInstr* branch) {
538 BranchLabels labels = compiler->CreateBranchLabels(branch);
539
540 Condition branch_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
541 Register left_reg = locs()->in(0).reg(); 509 Register left_reg = locs()->in(0).reg();
542 Location right = locs()->in(1); 510 Location right = locs()->in(1);
543 if (right.IsConstant()) { 511 if (right.IsConstant()) {
544 ASSERT(right.constant().IsSmi()); 512 ASSERT(right.constant().IsSmi());
545 const int64_t imm = 513 const int64_t imm =
546 reinterpret_cast<int64_t>(right.constant().raw()); 514 reinterpret_cast<int64_t>(right.constant().raw());
547 __ TestImmediate(left_reg, Immediate(imm), PP); 515 __ TestImmediate(left_reg, Immediate(imm), PP);
548 } else { 516 } else {
549 __ testq(left_reg, right.reg()); 517 __ testq(left_reg, right.reg());
550 } 518 }
551 EmitBranchOnCondition(compiler, branch_condition, labels); 519 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
520 return true_condition;
521 }
522
523
524 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
525 // Never emitted outside of the BranchInstr.
526 UNREACHABLE();
527 }
528
529
530 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
531 BranchInstr* branch) {
532 BranchLabels labels = compiler->CreateBranchLabels(branch);
533 Condition true_condition = EmitComparisonCode(compiler, labels);
534 EmitBranchOnCondition(compiler, true_condition, labels);
552 } 535 }
553 536
554 537
555 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 538 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
556 const intptr_t kNumInputs = 2; 539 const intptr_t kNumInputs = 2;
557 const intptr_t kNumTemps = 0; 540 const intptr_t kNumTemps = 0;
558 if (operation_cid() == kDoubleCid) { 541 if (operation_cid() == kDoubleCid) {
559 LocationSummary* summary = 542 LocationSummary* summary =
560 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 543 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
561 summary->set_in(0, Location::RequiresFpuRegister()); 544 summary->set_in(0, Location::RequiresFpuRegister());
562 summary->set_in(1, Location::RequiresFpuRegister()); 545 summary->set_in(1, Location::RequiresFpuRegister());
563 summary->set_out(Location::RequiresRegister()); 546 summary->set_out(Location::RequiresRegister());
564 return summary; 547 return summary;
565 } 548 }
566 ASSERT(operation_cid() == kSmiCid); 549 ASSERT(operation_cid() == kSmiCid);
567 LocationSummary* summary = 550 LocationSummary* summary =
568 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 551 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
569 summary->set_in(0, Location::RegisterOrConstant(left())); 552 summary->set_in(0, Location::RegisterOrConstant(left()));
570 // Only one input can be a constant operand. The case of two constant 553 // Only one input can be a constant operand. The case of two constant
571 // operands should be handled by constant propagation. 554 // operands should be handled by constant propagation.
572 summary->set_in(1, summary->in(0).IsConstant() 555 summary->set_in(1, summary->in(0).IsConstant()
573 ? Location::RequiresRegister() 556 ? Location::RequiresRegister()
574 : Location::RegisterOrConstant(right())); 557 : Location::RegisterOrConstant(right()));
575 summary->set_out(Location::RequiresRegister()); 558 summary->set_out(Location::RequiresRegister());
576 return summary; 559 return summary;
577 } 560 }
578 561
579 562
563 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
564 BranchLabels labels) {
565 if (operation_cid() == kSmiCid) {
566 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
567 } else {
568 ASSERT(operation_cid() == kDoubleCid);
569 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
570 }
571 }
572
573
580 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 574 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
581 Label is_true, is_false; 575 Label is_true, is_false;
582 BranchLabels labels = { &is_true, &is_false, &is_false }; 576 BranchLabels labels = { &is_true, &is_false, &is_false };
577 Condition true_condition = EmitComparisonCode(compiler, labels);
578 EmitBranchOnCondition(compiler, true_condition, labels);
583 579
584 if (operation_cid() == kSmiCid) {
585 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
586 } else {
587 ASSERT(operation_cid() == kDoubleCid);
588 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
589 }
590 Register result = locs()->out().reg(); 580 Register result = locs()->out().reg();
591 Label done; 581 Label done;
592 __ Bind(&is_false); 582 __ Bind(&is_false);
593 __ LoadObject(result, Bool::False(), PP); 583 __ LoadObject(result, Bool::False(), PP);
594 __ jmp(&done); 584 __ jmp(&done);
595 __ Bind(&is_true); 585 __ Bind(&is_true);
596 __ LoadObject(result, Bool::True(), PP); 586 __ LoadObject(result, Bool::True(), PP);
597 __ Bind(&done); 587 __ Bind(&done);
598 } 588 }
599 589
600 590
601 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 591 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
602 BranchInstr* branch) { 592 BranchInstr* branch) {
603 BranchLabels labels = compiler->CreateBranchLabels(branch); 593 BranchLabels labels = compiler->CreateBranchLabels(branch);
604 594 Condition true_condition = EmitComparisonCode(compiler, labels);
605 if (operation_cid() == kSmiCid) { 595 EmitBranchOnCondition(compiler, true_condition, labels);
606 EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
607 } else {
608 ASSERT(operation_cid() == kDoubleCid);
609 EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
610 }
611 } 596 }
612 597
613 598
614 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 599 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
615 const intptr_t kNumInputs = 0; 600 const intptr_t kNumInputs = 0;
616 const intptr_t kNumTemps = 3; 601 const intptr_t kNumTemps = 3;
617 LocationSummary* locs = 602 LocationSummary* locs =
618 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 603 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
619 locs->set_temp(0, Location::RegisterLocation(RAX)); 604 locs->set_temp(0, Location::RegisterLocation(RAX));
620 locs->set_temp(1, Location::RegisterLocation(RBX)); 605 locs->set_temp(1, Location::RegisterLocation(RBX));
(...skipping 3774 matching lines...) Expand 10 before | Expand all | Expand 10 after
4395 // Only one of the inputs can be a constant. Choose register if the first one 4380 // Only one of the inputs can be a constant. Choose register if the first one
4396 // is a constant. 4381 // is a constant.
4397 locs->set_in(1, locs->in(0).IsConstant() 4382 locs->set_in(1, locs->in(0).IsConstant()
4398 ? Location::RequiresRegister() 4383 ? Location::RequiresRegister()
4399 : Location::RegisterOrConstant(right())); 4384 : Location::RegisterOrConstant(right()));
4400 locs->set_out(Location::RequiresRegister()); 4385 locs->set_out(Location::RequiresRegister());
4401 return locs; 4386 return locs;
4402 } 4387 }
4403 4388
4404 4389
4405 static void EmitStrictComparison(FlowGraphCompiler* compiler, 4390 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
4406 StrictCompareInstr* compare, 4391 BranchLabels labels) {
4407 BranchLabels labels) { 4392 Location left = locs()->in(0);
4408 LocationSummary* locs = compare->locs(); 4393 Location right = locs()->in(1);
4409 bool needs_number_check = compare->needs_number_check();
4410 intptr_t token_pos = compare->token_pos();
4411 Token::Kind kind = compare->kind();
4412 Location left = locs->in(0);
4413 Location right = locs->in(1);
4414 ASSERT(!left.IsConstant() || !right.IsConstant()); 4394 ASSERT(!left.IsConstant() || !right.IsConstant());
4415 if (left.IsConstant()) { 4395 if (left.IsConstant()) {
4416 compiler->EmitEqualityRegConstCompare(right.reg(), 4396 compiler->EmitEqualityRegConstCompare(right.reg(),
4417 left.constant(), 4397 left.constant(),
4418 needs_number_check, 4398 needs_number_check(),
4419 token_pos); 4399 token_pos());
4420 } else if (right.IsConstant()) { 4400 } else if (right.IsConstant()) {
4421 compiler->EmitEqualityRegConstCompare(left.reg(), 4401 compiler->EmitEqualityRegConstCompare(left.reg(),
4422 right.constant(), 4402 right.constant(),
4423 needs_number_check, 4403 needs_number_check(),
4424 token_pos); 4404 token_pos());
4425 } else { 4405 } else {
4426 compiler->EmitEqualityRegRegCompare(left.reg(), 4406 compiler->EmitEqualityRegRegCompare(left.reg(),
4427 right.reg(), 4407 right.reg(),
4428 needs_number_check, 4408 needs_number_check(),
4429 token_pos); 4409 token_pos());
4430 } 4410 }
4431 4411
4432 Condition true_condition = (kind == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 4412 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
4433 EmitBranchOnCondition(compiler, true_condition, labels); 4413 return true_condition;
4434 } 4414 }
4435 4415
4436 4416
4437 // Special code for numbers (compare values instead of references.)
4438 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4417 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4439 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4418 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4440 4419
4441 Label is_true, is_false; 4420 Label is_true, is_false;
4442 BranchLabels labels = { &is_true, &is_false, &is_false }; 4421 BranchLabels labels = { &is_true, &is_false, &is_false };
4443 4422
4444 EmitStrictComparison(compiler, this, labels); 4423 Condition true_condition = EmitComparisonCode(compiler, labels);
4424 EmitBranchOnCondition(compiler, true_condition, labels);
4445 4425
4446 Register result = locs()->out().reg(); 4426 Register result = locs()->out().reg();
4447 Label done; 4427 Label done;
4448 __ Bind(&is_false); 4428 __ Bind(&is_false);
4449 __ LoadObject(result, Bool::False(), PP); 4429 __ LoadObject(result, Bool::False(), PP);
4450 __ jmp(&done); 4430 __ jmp(&done);
4451 __ Bind(&is_true); 4431 __ Bind(&is_true);
4452 __ LoadObject(result, Bool::True(), PP); 4432 __ LoadObject(result, Bool::True(), PP);
4453 __ Bind(&done); 4433 __ Bind(&done);
4454 } 4434 }
4455 4435
4456 4436
4457 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 4437 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
4458 BranchInstr* branch) { 4438 BranchInstr* branch) {
4459 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4439 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4460 4440
4461 BranchLabels labels = compiler->CreateBranchLabels(branch); 4441 BranchLabels labels = compiler->CreateBranchLabels(branch);
4462 4442 Condition true_condition = EmitComparisonCode(compiler, labels);
4463 EmitStrictComparison(compiler, this, labels); 4443 EmitBranchOnCondition(compiler, true_condition, labels);
4464 } 4444 }
4465 4445
4466 4446
4467 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { 4447 LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
4468 const intptr_t kNumInputs = 0; 4448 const intptr_t kNumInputs = 0;
4469 const intptr_t kNumTemps = 1; 4449 const intptr_t kNumTemps = 1;
4470 LocationSummary* result = 4450 LocationSummary* result =
4471 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4451 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4472 result->set_out(Location::RegisterLocation(RAX)); 4452 result->set_out(Location::RegisterLocation(RAX));
4473 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. 4453 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
4572 PcDescriptors::kOther, 4552 PcDescriptors::kOther,
4573 locs()); 4553 locs());
4574 __ Drop(2); // Discard type arguments and receiver. 4554 __ Drop(2); // Discard type arguments and receiver.
4575 } 4555 }
4576 4556
4577 } // namespace dart 4557 } // namespace dart
4578 4558
4579 #undef __ 4559 #undef __
4580 4560
4581 #endif // defined TARGET_ARCH_X64 4561 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | tests/language/vm/if_conversion_vm_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698