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

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));
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
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
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