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

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
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | 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) 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 3649 matching lines...) Expand 10 before | Expand all | Expand 10 after
3660 result->set_in(1, Location::FpuRegisterLocation(V1)); 3660 result->set_in(1, Location::FpuRegisterLocation(V1));
3661 } 3661 }
3662 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 3662 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
3663 result->AddTemp(Location::FpuRegisterLocation(V30)); 3663 result->AddTemp(Location::FpuRegisterLocation(V30));
3664 } 3664 }
3665 result->set_out(0, Location::FpuRegisterLocation(V0)); 3665 result->set_out(0, Location::FpuRegisterLocation(V0));
3666 return result; 3666 return result;
3667 } 3667 }
3668 3668
3669 3669
3670 // Pseudo code:
3671 // if (exponent == 0.0) return 1.0;
3672 // // Speed up simple cases.
3673 // if (exponent == 1.0) return base;
3674 // if (exponent == 2.0) return base * base;
3675 // if (exponent == 3.0) return base * base * base;
3676 // if (base == 1.0) return 1.0;
3677 // if (base.isNaN || exponent.isNaN) {
3678 // return double.NAN;
3679 // }
3680 // if (base != -Infinity && exponent == 0.5) {
3681 // if (base == 0.0) return 0.0;
3682 // return sqrt(value);
3683 // }
3684 // TODO(srdjan): Move into a stub?
3685 static void InvokeDoublePow(FlowGraphCompiler* compiler,
3686 InvokeMathCFunctionInstr* instr) {
3687 ASSERT(instr->recognized_kind() == MethodRecognizer::kMathDoublePow);
3688 const intptr_t kInputCount = 2;
3689 ASSERT(instr->InputCount() == kInputCount);
3690 LocationSummary* locs = instr->locs();
3691
3692 const VRegister base = locs->in(0).fpu_reg();
3693 const VRegister exp = locs->in(1).fpu_reg();
3694 const VRegister result = locs->out(0).fpu_reg();
3695 const VRegister saved_base = locs->temp(0).fpu_reg();
3696 ASSERT((base == result) && (result != saved_base));
3697
3698 Label skip_call, try_sqrt, check_base, return_nan, do_pow;
3699 __ fmovdd(saved_base, base);
3700 __ b(&do_pow);
3701 __ LoadDImmediate(result, 1.0, PP);
3702 // exponent == 0.0 -> return 1.0;
3703 __ fcmpdz(exp);
3704 __ b(&check_base, VS); // NaN -> check base.
3705 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0.
3706
3707 // exponent == 1.0 ?
3708 __ fcmpd(exp, result);
3709 Label return_base;
3710 __ b(&return_base, EQ);
3711
3712 // exponent == 2.0 ?
3713 __ LoadDImmediate(VTMP, 2.0, PP);
3714 __ fcmpd(exp, VTMP);
3715 Label return_base_times_2;
3716 __ b(&return_base_times_2, EQ);
3717
3718 // exponent == 3.0 ?
3719 __ LoadDImmediate(VTMP, 3.0, PP);
3720 __ fcmpd(exp, VTMP);
3721 __ b(&check_base, NE);
3722
3723 // base_times_3.
3724 __ fmuld(result, saved_base, saved_base);
3725 __ fmuld(result, result, saved_base);
3726 __ b(&skip_call);
3727
3728 __ Bind(&return_base);
3729 __ fmovdd(result, saved_base);
3730 __ b(&skip_call);
3731
3732 __ Bind(&return_base_times_2);
3733 __ fmuld(result, saved_base, saved_base);
3734 __ b(&skip_call);
3735
3736 __ Bind(&check_base);
3737 // Note: 'exp' could be NaN.
3738 // base == 1.0 -> return 1.0;
3739 __ fcmpd(saved_base, result);
3740 __ b(&return_nan, VS);
3741 __ b(&skip_call, EQ); // base is 1.0, result is 1.0.
3742
3743 __ fcmpd(saved_base, exp);
3744 __ b(&try_sqrt, VC); // // Neither 'exp' nor 'base' is NaN.
3745
3746 __ Bind(&return_nan);
3747 __ LoadDImmediate(result, NAN, PP);
3748 __ b(&skip_call);
3749
3750 Label return_zero;
3751 __ Bind(&try_sqrt);
3752
3753 // Before calling pow, check if we could use sqrt instead of pow.
3754 __ LoadDImmediate(result, -INFINITY, PP);
3755
3756 // base == -Infinity -> call pow;
3757 __ fcmpd(saved_base, result);
3758 __ b(&do_pow, EQ);
3759
3760 // exponent == 0.5 ?
3761 __ LoadDImmediate(result, 0.5, PP);
3762 __ fcmpd(exp, result);
3763 __ b(&do_pow, NE);
3764
3765 // base == 0 -> return 0;
3766 __ fcmpdz(base);
3767 __ b(&return_zero, EQ);
3768
3769 __ fsqrtd(result, saved_base);
3770 __ b(&skip_call);
3771
3772 __ Bind(&return_zero);
3773 __ LoadDImmediate(result, 0.0, PP);
3774 __ b(&skip_call);
3775
3776 __ Bind(&do_pow);
3777 __ fmovdd(base, saved_base); // Restore base.
3778
3779 __ CallRuntime(instr->TargetFunction(), kInputCount);
3780 __ Bind(&skip_call);
3781 }
3782
3783
3670 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3784 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3671 // For pow-function return NaN if exponent is NaN.
3672 Label skip_call;
3673 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 3785 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
3674 // Pseudo code: 3786 InvokeDoublePow(compiler, this);
3675 // if (exponent == 0.0) return 1.0; 3787 return;
3676 // if (base == 1.0) return 1.0;
3677 // if (base.isNaN || exponent.isNaN) {
3678 // return double.NAN;
3679 // }
3680 // if (base != -Infinity && exponent == 0.5) {
3681 // if (base == 0.0) return 0.0;
3682 // return sqrt(value);
3683 // }
3684 const VRegister base = locs()->in(0).fpu_reg();
3685 const VRegister exp = locs()->in(1).fpu_reg();
3686 const VRegister result = locs()->out(0).fpu_reg();
3687 const VRegister saved_base = locs()->temp(0).fpu_reg();
3688 ASSERT((base == result) && (result != saved_base));
3689
3690 Label try_sqrt, check_base, return_nan;
3691 __ fmovdd(saved_base, base);
3692 __ LoadDImmediate(VTMP, 0.0, PP);
3693 __ LoadDImmediate(result, 1.0, PP);
3694 // exponent == 0.0 -> return 1.0;
3695 __ fcmpd(exp, VTMP);
3696 __ b(&check_base, VS); // NaN -> check base.
3697 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0.
3698
3699 __ Bind(&check_base);
3700 // Note: 'exp' could be NaN.
3701 // base == 1.0 -> return 1.0;
3702 __ fcmpd(saved_base, result);
3703 __ b(&return_nan, VS);
3704 __ b(&skip_call, EQ); // base is 1.0, result is 1.0.
3705
3706 __ fcmpd(saved_base, exp);
3707 __ b(&try_sqrt, VC); // // Neither 'exp' nor 'base' is NaN.
3708
3709 __ Bind(&return_nan);
3710 __ LoadDImmediate(result, NAN, PP);
3711 __ b(&skip_call);
3712
3713 Label do_pow, return_zero;
3714 __ Bind(&try_sqrt);
3715
3716 // Before calling pow, check if we could use sqrt instead of pow.
3717 __ LoadDImmediate(result, -INFINITY, PP);
3718
3719 // base == -Infinity -> call pow;
3720 __ fcmpd(saved_base, result);
3721 __ b(&do_pow, EQ);
3722
3723 // exponent == 0.5 ?
3724 __ LoadDImmediate(result, 0.5, PP);
3725 __ fcmpd(exp, result);
3726 __ b(&do_pow, NE);
3727
3728 // base == 0 -> return 0;
3729 __ fcmpd(base, VTMP);
3730 __ b(&return_zero, EQ);
3731
3732 __ fsqrtd(result, saved_base);
3733 __ b(&skip_call);
3734
3735 __ Bind(&return_zero);
3736 __ fmovdd(result, VTMP);
3737 __ b(&skip_call);
3738
3739 __ Bind(&do_pow);
3740 __ fmovdd(base, saved_base); // Restore base.
3741 } 3788 }
3742
3743 __ CallRuntime(TargetFunction(), InputCount()); 3789 __ CallRuntime(TargetFunction(), InputCount());
3744 __ Bind(&skip_call);
3745 } 3790 }
3746 3791
3747 3792
3748 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const { 3793 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const {
3749 // Only use this instruction in optimized code. 3794 // Only use this instruction in optimized code.
3750 ASSERT(opt); 3795 ASSERT(opt);
3751 const intptr_t kNumInputs = 1; 3796 const intptr_t kNumInputs = 1;
3752 LocationSummary* summary = 3797 LocationSummary* summary =
3753 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); 3798 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
3754 if (representation() == kUnboxedDouble) { 3799 if (representation() == kUnboxedDouble) {
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
4315 compiler->GenerateCall(token_pos(), 4360 compiler->GenerateCall(token_pos(),
4316 &label, 4361 &label,
4317 PcDescriptors::kOther, 4362 PcDescriptors::kOther,
4318 locs()); 4363 locs());
4319 __ Drop(ArgumentCount()); // Discard arguments. 4364 __ Drop(ArgumentCount()); // Discard arguments.
4320 } 4365 }
4321 4366
4322 } // namespace dart 4367 } // namespace dart
4323 4368
4324 #endif // defined TARGET_ARCH_ARM64 4369 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698