Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(414)

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 23072044: Fix corner cases for double pow operation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698