| 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 3752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3763 | 3763 |
| 3764 LocationSummary* MathUnaryInstr::MakeLocationSummary() const { | 3764 LocationSummary* MathUnaryInstr::MakeLocationSummary() const { |
| 3765 if ((kind() == MethodRecognizer::kMathSin) || | 3765 if ((kind() == MethodRecognizer::kMathSin) || |
| 3766 (kind() == MethodRecognizer::kMathCos)) { | 3766 (kind() == MethodRecognizer::kMathCos)) { |
| 3767 const intptr_t kNumInputs = 1; | 3767 const intptr_t kNumInputs = 1; |
| 3768 const intptr_t kNumTemps = 0; | 3768 const intptr_t kNumTemps = 0; |
| 3769 LocationSummary* summary = | 3769 LocationSummary* summary = |
| 3770 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 3770 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 3771 summary->set_in(0, Location::FpuRegisterLocation(Q0)); | 3771 summary->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 3772 summary->set_out(Location::FpuRegisterLocation(Q0)); | 3772 summary->set_out(Location::FpuRegisterLocation(Q0)); |
| 3773 #if !defined(ARM_FLOAT_ABI_HARD) |
| 3774 summary->AddTemp(Location::RegisterLocation(R0)); |
| 3775 summary->AddTemp(Location::RegisterLocation(R1)); |
| 3776 summary->AddTemp(Location::RegisterLocation(R2)); |
| 3777 summary->AddTemp(Location::RegisterLocation(R3)); |
| 3778 #endif |
| 3773 return summary; | 3779 return summary; |
| 3774 } | 3780 } |
| 3781 // Sqrt. |
| 3775 const intptr_t kNumInputs = 1; | 3782 const intptr_t kNumInputs = 1; |
| 3776 const intptr_t kNumTemps = 0; | 3783 const intptr_t kNumTemps = 0; |
| 3777 LocationSummary* summary = | 3784 LocationSummary* summary = |
| 3778 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3785 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3779 summary->set_in(0, Location::RequiresFpuRegister()); | 3786 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3780 summary->set_out(Location::RequiresFpuRegister()); | 3787 summary->set_out(Location::RequiresFpuRegister()); |
| 3781 return summary; | 3788 return summary; |
| 3782 } | 3789 } |
| 3783 | 3790 |
| 3784 | 3791 |
| 3785 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3792 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3786 if (kind() == MethodRecognizer::kMathSqrt) { | 3793 if (kind() == MethodRecognizer::kMathSqrt) { |
| 3787 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3794 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3788 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3795 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 3789 __ vsqrtd(result, val); | 3796 __ vsqrtd(result, val); |
| 3790 } else { | 3797 } else { |
| 3798 #if defined(ARM_FLOAT_ABI_HARD) |
| 3791 __ CallRuntime(TargetFunction(), InputCount()); | 3799 __ CallRuntime(TargetFunction(), InputCount()); |
| 3800 #else |
| 3801 // If we aren't doing "hardfp", then we have to move the double arguments |
| 3802 // to the integer registers, and take the results from the integer |
| 3803 // registers. |
| 3804 __ vmovrrd(R0, R1, D0); |
| 3805 __ vmovrrd(R2, R3, D1); |
| 3806 __ CallRuntime(TargetFunction(), InputCount()); |
| 3807 __ vmovdrr(D0, R0, R1); |
| 3808 __ vmovdrr(D1, R2, R3); |
| 3809 #endif |
| 3792 } | 3810 } |
| 3793 } | 3811 } |
| 3794 | 3812 |
| 3795 | 3813 |
| 3796 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3814 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { |
| 3797 if (result_cid() == kDoubleCid) { | 3815 if (result_cid() == kDoubleCid) { |
| 3798 const intptr_t kNumInputs = 2; | 3816 const intptr_t kNumInputs = 2; |
| 3799 const intptr_t kNumTemps = 1; | 3817 const intptr_t kNumTemps = 1; |
| 3800 LocationSummary* summary = | 3818 LocationSummary* summary = |
| 3801 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3819 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4072 LocationSummary* result = | 4090 LocationSummary* result = |
| 4073 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 4091 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 4074 result->set_in(0, Location::FpuRegisterLocation(Q0)); | 4092 result->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 4075 if (InputCount() == 2) { | 4093 if (InputCount() == 2) { |
| 4076 result->set_in(1, Location::FpuRegisterLocation(Q1)); | 4094 result->set_in(1, Location::FpuRegisterLocation(Q1)); |
| 4077 } | 4095 } |
| 4078 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 4096 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
| 4079 result->AddTemp(Location::RegisterLocation(R2)); | 4097 result->AddTemp(Location::RegisterLocation(R2)); |
| 4080 result->AddTemp(Location::FpuRegisterLocation(Q2)); | 4098 result->AddTemp(Location::FpuRegisterLocation(Q2)); |
| 4081 } | 4099 } |
| 4100 #if !defined(ARM_FLOAT_ABI_HARD) |
| 4101 result->AddTemp(Location::RegisterLocation(R0)); |
| 4102 result->AddTemp(Location::RegisterLocation(R1)); |
| 4103 // Check if R2 is already added. |
| 4104 if (recognized_kind() != MethodRecognizer::kMathDoublePow) { |
| 4105 result->AddTemp(Location::RegisterLocation(R2)); |
| 4106 } |
| 4107 result->AddTemp(Location::RegisterLocation(R3)); |
| 4108 #endif |
| 4082 result->set_out(Location::FpuRegisterLocation(Q0)); | 4109 result->set_out(Location::FpuRegisterLocation(Q0)); |
| 4083 return result; | 4110 return result; |
| 4084 } | 4111 } |
| 4085 | 4112 |
| 4086 | 4113 |
| 4087 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4114 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4088 // For pow-function return NaN if exponent is NaN. | 4115 // For pow-function return NaN if exponent is NaN. |
| 4089 Label do_call, skip_call; | 4116 Label do_call, skip_call; |
| 4090 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 4117 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
| 4091 // Pseudo code: | 4118 // Pseudo code: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4114 | 4141 |
| 4115 __ Bind(&check_base_is_one); | 4142 __ Bind(&check_base_is_one); |
| 4116 __ vcmpd(saved_base, result); | 4143 __ vcmpd(saved_base, result); |
| 4117 __ vmstat(); | 4144 __ vmstat(); |
| 4118 __ vmovd(result, saved_base, VS); // base is NaN, return NaN. | 4145 __ vmovd(result, saved_base, VS); // base is NaN, return NaN. |
| 4119 __ b(&skip_call, VS); | 4146 __ b(&skip_call, VS); |
| 4120 __ b(&skip_call, EQ); // base and result are 1.0. | 4147 __ b(&skip_call, EQ); // base and result are 1.0. |
| 4121 __ vmovd(base, saved_base); // Restore base. | 4148 __ vmovd(base, saved_base); // Restore base. |
| 4122 } | 4149 } |
| 4123 __ Bind(&do_call); | 4150 __ Bind(&do_call); |
| 4124 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' | |
| 4125 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values | |
| 4126 // are passed and returned in vfp registers rather than in integer | |
| 4127 // register pairs. | |
| 4128 if (InputCount() == 2) { | 4151 if (InputCount() == 2) { |
| 4129 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. | 4152 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. |
| 4130 __ vmovd(D1, D2); | 4153 __ vmovd(D1, D2); |
| 4131 } | 4154 } |
| 4155 #if defined(ARM_FLOAT_ABI_HARD) |
| 4132 __ CallRuntime(TargetFunction(), InputCount()); | 4156 __ CallRuntime(TargetFunction(), InputCount()); |
| 4157 #else |
| 4158 // If the ABI is not "hardfp", then we have to move the double arguments |
| 4159 // to the integer registers, and take the results from the integer |
| 4160 // registers. |
| 4161 __ vmovrrd(R0, R1, D0); |
| 4162 __ vmovrrd(R2, R3, D1); |
| 4163 __ CallRuntime(TargetFunction(), InputCount()); |
| 4164 __ vmovdrr(D0, R0, R1); |
| 4165 __ vmovdrr(D1, R2, R3); |
| 4166 #endif |
| 4133 __ Bind(&skip_call); | 4167 __ Bind(&skip_call); |
| 4134 } | 4168 } |
| 4135 | 4169 |
| 4136 | 4170 |
| 4137 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 4171 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| 4138 return MakeCallSummary(); | 4172 return MakeCallSummary(); |
| 4139 } | 4173 } |
| 4140 | 4174 |
| 4141 | 4175 |
| 4142 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4176 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4651 compiler->GenerateCall(token_pos(), | 4685 compiler->GenerateCall(token_pos(), |
| 4652 &label, | 4686 &label, |
| 4653 PcDescriptors::kOther, | 4687 PcDescriptors::kOther, |
| 4654 locs()); | 4688 locs()); |
| 4655 __ Drop(2); // Discard type arguments and receiver. | 4689 __ Drop(2); // Discard type arguments and receiver. |
| 4656 } | 4690 } |
| 4657 | 4691 |
| 4658 } // namespace dart | 4692 } // namespace dart |
| 4659 | 4693 |
| 4660 #endif // defined TARGET_ARCH_ARM | 4694 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |