Chromium Code Reviews| 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 4114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4125 | 4125 |
| 4126 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 4126 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { |
| 4127 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 4127 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
| 4128 const intptr_t kNumTemps = 0; | 4128 const intptr_t kNumTemps = 0; |
| 4129 LocationSummary* result = | 4129 LocationSummary* result = |
| 4130 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 4130 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 4131 result->set_in(0, Location::FpuRegisterLocation(Q0)); | 4131 result->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 4132 if (InputCount() == 2) { | 4132 if (InputCount() == 2) { |
| 4133 result->set_in(1, Location::FpuRegisterLocation(Q1)); | 4133 result->set_in(1, Location::FpuRegisterLocation(Q1)); |
| 4134 } | 4134 } |
| 4135 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | |
| 4136 result->AddTemp(Location::RegisterLocation(R2)); | |
|
zra
2013/08/23 22:43:03
Why does this have to be R2? I think you can use T
srdjan
2013/08/23 23:26:04
The IP is used because the offset is not 4-byte al
| |
| 4137 result->AddTemp(Location::FpuRegisterLocation(Q2)); | |
| 4138 } | |
| 4135 result->set_out(Location::FpuRegisterLocation(Q0)); | 4139 result->set_out(Location::FpuRegisterLocation(Q0)); |
| 4136 return result; | 4140 return result; |
| 4137 } | 4141 } |
| 4138 | 4142 |
| 4139 | 4143 |
| 4140 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4144 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4141 // For pow-function return NaN if exponent is NaN. | 4145 // For pow-function return NaN if exponent is NaN. |
| 4142 Label do_call, skip_call; | 4146 Label do_call, skip_call; |
| 4143 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 4147 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
| 4148 // if (exponent == 0.0) return 0.0; | |
|
regis
2013/08/26 17:03:26
I would add a comment like this, otherwise it look
srdjan
2013/08/26 17:24:00
Done.
| |
| 4149 // if (base == 1.0) return 1.0; | |
| 4150 // if (base.isNaN || exponent.isNaN) { | |
| 4151 // return double.NAN; | |
| 4152 // } | |
| 4153 DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg()); | |
| 4144 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 4154 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 4145 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4155 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 4146 __ vcmpd(exp, exp); | 4156 Register temp = locs()->temp(0).reg(); |
| 4157 DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | |
| 4158 ASSERT((base == result) && (result != saved_base)); | |
| 4159 Label check_base_is_one; | |
| 4160 // Check if exponent is 0.0 -> return 1.0; | |
| 4161 __ vmovd(saved_base, base); | |
| 4162 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); | |
| 4163 __ LoadDFromOffset(DTMP, temp, Double::value_offset() - kHeapObjectTag); | |
| 4164 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); | |
| 4165 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); | |
| 4166 __ vcmpd(exp, DTMP); | |
| 4147 __ vmstat(); | 4167 __ vmstat(); |
| 4148 __ b(&do_call, VC); // NaN -> false; | 4168 __ b(&check_base_is_one, VS); // NaN -> not zero. |
| 4149 // Exponent is NaN, return NaN. | 4169 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0. |
| 4150 __ vmovd(result, exp); | 4170 |
| 4171 Label base_is_nan; | |
| 4172 __ Bind(&check_base_is_one); | |
| 4173 __ vcmpd(saved_base, result); | |
| 4174 __ vmstat(); | |
| 4175 __ b(&base_is_nan, VS); | |
|
regis
2013/08/26 17:03:26
Instead of:
__ b(&base_is_nan, VS);
and
__ Bind(&b
srdjan
2013/08/26 17:24:00
Done.
| |
| 4176 __ b(&skip_call, EQ); // base and result are 1.0. | |
| 4177 __ b(&do_call); | |
| 4178 | |
| 4179 __ Bind(&base_is_nan); | |
| 4180 __ vmovd(result, saved_base); // base is NaN, return NaN. | |
| 4151 __ b(&skip_call); | 4181 __ b(&skip_call); |
| 4182 __ Bind(&do_call); | |
| 4183 __ vmovd(base, saved_base); // Restore base. | |
| 4184 } else { | |
| 4185 __ Bind(&do_call); | |
| 4152 } | 4186 } |
| 4153 __ Bind(&do_call); | |
| 4154 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' | 4187 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' |
| 4155 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values | 4188 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values |
| 4156 // are passed and returned in vfp registers rather than in integer | 4189 // are passed and returned in vfp registers rather than in integer |
| 4157 // register pairs. | 4190 // register pairs. |
| 4158 if (InputCount() == 2) { | 4191 if (InputCount() == 2) { |
| 4159 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. | 4192 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. |
| 4160 __ vmovd(D1, D2); | 4193 __ vmovd(D1, D2); |
| 4161 } | 4194 } |
| 4162 __ CallRuntime(TargetFunction()); | 4195 __ CallRuntime(TargetFunction()); |
| 4163 __ Bind(&skip_call); | 4196 __ Bind(&skip_call); |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4643 compiler->GenerateCall(token_pos(), | 4676 compiler->GenerateCall(token_pos(), |
| 4644 &label, | 4677 &label, |
| 4645 PcDescriptors::kOther, | 4678 PcDescriptors::kOther, |
| 4646 locs()); | 4679 locs()); |
| 4647 __ Drop(2); // Discard type arguments and receiver. | 4680 __ Drop(2); // Discard type arguments and receiver. |
| 4648 } | 4681 } |
| 4649 | 4682 |
| 4650 } // namespace dart | 4683 } // namespace dart |
| 4651 | 4684 |
| 4652 #endif // defined TARGET_ARCH_ARM | 4685 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |