OLD | NEW |
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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 case LS: return CS; | 440 case LS: return CS; |
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 EmitBranchOnValue(FlowGraphCompiler* compiler, | |
451 TargetEntryInstr* true_successor, | |
452 TargetEntryInstr* false_successor, | |
453 bool value) { | |
454 if (value && !compiler->CanFallThroughTo(true_successor)) { | |
455 __ b(compiler->GetJumpLabel(true_successor)); | |
456 } else if (!value && !compiler->CanFallThroughTo(false_successor)) { | |
457 __ b(compiler->GetJumpLabel(false_successor)); | |
458 } | |
459 } | |
460 | |
461 | |
462 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, | 450 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
463 TargetEntryInstr* true_successor, | 451 TargetEntryInstr* true_successor, |
464 TargetEntryInstr* false_successor, | 452 TargetEntryInstr* false_successor, |
465 Condition true_condition) { | 453 Condition true_condition) { |
466 if (compiler->CanFallThroughTo(false_successor)) { | 454 if (compiler->CanFallThroughTo(false_successor)) { |
467 // If the next block is the false successor we will fall through to it. | 455 // If the next block is the false successor we will fall through to it. |
468 __ b(compiler->GetJumpLabel(true_successor), true_condition); | 456 __ b(compiler->GetJumpLabel(true_successor), true_condition); |
469 } else { | 457 } else { |
470 // If the next block is not the false successor we will branch to it. | 458 // If the next block is not the false successor we will branch to it. |
471 Condition false_condition = NegateCondition(true_condition); | 459 Condition false_condition = NegateCondition(true_condition); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 return; | 602 return; |
615 } | 603 } |
616 UNREACHABLE(); | 604 UNREACHABLE(); |
617 } | 605 } |
618 | 606 |
619 | 607 |
620 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 608 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
621 BranchInstr* branch) { | 609 BranchInstr* branch) { |
622 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 610 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
623 if (operation_cid() == kSmiCid) { | 611 if (operation_cid() == kSmiCid) { |
624 // Deoptimizes if both arguments not Smi. | |
625 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 612 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
626 return; | 613 return; |
627 } | 614 } |
628 if (operation_cid() == kMintCid) { | 615 if (operation_cid() == kMintCid) { |
629 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); | 616 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); |
630 return; | 617 return; |
631 } | 618 } |
632 if (operation_cid() == kDoubleCid) { | 619 if (operation_cid() == kDoubleCid) { |
633 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 620 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
634 return; | 621 return; |
(...skipping 3805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4440 LocationSummary* locs = | 4427 LocationSummary* locs = |
4441 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4428 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
4442 locs->set_in(0, Location::RegisterLocation(R0)); | 4429 locs->set_in(0, Location::RegisterLocation(R0)); |
4443 locs->set_in(1, Location::RegisterLocation(R1)); | 4430 locs->set_in(1, Location::RegisterLocation(R1)); |
4444 locs->set_out(Location::RegisterLocation(R0)); | 4431 locs->set_out(Location::RegisterLocation(R0)); |
4445 return locs; | 4432 return locs; |
4446 } | 4433 } |
4447 LocationSummary* locs = | 4434 LocationSummary* locs = |
4448 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4435 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4449 locs->set_in(0, Location::RegisterOrConstant(left())); | 4436 locs->set_in(0, Location::RegisterOrConstant(left())); |
4450 locs->set_in(1, Location::RegisterOrConstant(right())); | 4437 // Only one of the inputs can be a constant. Choose register if the first one |
| 4438 // is a constant. |
| 4439 locs->set_in(1, locs->in(0).IsConstant() |
| 4440 ? Location::RequiresRegister() |
| 4441 : Location::RegisterOrConstant(right())); |
4451 locs->set_out(Location::RequiresRegister()); | 4442 locs->set_out(Location::RequiresRegister()); |
4452 return locs; | 4443 return locs; |
4453 } | 4444 } |
4454 | 4445 |
4455 | 4446 |
4456 // Special code for numbers (compare values instead of references.) | 4447 // Special code for numbers (compare values instead of references.) |
4457 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4448 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4458 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4449 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
4459 Location left = locs()->in(0); | 4450 Location left = locs()->in(0); |
4460 Location right = locs()->in(1); | 4451 Location right = locs()->in(1); |
4461 if (left.IsConstant() && right.IsConstant()) { | 4452 ASSERT(!left.IsConstant() || !right.IsConstant()); |
4462 // TODO(vegorov): should be eliminated earlier by constant propagation. | |
4463 const bool result = (kind() == Token::kEQ_STRICT) ? | |
4464 left.constant().raw() == right.constant().raw() : | |
4465 left.constant().raw() != right.constant().raw(); | |
4466 __ LoadObject(locs()->out().reg(), Bool::Get(result)); | |
4467 return; | |
4468 } | |
4469 if (left.IsConstant()) { | 4453 if (left.IsConstant()) { |
4470 compiler->EmitEqualityRegConstCompare(right.reg(), | 4454 compiler->EmitEqualityRegConstCompare(right.reg(), |
4471 left.constant(), | 4455 left.constant(), |
4472 needs_number_check(), | 4456 needs_number_check(), |
4473 token_pos()); | 4457 token_pos()); |
4474 } else if (right.IsConstant()) { | 4458 } else if (right.IsConstant()) { |
4475 compiler->EmitEqualityRegConstCompare(left.reg(), | 4459 compiler->EmitEqualityRegConstCompare(left.reg(), |
4476 right.constant(), | 4460 right.constant(), |
4477 needs_number_check(), | 4461 needs_number_check(), |
4478 token_pos()); | 4462 token_pos()); |
4479 } else { | 4463 } else { |
4480 compiler->EmitEqualityRegRegCompare(left.reg(), | 4464 compiler->EmitEqualityRegRegCompare(left.reg(), |
4481 right.reg(), | 4465 right.reg(), |
4482 needs_number_check(), | 4466 needs_number_check(), |
4483 token_pos()); | 4467 token_pos()); |
4484 } | 4468 } |
4485 | 4469 |
4486 Register result = locs()->out().reg(); | 4470 Register result = locs()->out().reg(); |
4487 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; | 4471 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; |
4488 __ LoadObject(result, Bool::True(), true_condition); | 4472 __ LoadObject(result, Bool::True(), true_condition); |
4489 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); | 4473 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); |
4490 } | 4474 } |
4491 | 4475 |
4492 | 4476 |
4493 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 4477 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
4494 BranchInstr* branch) { | 4478 BranchInstr* branch) { |
4495 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4479 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
4496 Location left = locs()->in(0); | 4480 Location left = locs()->in(0); |
4497 Location right = locs()->in(1); | 4481 Location right = locs()->in(1); |
4498 if (left.IsConstant() && right.IsConstant()) { | 4482 ASSERT(!left.IsConstant() || !right.IsConstant()); |
4499 // TODO(vegorov): should be eliminated earlier by constant propagation. | |
4500 const bool result = (kind() == Token::kEQ_STRICT) ? | |
4501 left.constant().raw() == right.constant().raw() : | |
4502 left.constant().raw() != right.constant().raw(); | |
4503 EmitBranchOnValue(compiler, | |
4504 branch->true_successor(), | |
4505 branch->false_successor(), | |
4506 result); | |
4507 return; | |
4508 } | |
4509 if (left.IsConstant()) { | 4483 if (left.IsConstant()) { |
4510 compiler->EmitEqualityRegConstCompare(right.reg(), | 4484 compiler->EmitEqualityRegConstCompare(right.reg(), |
4511 left.constant(), | 4485 left.constant(), |
4512 needs_number_check(), | 4486 needs_number_check(), |
4513 token_pos()); | 4487 token_pos()); |
4514 } else if (right.IsConstant()) { | 4488 } else if (right.IsConstant()) { |
4515 compiler->EmitEqualityRegConstCompare(left.reg(), | 4489 compiler->EmitEqualityRegConstCompare(left.reg(), |
4516 right.constant(), | 4490 right.constant(), |
4517 needs_number_check(), | 4491 needs_number_check(), |
4518 token_pos()); | 4492 token_pos()); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4604 compiler->GenerateCall(token_pos(), | 4578 compiler->GenerateCall(token_pos(), |
4605 &label, | 4579 &label, |
4606 PcDescriptors::kOther, | 4580 PcDescriptors::kOther, |
4607 locs()); | 4581 locs()); |
4608 __ Drop(2); // Discard type arguments and receiver. | 4582 __ Drop(2); // Discard type arguments and receiver. |
4609 } | 4583 } |
4610 | 4584 |
4611 } // namespace dart | 4585 } // namespace dart |
4612 | 4586 |
4613 #endif // defined TARGET_ARCH_ARM | 4587 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |