| 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 |