| 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)); |
| 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 // Pseudo code: |
| 4149 // if (exponent == 0.0) return 0.0; |
| 4150 // if (base == 1.0) return 1.0; |
| 4151 // if (base.isNaN || exponent.isNaN) { |
| 4152 // return double.NAN; |
| 4153 // } |
| 4154 DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 4144 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 4155 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 4145 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4156 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 4146 __ vcmpd(exp, exp); | 4157 Register temp = locs()->temp(0).reg(); |
| 4158 DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 4159 ASSERT((base == result) && (result != saved_base)); |
| 4160 Label check_base_is_one; |
| 4161 // Check if exponent is 0.0 -> return 1.0; |
| 4162 __ vmovd(saved_base, base); |
| 4163 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); |
| 4164 __ LoadDFromOffset(DTMP, temp, Double::value_offset() - kHeapObjectTag); |
| 4165 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); |
| 4166 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); |
| 4167 __ vcmpd(exp, DTMP); |
| 4147 __ vmstat(); | 4168 __ vmstat(); |
| 4148 __ b(&do_call, VC); // NaN -> false; | 4169 __ b(&check_base_is_one, VS); // NaN -> not zero. |
| 4149 // Exponent is NaN, return NaN. | 4170 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0. |
| 4150 __ vmovd(result, exp); | 4171 |
| 4151 __ b(&skip_call); | 4172 __ Bind(&check_base_is_one); |
| 4173 __ vcmpd(saved_base, result); |
| 4174 __ vmstat(); |
| 4175 __ vmovd(result, saved_base, VS); // base is NaN, return NaN. |
| 4176 __ b(&skip_call, VS); |
| 4177 __ b(&skip_call, EQ); // base and result are 1.0. |
| 4178 __ vmovd(base, saved_base); // Restore base. |
| 4152 } | 4179 } |
| 4153 __ Bind(&do_call); | 4180 __ Bind(&do_call); |
| 4154 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' | 4181 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp' |
| 4155 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values | 4182 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values |
| 4156 // are passed and returned in vfp registers rather than in integer | 4183 // are passed and returned in vfp registers rather than in integer |
| 4157 // register pairs. | 4184 // register pairs. |
| 4158 if (InputCount() == 2) { | 4185 if (InputCount() == 2) { |
| 4159 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. | 4186 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. |
| 4160 __ vmovd(D1, D2); | 4187 __ vmovd(D1, D2); |
| 4161 } | 4188 } |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4643 compiler->GenerateCall(token_pos(), | 4670 compiler->GenerateCall(token_pos(), |
| 4644 &label, | 4671 &label, |
| 4645 PcDescriptors::kOther, | 4672 PcDescriptors::kOther, |
| 4646 locs()); | 4673 locs()); |
| 4647 __ Drop(2); // Discard type arguments and receiver. | 4674 __ Drop(2); // Discard type arguments and receiver. |
| 4648 } | 4675 } |
| 4649 | 4676 |
| 4650 } // namespace dart | 4677 } // namespace dart |
| 4651 | 4678 |
| 4652 #endif // defined TARGET_ARCH_ARM | 4679 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |