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

Side by Side Diff: runtime/vm/intermediate_language_mips.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) 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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 3834 matching lines...) Expand 10 before | Expand all | Expand 10 after
3845 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 3845 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3846 result->set_in(0, Location::FpuRegisterLocation(D6)); 3846 result->set_in(0, Location::FpuRegisterLocation(D6));
3847 if (InputCount() == 2) { 3847 if (InputCount() == 2) {
3848 result->set_in(1, Location::FpuRegisterLocation(D7)); 3848 result->set_in(1, Location::FpuRegisterLocation(D7));
3849 } 3849 }
3850 result->set_out(0, Location::FpuRegisterLocation(D0)); 3850 result->set_out(0, Location::FpuRegisterLocation(D0));
3851 return result; 3851 return result;
3852 } 3852 }
3853 3853
3854 3854
3855 // Pseudo code:
3856 // if (exponent == 0.0) return 1.0;
3857 // // Speed up simple cases.
3858 // if (exponent == 1.0) return base;
3859 // if (exponent == 2.0) return base * base;
3860 // if (exponent == 3.0) return base * base * base;
3861 // if (base == 1.0) return 1.0;
3862 // if (base.isNaN || exponent.isNaN) {
3863 // return double.NAN;
3864 // }
3865 // if (base != -Infinity && exponent == 0.5) {
3866 // if (base == 0.0) return 0.0;
3867 // return sqrt(value);
3868 // }
3869 // TODO(srdjan): Move into a stub?
3870 static void InvokeDoublePow(FlowGraphCompiler* compiler,
3871 InvokeMathCFunctionInstr* instr) {
3872 ASSERT(instr->recognized_kind() == MethodRecognizer::kMathDoublePow);
3873 const intptr_t kInputCount = 2;
3874 ASSERT(instr->InputCount() == kInputCount);
3875 LocationSummary* locs = instr->locs();
3876
3877 DRegister base = locs->in(0).fpu_reg();
3878 DRegister exp = locs->in(1).fpu_reg();
3879 DRegister result = locs->out(0).fpu_reg();
3880
3881 Label check_base, skip_call;
3882 __ LoadImmediate(DTMP, 0.0);
3883 __ LoadImmediate(result, 1.0);
3884 // exponent == 0.0 -> return 1.0;
3885 __ cund(exp, exp);
3886 __ bc1t(&check_base); // NaN -> check base.
3887 __ ceqd(exp, DTMP);
3888 __ bc1t(&skip_call); // exp is 0.0, result is 1.0.
3889
3890 // exponent == 1.0 ?
3891 __ ceqd(exp, result);
3892 Label return_base;
3893 __ bc1t(&return_base);
3894 // exponent == 2.0 ?
3895 __ LoadImmediate(DTMP, 2.0);
3896 __ ceqd(exp, DTMP);
3897 Label return_base_times_2;
3898 __ bc1t(&return_base_times_2);
3899 // exponent == 3.0 ?
3900 __ LoadImmediate(DTMP, 3.0);
3901 __ ceqd(exp, DTMP);
3902 __ bc1f(&check_base);
3903
3904 // base_times_3.
3905 __ muld(result, base, base);
3906 __ muld(result, result, base);
3907 __ b(&skip_call);
3908
3909 __ Bind(&return_base);
3910 __ movd(result, base);
3911 __ b(&skip_call);
3912
3913 __ Bind(&return_base_times_2);
3914 __ muld(result, base, base);
3915 __ b(&skip_call);
3916
3917 __ Bind(&check_base);
3918 // Note: 'exp' could be NaN.
3919 // base == 1.0 -> return 1.0;
3920 __ cund(base, base);
3921 Label return_nan;
3922 __ bc1t(&return_nan);
3923 __ ceqd(base, result);
3924 __ bc1t(&skip_call); // base and result are 1.0.
3925
3926 __ cund(exp, exp);
3927 Label try_sqrt;
3928 __ bc1f(&try_sqrt); // Neither 'exp' nor 'base' are NaN.
3929
3930 __ Bind(&return_nan);
3931 __ LoadImmediate(result, NAN);
3932 __ b(&skip_call);
3933
3934 __ Bind(&try_sqrt);
3935 // Before calling pow, check if we could use sqrt instead of pow.
3936 __ LoadImmediate(result, INFINITY);
3937 // base == -Infinity -> call pow;
3938 __ ceqd(base, result);
3939 Label do_pow;
3940 __ b(&do_pow);
3941
3942 // exponent == 0.5 ?
3943 __ LoadImmediate(result, 0.5);
3944 __ ceqd(base, result);
3945 __ bc1f(&do_pow);
3946
3947 // base == 0 -> return 0;
3948 __ LoadImmediate(DTMP, 0.0);
3949 __ ceqd(base, DTMP);
3950 Label return_zero;
3951 __ bc1t(&return_zero);
3952
3953 __ sqrtd(result, base);
3954 __ b(&skip_call);
3955
3956 __ Bind(&return_zero);
3957 __ movd(result, DTMP);
3958 __ b(&skip_call);
3959
3960 __ Bind(&do_pow);
3961
3962 // double values are passed and returned in vfp registers.
3963 __ CallRuntime(instr->TargetFunction(), kInputCount);
3964 __ Bind(&skip_call);
3965 }
3966
3967
3855 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3968 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3856 // For pow-function return NaN if exponent is NaN. 3969 // For pow-function return NaN if exponent is NaN.
3857 Label skip_call;
3858 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 3970 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
3859 // Pseudo code: 3971 InvokeDoublePow(compiler, this);
3860 // if (exponent == 0.0) return 1.0; 3972 return;
3861 // if (base == 1.0) return 1.0;
3862 // if (base.isNaN || exponent.isNaN) {
3863 // return double.NAN;
3864 // }
3865 // if (base != -Infinity && exponent == 0.5) {
3866 // if (base == 0.0) return 0.0;
3867 // return sqrt(value);
3868 // }
3869 DRegister base = locs()->in(0).fpu_reg();
3870 DRegister exp = locs()->in(1).fpu_reg();
3871 DRegister result = locs()->out(0).fpu_reg();
3872
3873 Label try_sqrt, check_base, return_nan;
3874 __ LoadImmediate(DTMP, 0.0);
3875 __ LoadImmediate(result, 1.0);
3876 // exponent == 0.0 -> return 1.0;
3877 __ cund(exp, exp);
3878 __ bc1t(&check_base); // NaN -> check base.
3879 __ ceqd(exp, DTMP);
3880 __ bc1t(&skip_call); // exp is 0.0, result is 1.0.
3881
3882 __ Bind(&check_base);
3883 // Note: 'exp' could be NaN.
3884 // base == 1.0 -> return 1.0;
3885 __ cund(base, base);
3886 __ bc1t(&return_nan);
3887 __ ceqd(base, result);
3888 __ bc1t(&skip_call); // base and result are 1.0.
3889
3890 __ cund(exp, exp);
3891 __ bc1f(&try_sqrt); // Neither 'exp' nor 'base' are NaN.
3892
3893 __ Bind(&return_nan);
3894 __ LoadImmediate(result, NAN);
3895 __ b(&skip_call);
3896
3897 __ Bind(&try_sqrt);
3898 // Before calling pow, check if we could use sqrt instead of pow.
3899 Label do_pow, return_zero;
3900 __ LoadImmediate(result, INFINITY);
3901 // base == -Infinity -> call pow;
3902 __ ceqd(base, result);
3903 __ b(&do_pow);
3904
3905 // exponent == 0.5 ?
3906 __ LoadImmediate(result, 0.5);
3907 __ ceqd(base, result);
3908 __ bc1f(&do_pow);
3909
3910 // base == 0 -> return 0;
3911 __ ceqd(base, DTMP);
3912 __ bc1t(&return_zero);
3913
3914 __ sqrtd(result, base);
3915 __ b(&skip_call);
3916
3917 __ Bind(&return_zero);
3918 __ movd(result, DTMP);
3919 __ b(&skip_call);
3920
3921 __ Bind(&do_pow);
3922 } 3973 }
3923 // double values are passed and returned in vfp registers. 3974 // double values are passed and returned in vfp registers.
3924 __ CallRuntime(TargetFunction(), InputCount()); 3975 __ CallRuntime(TargetFunction(), InputCount());
3925 __ Bind(&skip_call);
3926 } 3976 }
3927 3977
3928 3978
3929 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const { 3979 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const {
3930 // Only use this instruction in optimized code. 3980 // Only use this instruction in optimized code.
3931 ASSERT(opt); 3981 ASSERT(opt);
3932 const intptr_t kNumInputs = 1; 3982 const intptr_t kNumInputs = 1;
3933 LocationSummary* summary = 3983 LocationSummary* summary =
3934 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); 3984 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
3935 if (representation() == kUnboxedDouble) { 3985 if (representation() == kUnboxedDouble) {
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
4497 compiler->GenerateCall(token_pos(), 4547 compiler->GenerateCall(token_pos(),
4498 &label, 4548 &label,
4499 PcDescriptors::kOther, 4549 PcDescriptors::kOther,
4500 locs()); 4550 locs());
4501 __ Drop(ArgumentCount()); // Discard arguments. 4551 __ Drop(ArgumentCount()); // Discard arguments.
4502 } 4552 }
4503 4553
4504 } // namespace dart 4554 } // namespace dart
4505 4555
4506 #endif // defined TARGET_ARCH_MIPS 4556 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698