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 |