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 |