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 3755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3766 __ b(&skip_call); | 3766 __ b(&skip_call); |
3767 | 3767 |
3768 __ Bind(&do_pow); | 3768 __ Bind(&do_pow); |
3769 } | 3769 } |
3770 // double values are passed and returned in vfp registers. | 3770 // double values are passed and returned in vfp registers. |
3771 __ CallRuntime(TargetFunction(), InputCount()); | 3771 __ CallRuntime(TargetFunction(), InputCount()); |
3772 __ Bind(&skip_call); | 3772 __ Bind(&skip_call); |
3773 } | 3773 } |
3774 | 3774 |
3775 | 3775 |
| 3776 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const { |
| 3777 // Only use this instruction in optimized code. |
| 3778 ASSERT(opt); |
| 3779 const intptr_t kNumInputs = 1; |
| 3780 LocationSummary* summary = |
| 3781 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
| 3782 if (representation() == kUnboxedDouble) { |
| 3783 if (index() == 0) { |
| 3784 summary->set_in(0, Location::Pair(Location::RequiresFpuRegister(), |
| 3785 Location::Any())); |
| 3786 } else { |
| 3787 ASSERT(index() == 1); |
| 3788 summary->set_in(0, Location::Pair(Location::Any(), |
| 3789 Location::RequiresFpuRegister())); |
| 3790 } |
| 3791 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3792 } else { |
| 3793 ASSERT(representation() == kTagged); |
| 3794 if (index() == 0) { |
| 3795 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 3796 Location::Any())); |
| 3797 } else { |
| 3798 ASSERT(index() == 1); |
| 3799 summary->set_in(0, Location::Pair(Location::Any(), |
| 3800 Location::RequiresRegister())); |
| 3801 } |
| 3802 summary->set_out(0, Location::RequiresRegister()); |
| 3803 } |
| 3804 return summary; |
| 3805 } |
| 3806 |
| 3807 |
| 3808 void ExtractNthOutputInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3809 ASSERT(locs()->in(0).IsPairLocation()); |
| 3810 PairLocation* pair = locs()->in(0).AsPairLocation(); |
| 3811 Location in_loc = pair->At(index()); |
| 3812 if (representation() == kUnboxedDouble) { |
| 3813 DRegister out = locs()->out(0).fpu_reg(); |
| 3814 DRegister in = in_loc.fpu_reg(); |
| 3815 __ movd(out, in); |
| 3816 } else { |
| 3817 ASSERT(representation() == kTagged); |
| 3818 Register out = locs()->out(0).reg(); |
| 3819 Register in = in_loc.reg(); |
| 3820 __ mov(out, in); |
| 3821 } |
| 3822 } |
| 3823 |
| 3824 |
3776 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { | 3825 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
3777 if (kind() == MergedMathInstr::kTruncDivMod) { | 3826 if (kind() == MergedMathInstr::kTruncDivMod) { |
3778 const intptr_t kNumInputs = 2; | 3827 const intptr_t kNumInputs = 2; |
3779 const intptr_t kNumTemps = 3; | 3828 const intptr_t kNumTemps = 1; |
3780 LocationSummary* summary = | 3829 LocationSummary* summary = |
3781 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3830 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3782 summary->set_in(0, Location::RequiresRegister()); | 3831 summary->set_in(0, Location::RequiresRegister()); |
3783 summary->set_in(1, Location::RequiresRegister()); | 3832 summary->set_in(1, Location::RequiresRegister()); |
3784 summary->set_temp(0, Location::RequiresRegister()); | 3833 summary->set_temp(0, Location::RequiresRegister()); |
3785 summary->set_temp(1, Location::RequiresRegister()); // result_div. | 3834 // Output is a pair of registers. |
3786 summary->set_temp(2, Location::RequiresRegister()); // result_mod. | 3835 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
3787 summary->set_out(0, Location::RequiresRegister()); | 3836 Location::RequiresRegister())); |
3788 return summary; | 3837 return summary; |
3789 } | 3838 } |
3790 UNIMPLEMENTED(); | 3839 UNIMPLEMENTED(); |
3791 return NULL; | 3840 return NULL; |
3792 } | 3841 } |
3793 | 3842 |
3794 | 3843 |
3795 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3844 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3796 Label* deopt = NULL; | 3845 Label* deopt = NULL; |
3797 if (CanDeoptimize()) { | 3846 if (CanDeoptimize()) { |
3798 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 3847 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); |
3799 } | 3848 } |
3800 if (kind() == MergedMathInstr::kTruncDivMod) { | 3849 if (kind() == MergedMathInstr::kTruncDivMod) { |
3801 Register left = locs()->in(0).reg(); | 3850 Register left = locs()->in(0).reg(); |
3802 Register right = locs()->in(1).reg(); | 3851 Register right = locs()->in(1).reg(); |
3803 Register result = locs()->out(0).reg(); | |
3804 Register temp = locs()->temp(0).reg(); | 3852 Register temp = locs()->temp(0).reg(); |
3805 Register result_div = locs()->temp(1).reg(); | 3853 ASSERT(locs()->out(0).IsPairLocation()); |
3806 Register result_mod = locs()->temp(2).reg(); | 3854 PairLocation* pair = locs()->out(0).AsPairLocation(); |
| 3855 Register result_div = pair->At(0).reg(); |
| 3856 Register result_mod = pair->At(1).reg(); |
3807 Range* right_range = InputAt(1)->definition()->range(); | 3857 Range* right_range = InputAt(1)->definition()->range(); |
3808 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 3858 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
3809 // Handle divide by zero in runtime. | 3859 // Handle divide by zero in runtime. |
3810 __ beq(right, ZR, deopt); | 3860 __ beq(right, ZR, deopt); |
3811 } | 3861 } |
3812 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. | 3862 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. |
3813 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. | 3863 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. |
3814 __ div(temp, TMP); | 3864 __ div(temp, TMP); |
3815 __ mflo(result_div); | 3865 __ mflo(result_div); |
3816 __ mfhi(result_mod); | 3866 __ mfhi(result_mod); |
(...skipping 21 matching lines...) Expand all Loading... |
3838 // Right is positive. | 3888 // Right is positive. |
3839 __ addu(result_mod, result_mod, TMP); | 3889 __ addu(result_mod, result_mod, TMP); |
3840 } else { | 3890 } else { |
3841 // Right is negative. | 3891 // Right is negative. |
3842 __ subu(result_mod, result_mod, TMP); | 3892 __ subu(result_mod, result_mod, TMP); |
3843 } | 3893 } |
3844 __ Bind(&done); | 3894 __ Bind(&done); |
3845 | 3895 |
3846 __ SmiTag(result_div); | 3896 __ SmiTag(result_div); |
3847 __ SmiTag(result_mod); | 3897 __ SmiTag(result_mod); |
3848 __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld))); | |
3849 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays. | |
3850 // [0]: divide resut, [1]: mod result. | |
3851 __ LoadImmediate(temp, | |
3852 FlowGraphCompiler::DataOffsetFor(kArrayCid) - kHeapObjectTag); | |
3853 __ addu(temp, result, temp); | |
3854 Address div_result_address(temp, 0); | |
3855 Address mod_result_address(temp, kWordSize); | |
3856 __ StoreIntoObjectNoBarrier(result, div_result_address, result_div); | |
3857 __ StoreIntoObjectNoBarrier(result, mod_result_address, result_mod); | |
3858 return; | 3898 return; |
3859 } | 3899 } |
3860 UNIMPLEMENTED(); | 3900 UNIMPLEMENTED(); |
3861 } | 3901 } |
3862 | 3902 |
3863 | 3903 |
3864 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( | 3904 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
3865 bool opt) const { | 3905 bool opt) const { |
3866 return MakeCallSummary(); | 3906 return MakeCallSummary(); |
3867 } | 3907 } |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4311 compiler->GenerateCall(token_pos(), | 4351 compiler->GenerateCall(token_pos(), |
4312 &label, | 4352 &label, |
4313 PcDescriptors::kOther, | 4353 PcDescriptors::kOther, |
4314 locs()); | 4354 locs()); |
4315 __ Drop(ArgumentCount()); // Discard arguments. | 4355 __ Drop(ArgumentCount()); // Discard arguments. |
4316 } | 4356 } |
4317 | 4357 |
4318 } // namespace dart | 4358 } // namespace dart |
4319 | 4359 |
4320 #endif // defined TARGET_ARCH_MIPS | 4360 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |