| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 case LE: return GE; | 462 case LE: return GE; |
| 463 case GT: return LT; | 463 case GT: return LT; |
| 464 case GE: return LE; | 464 case GE: return LE; |
| 465 default: | 465 default: |
| 466 UNREACHABLE(); | 466 UNREACHABLE(); |
| 467 return EQ; | 467 return EQ; |
| 468 } | 468 } |
| 469 } | 469 } |
| 470 | 470 |
| 471 | 471 |
| 472 static void EmitBranchOnValue(FlowGraphCompiler* compiler, | |
| 473 TargetEntryInstr* true_successor, | |
| 474 TargetEntryInstr* false_successor, | |
| 475 bool value) { | |
| 476 __ TraceSimMsg("ControlInstruction::EmitBranchOnValue"); | |
| 477 if (value && !compiler->CanFallThroughTo(true_successor)) { | |
| 478 __ b(compiler->GetJumpLabel(true_successor)); | |
| 479 } else if (!value && !compiler->CanFallThroughTo(false_successor)) { | |
| 480 __ b(compiler->GetJumpLabel(false_successor)); | |
| 481 } | |
| 482 } | |
| 483 | |
| 484 | |
| 485 // The comparison result is in CMPRES1. | 472 // The comparison result is in CMPRES1. |
| 486 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, | 473 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 487 TargetEntryInstr* true_successor, | 474 TargetEntryInstr* true_successor, |
| 488 TargetEntryInstr* false_successor, | 475 TargetEntryInstr* false_successor, |
| 489 Condition true_condition) { | 476 Condition true_condition) { |
| 490 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition"); | 477 __ TraceSimMsg("ControlInstruction::EmitBranchOnCondition"); |
| 491 if (compiler->CanFallThroughTo(false_successor)) { | 478 if (compiler->CanFallThroughTo(false_successor)) { |
| 492 // If the next block is the false successor, fall through to it. | 479 // If the next block is the false successor, fall through to it. |
| 493 Label* label = compiler->GetJumpLabel(true_successor); | 480 Label* label = compiler->GetJumpLabel(true_successor); |
| 494 EmitBranchAfterCompare(compiler, true_condition, label); | 481 EmitBranchAfterCompare(compiler, true_condition, label); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 UNREACHABLE(); | 682 UNREACHABLE(); |
| 696 } | 683 } |
| 697 | 684 |
| 698 | 685 |
| 699 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 686 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 700 BranchInstr* branch) { | 687 BranchInstr* branch) { |
| 701 __ TraceSimMsg("EqualityCompareInstr"); | 688 __ TraceSimMsg("EqualityCompareInstr"); |
| 702 __ Comment("EqualityCompareInstr:BranchCode"); | 689 __ Comment("EqualityCompareInstr:BranchCode"); |
| 703 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 690 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 704 if (operation_cid() == kSmiCid) { | 691 if (operation_cid() == kSmiCid) { |
| 705 // Deoptimizes if both arguments not Smi. | |
| 706 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 692 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 707 return; | 693 return; |
| 708 } | 694 } |
| 709 if (operation_cid() == kMintCid) { | 695 if (operation_cid() == kMintCid) { |
| 710 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); | 696 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); |
| 711 return; | 697 return; |
| 712 } | 698 } |
| 713 if (operation_cid() == kDoubleCid) { | 699 if (operation_cid() == kDoubleCid) { |
| 714 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 700 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 715 return; | 701 return; |
| (...skipping 3099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3815 LocationSummary* locs = | 3801 LocationSummary* locs = |
| 3816 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 3802 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 3817 locs->set_in(0, Location::RegisterLocation(A0)); | 3803 locs->set_in(0, Location::RegisterLocation(A0)); |
| 3818 locs->set_in(1, Location::RegisterLocation(A1)); | 3804 locs->set_in(1, Location::RegisterLocation(A1)); |
| 3819 locs->set_out(Location::RegisterLocation(A0)); | 3805 locs->set_out(Location::RegisterLocation(A0)); |
| 3820 return locs; | 3806 return locs; |
| 3821 } | 3807 } |
| 3822 LocationSummary* locs = | 3808 LocationSummary* locs = |
| 3823 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3809 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3824 locs->set_in(0, Location::RegisterOrConstant(left())); | 3810 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 3825 locs->set_in(1, Location::RegisterOrConstant(right())); | 3811 // Only one of the inputs can be a constant. Choose register if the first one |
| 3812 // is a constant. |
| 3813 locs->set_in(1, locs->in(0).IsConstant() |
| 3814 ? Location::RequiresRegister() |
| 3815 : Location::RegisterOrConstant(right())); |
| 3826 locs->set_out(Location::RequiresRegister()); | 3816 locs->set_out(Location::RequiresRegister()); |
| 3827 return locs; | 3817 return locs; |
| 3828 } | 3818 } |
| 3829 | 3819 |
| 3830 | 3820 |
| 3831 // Special code for numbers (compare values instead of references.) | 3821 // Special code for numbers (compare values instead of references.) |
| 3832 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3822 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3833 __ TraceSimMsg("StrictCompareInstr"); | 3823 __ TraceSimMsg("StrictCompareInstr"); |
| 3834 __ Comment("StrictCompareInstr"); | 3824 __ Comment("StrictCompareInstr"); |
| 3835 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 3825 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 3836 Location left = locs()->in(0); | 3826 Location left = locs()->in(0); |
| 3837 Location right = locs()->in(1); | 3827 Location right = locs()->in(1); |
| 3838 if (left.IsConstant() && right.IsConstant()) { | 3828 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 3839 // TODO(vegorov): should be eliminated earlier by constant propagation. | |
| 3840 const bool result = (kind() == Token::kEQ_STRICT) ? | |
| 3841 left.constant().raw() == right.constant().raw() : | |
| 3842 left.constant().raw() != right.constant().raw(); | |
| 3843 __ LoadObject(locs()->out().reg(), Bool::Get(result)); | |
| 3844 return; | |
| 3845 } | |
| 3846 if (left.IsConstant()) { | 3829 if (left.IsConstant()) { |
| 3847 compiler->EmitEqualityRegConstCompare(right.reg(), | 3830 compiler->EmitEqualityRegConstCompare(right.reg(), |
| 3848 left.constant(), | 3831 left.constant(), |
| 3849 needs_number_check(), | 3832 needs_number_check(), |
| 3850 token_pos()); | 3833 token_pos()); |
| 3851 } else if (right.IsConstant()) { | 3834 } else if (right.IsConstant()) { |
| 3852 compiler->EmitEqualityRegConstCompare(left.reg(), | 3835 compiler->EmitEqualityRegConstCompare(left.reg(), |
| 3853 right.constant(), | 3836 right.constant(), |
| 3854 needs_number_check(), | 3837 needs_number_check(), |
| 3855 token_pos()); | 3838 token_pos()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3875 __ Bind(&done); | 3858 __ Bind(&done); |
| 3876 } | 3859 } |
| 3877 | 3860 |
| 3878 | 3861 |
| 3879 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 3862 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 3880 BranchInstr* branch) { | 3863 BranchInstr* branch) { |
| 3881 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); | 3864 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); |
| 3882 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 3865 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 3883 Location left = locs()->in(0); | 3866 Location left = locs()->in(0); |
| 3884 Location right = locs()->in(1); | 3867 Location right = locs()->in(1); |
| 3885 if (left.IsConstant() && right.IsConstant()) { | 3868 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 3886 // TODO(vegorov): should be eliminated earlier by constant propagation. | |
| 3887 const bool result = (kind() == Token::kEQ_STRICT) ? | |
| 3888 left.constant().raw() == right.constant().raw() : | |
| 3889 left.constant().raw() != right.constant().raw(); | |
| 3890 EmitBranchOnValue(compiler, | |
| 3891 branch->true_successor(), | |
| 3892 branch->false_successor(), | |
| 3893 result); | |
| 3894 return; | |
| 3895 } | |
| 3896 if (left.IsConstant()) { | 3869 if (left.IsConstant()) { |
| 3897 compiler->EmitEqualityRegConstCompare(right.reg(), | 3870 compiler->EmitEqualityRegConstCompare(right.reg(), |
| 3898 left.constant(), | 3871 left.constant(), |
| 3899 needs_number_check(), | 3872 needs_number_check(), |
| 3900 token_pos()); | 3873 token_pos()); |
| 3901 } else if (right.IsConstant()) { | 3874 } else if (right.IsConstant()) { |
| 3902 compiler->EmitEqualityRegConstCompare(left.reg(), | 3875 compiler->EmitEqualityRegConstCompare(left.reg(), |
| 3903 right.constant(), | 3876 right.constant(), |
| 3904 needs_number_check(), | 3877 needs_number_check(), |
| 3905 token_pos()); | 3878 token_pos()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3995 compiler->GenerateCall(token_pos(), | 3968 compiler->GenerateCall(token_pos(), |
| 3996 &label, | 3969 &label, |
| 3997 PcDescriptors::kOther, | 3970 PcDescriptors::kOther, |
| 3998 locs()); | 3971 locs()); |
| 3999 __ Drop(2); // Discard type arguments and receiver. | 3972 __ Drop(2); // Discard type arguments and receiver. |
| 4000 } | 3973 } |
| 4001 | 3974 |
| 4002 } // namespace dart | 3975 } // namespace dart |
| 4003 | 3976 |
| 4004 #endif // defined TARGET_ARCH_MIPS | 3977 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |