| Index: runtime/vm/intermediate_language_mips.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_mips.cc (revision 26548)
|
| +++ runtime/vm/intermediate_language_mips.cc (working copy)
|
| @@ -3524,6 +3524,8 @@
|
|
|
|
|
| LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const {
|
| + // Calling convetion on MIPS uses D6 and D7 to pass the first two
|
| + // double arguments.
|
| ASSERT((InputCount() == 1) || (InputCount() == 2));
|
| const intptr_t kNumTemps = 0;
|
| LocationSummary* result =
|
| @@ -3541,11 +3543,38 @@
|
| // For pow-function return NaN if exponent is NaN.
|
| Label do_call, skip_call;
|
| if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
|
| + // if (exponent == 0.0) return 0.0;
|
| + // if (base == 1.0) return 1.0;
|
| + // if (base.isNaN || exponent.isNaN) {
|
| + // return double.NAN;
|
| + // }
|
| + DRegister base = locs()->in(0).fpu_reg();
|
| DRegister exp = locs()->in(1).fpu_reg();
|
| + DRegister result = locs()->out().fpu_reg();
|
| +
|
| + Label check_base_is_one;
|
| +
|
| + // Check if exponent is 0.0 -> return 1.0;
|
| + __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(0)));
|
| + __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag);
|
| + __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(1)));
|
| + __ LoadDFromOffset(result, TMP, Double::value_offset() - kHeapObjectTag);
|
| + // 'result' contains 1.0.
|
| __ cund(exp, exp);
|
| - __ bc1f(&do_call);
|
| - // Exponent is NaN, return NaN.
|
| - __ movd(locs()->out().fpu_reg(), exp);
|
| + __ bc1t(&check_base_is_one); // NaN -> not zero.
|
| + __ ceqd(exp, DTMP);
|
| + __ bc1t(&skip_call); // exp is 0.0, result is 1.0.
|
| +
|
| + Label base_is_nan;
|
| + __ Bind(&check_base_is_one);
|
| + __ cund(base, base);
|
| + __ bc1t(&base_is_nan);
|
| + __ ceqd(base, result);
|
| + __ bc1t(&skip_call); // base and result are 1.0.
|
| + __ b(&do_call);
|
| +
|
| + __ Bind(&base_is_nan);
|
| + __ movd(result, base); // base is NaN, return NaN.
|
| __ b(&skip_call);
|
| }
|
| __ Bind(&do_call);
|
|
|