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

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

Issue 270743004: Refactor and improve code for pow. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 3588 matching lines...) Expand 10 before | Expand all | Expand 10 after
3599 result->set_in(1, Location::FpuRegisterLocation(V1)); 3599 result->set_in(1, Location::FpuRegisterLocation(V1));
3600 } 3600 }
3601 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 3601 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
3602 result->AddTemp(Location::FpuRegisterLocation(V30)); 3602 result->AddTemp(Location::FpuRegisterLocation(V30));
3603 } 3603 }
3604 result->set_out(0, Location::FpuRegisterLocation(V0)); 3604 result->set_out(0, Location::FpuRegisterLocation(V0));
3605 return result; 3605 return result;
3606 } 3606 }
3607 3607
3608 3608
3609 // Pseudo code:
3610 // if (exponent == 0.0) return 1.0;
3611 // // Speed up simple cases.
3612 // if (exponent == 1.0) return base;
3613 // if (exponent == 2.0) return base * base;
3614 // if (exponent == 3.0) return base * base * base;
3615 // if (base == 1.0) return 1.0;
3616 // if (base.isNaN || exponent.isNaN) {
3617 // return double.NAN;
3618 // }
3619 // if (base != -Infinity && exponent == 0.5) {
3620 // if (base == 0.0) return 0.0;
3621 // return sqrt(value);
3622 // }
3623 // TODO(srdjan): Move into a stub?
3624 static void InvokeDoublePow(FlowGraphCompiler* compiler,
3625 InvokeMathCFunctionInstr* instr) {
3626 ASSERT(instr->recognized_kind() == MethodRecognizer::kMathDoublePow);
3627 const intptr_t kInputCount = 2;
3628 ASSERT(instr->InputCount() == kInputCount);
3629 LocationSummary* locs = instr->locs();
3630
3631 const VRegister base = locs->in(0).fpu_reg();
3632 const VRegister exp = locs->in(1).fpu_reg();
3633 const VRegister result = locs->out(0).fpu_reg();
3634 const VRegister saved_base = locs->temp(0).fpu_reg();
3635 ASSERT((base == result) && (result != saved_base));
3636
3637 Label skip_call, try_sqrt, check_base, return_nan;
3638 __ fmovdd(saved_base, base);
3639 __ LoadDImmediate(VTMP, 0.0, PP);
3640 __ LoadDImmediate(result, 1.0, PP);
3641 // exponent == 0.0 -> return 1.0;
3642 __ fcmpd(exp, VTMP);
zra 2014/05/08 19:07:57 __ fcmpdz(exp)
srdjan 2014/05/08 22:15:31 Done.
3643 __ b(&check_base, VS); // NaN -> check base.
3644 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0.
3645
3646 // exponent == 1.0 ?
3647 __ fcmpd(exp, result);
3648 Label return_base;
3649 __ b(&return_base, EQ);
3650
3651 // exponent == 2.0 ?
3652 __ LoadDImmediate(VTMP, 2.0, PP);
3653 __ fcmpd(exp, VTMP);
3654 Label return_base_times_2;
3655 __ b(&return_base_times_2, EQ);
3656
3657 // exponent == 3.0 ?
3658 __ LoadDImmediate(VTMP, 3.0, PP);
3659 __ fcmpd(exp, VTMP);
3660 __ b(&check_base, NE);
3661
3662 // base_times_3.
3663 __ fmuld(result, saved_base, saved_base);
3664 __ fmuld(result, result, saved_base);
3665 __ b(&skip_call);
3666
3667 __ Bind(&return_base);
3668 __ fmovdd(result, saved_base);
3669 __ b(&skip_call);
3670
3671 __ Bind(&return_base_times_2);
3672 __ fmuld(result, saved_base, saved_base);
3673 __ b(&skip_call);
3674
3675 __ Bind(&check_base);
3676 // Note: 'exp' could be NaN.
3677 // base == 1.0 -> return 1.0;
3678 __ fcmpd(saved_base, result);
3679 __ b(&return_nan, VS);
3680 __ b(&skip_call, EQ); // base is 1.0, result is 1.0.
3681
3682 __ fcmpd(saved_base, exp);
3683 __ b(&try_sqrt, VC); // // Neither 'exp' nor 'base' is NaN.
3684
3685 __ Bind(&return_nan);
3686 __ LoadDImmediate(result, NAN, PP);
3687 __ b(&skip_call);
3688
3689 Label do_pow, return_zero;
3690 __ Bind(&try_sqrt);
3691
3692 // Before calling pow, check if we could use sqrt instead of pow.
3693 __ LoadDImmediate(result, -INFINITY, PP);
3694
3695 // base == -Infinity -> call pow;
3696 __ fcmpd(saved_base, result);
3697 __ b(&do_pow, EQ);
3698
3699 // exponent == 0.5 ?
3700 __ LoadDImmediate(result, 0.5, PP);
3701 __ fcmpd(exp, result);
3702 __ b(&do_pow, NE);
3703
3704 // base == 0 -> return 0;
3705 __ LoadDImmediate(VTMP, 0.0, PP);
3706 __ fcmpd(base, VTMP);
zra 2014/05/08 19:07:57 __ fcmpdz(base);
srdjan 2014/05/08 22:15:31 Done.
3707 __ b(&return_zero, EQ);
3708
3709 __ fsqrtd(result, saved_base);
3710 __ b(&skip_call);
3711
3712 __ Bind(&return_zero);
3713 __ fmovdd(result, VTMP);
3714 __ b(&skip_call);
3715
3716 __ Bind(&do_pow);
3717 __ fmovdd(base, saved_base); // Restore base.
3718
3719 __ CallRuntime(instr->TargetFunction(), kInputCount);
3720 __ Bind(&skip_call);
3721 }
3722
3723
3609 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3724 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3610 // For pow-function return NaN if exponent is NaN.
3611 Label skip_call;
3612 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 3725 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
3613 // Pseudo code: 3726 InvokeDoublePow(compiler, this);
3614 // if (exponent == 0.0) return 1.0; 3727 return;
3615 // if (base == 1.0) return 1.0;
3616 // if (base.isNaN || exponent.isNaN) {
3617 // return double.NAN;
3618 // }
3619 // if (base != -Infinity && exponent == 0.5) {
3620 // if (base == 0.0) return 0.0;
3621 // return sqrt(value);
3622 // }
3623 const VRegister base = locs()->in(0).fpu_reg();
3624 const VRegister exp = locs()->in(1).fpu_reg();
3625 const VRegister result = locs()->out(0).fpu_reg();
3626 const VRegister saved_base = locs()->temp(0).fpu_reg();
3627 ASSERT((base == result) && (result != saved_base));
3628
3629 Label try_sqrt, check_base, return_nan;
3630 __ fmovdd(saved_base, base);
3631 __ LoadDImmediate(VTMP, 0.0, PP);
3632 __ LoadDImmediate(result, 1.0, PP);
3633 // exponent == 0.0 -> return 1.0;
3634 __ fcmpd(exp, VTMP);
3635 __ b(&check_base, VS); // NaN -> check base.
3636 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0.
3637
3638 __ Bind(&check_base);
3639 // Note: 'exp' could be NaN.
3640 // base == 1.0 -> return 1.0;
3641 __ fcmpd(saved_base, result);
3642 __ b(&return_nan, VS);
3643 __ b(&skip_call, EQ); // base is 1.0, result is 1.0.
3644
3645 __ fcmpd(saved_base, exp);
3646 __ b(&try_sqrt, VC); // // Neither 'exp' nor 'base' is NaN.
3647
3648 __ Bind(&return_nan);
3649 __ LoadDImmediate(result, NAN, PP);
3650 __ b(&skip_call);
3651
3652 Label do_pow, return_zero;
3653 __ Bind(&try_sqrt);
3654
3655 // Before calling pow, check if we could use sqrt instead of pow.
3656 __ LoadDImmediate(result, -INFINITY, PP);
3657
3658 // base == -Infinity -> call pow;
3659 __ fcmpd(saved_base, result);
3660 __ b(&do_pow, EQ);
3661
3662 // exponent == 0.5 ?
3663 __ LoadDImmediate(result, 0.5, PP);
3664 __ fcmpd(exp, result);
3665 __ b(&do_pow, NE);
3666
3667 // base == 0 -> return 0;
3668 __ fcmpd(base, VTMP);
3669 __ b(&return_zero, EQ);
3670
3671 __ fsqrtd(result, saved_base);
3672 __ b(&skip_call);
3673
3674 __ Bind(&return_zero);
3675 __ fmovdd(result, VTMP);
3676 __ b(&skip_call);
3677
3678 __ Bind(&do_pow);
3679 __ fmovdd(base, saved_base); // Restore base.
3680 } 3728 }
3681
3682 __ CallRuntime(TargetFunction(), InputCount()); 3729 __ CallRuntime(TargetFunction(), InputCount());
3683 __ Bind(&skip_call);
3684 } 3730 }
3685 3731
3686 3732
3687 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const { 3733 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const {
3688 // Only use this instruction in optimized code. 3734 // Only use this instruction in optimized code.
3689 ASSERT(opt); 3735 ASSERT(opt);
3690 const intptr_t kNumInputs = 1; 3736 const intptr_t kNumInputs = 1;
3691 LocationSummary* summary = 3737 LocationSummary* summary =
3692 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); 3738 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
3693 if (representation() == kUnboxedDouble) { 3739 if (representation() == kUnboxedDouble) {
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
4254 compiler->GenerateCall(token_pos(), 4300 compiler->GenerateCall(token_pos(),
4255 &label, 4301 &label,
4256 PcDescriptors::kOther, 4302 PcDescriptors::kOther,
4257 locs()); 4303 locs());
4258 __ Drop(ArgumentCount()); // Discard arguments. 4304 __ Drop(ArgumentCount()); // Discard arguments.
4259 } 4305 }
4260 4306
4261 } // namespace dart 4307 } // namespace dart
4262 4308
4263 #endif // defined TARGET_ARCH_ARM64 4309 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698