| OLD | NEW |
| 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 3506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3517 return NULL; | 3517 return NULL; |
| 3518 } | 3518 } |
| 3519 | 3519 |
| 3520 | 3520 |
| 3521 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3521 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3522 UNIMPLEMENTED(); | 3522 UNIMPLEMENTED(); |
| 3523 } | 3523 } |
| 3524 | 3524 |
| 3525 | 3525 |
| 3526 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 3526 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { |
| 3527 // Calling convetion on MIPS uses D6 and D7 to pass the first two |
| 3528 // double arguments. |
| 3527 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 3529 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
| 3528 const intptr_t kNumTemps = 0; | 3530 const intptr_t kNumTemps = 0; |
| 3529 LocationSummary* result = | 3531 LocationSummary* result = |
| 3530 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 3532 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 3531 result->set_in(0, Location::FpuRegisterLocation(D6)); | 3533 result->set_in(0, Location::FpuRegisterLocation(D6)); |
| 3532 if (InputCount() == 2) { | 3534 if (InputCount() == 2) { |
| 3533 result->set_in(1, Location::FpuRegisterLocation(D7)); | 3535 result->set_in(1, Location::FpuRegisterLocation(D7)); |
| 3534 } | 3536 } |
| 3535 result->set_out(Location::FpuRegisterLocation(D0)); | 3537 result->set_out(Location::FpuRegisterLocation(D0)); |
| 3536 return result; | 3538 return result; |
| 3537 } | 3539 } |
| 3538 | 3540 |
| 3539 | 3541 |
| 3540 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3542 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3541 // For pow-function return NaN if exponent is NaN. | 3543 // For pow-function return NaN if exponent is NaN. |
| 3542 Label do_call, skip_call; | 3544 Label do_call, skip_call; |
| 3543 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 3545 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
| 3546 // if (exponent == 0.0) return 0.0; |
| 3547 // if (base == 1.0) return 1.0; |
| 3548 // if (base.isNaN || exponent.isNaN) { |
| 3549 // return double.NAN; |
| 3550 // } |
| 3551 DRegister base = locs()->in(0).fpu_reg(); |
| 3544 DRegister exp = locs()->in(1).fpu_reg(); | 3552 DRegister exp = locs()->in(1).fpu_reg(); |
| 3553 DRegister result = locs()->out().fpu_reg(); |
| 3554 |
| 3555 Label check_base_is_one; |
| 3556 |
| 3557 // Check if exponent is 0.0 -> return 1.0; |
| 3558 __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(0))); |
| 3559 __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag); |
| 3560 __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(1))); |
| 3561 __ LoadDFromOffset(result, TMP, Double::value_offset() - kHeapObjectTag); |
| 3562 // 'result' contains 1.0. |
| 3545 __ cund(exp, exp); | 3563 __ cund(exp, exp); |
| 3546 __ bc1f(&do_call); | 3564 __ bc1t(&check_base_is_one); // NaN -> not zero. |
| 3547 // Exponent is NaN, return NaN. | 3565 __ ceqd(exp, DTMP); |
| 3548 __ movd(locs()->out().fpu_reg(), exp); | 3566 __ bc1t(&skip_call); // exp is 0.0, result is 1.0. |
| 3567 |
| 3568 Label base_is_nan; |
| 3569 __ Bind(&check_base_is_one); |
| 3570 __ cund(base, base); |
| 3571 __ bc1t(&base_is_nan); |
| 3572 __ ceqd(base, result); |
| 3573 __ bc1t(&skip_call); // base and result are 1.0. |
| 3574 __ b(&do_call); |
| 3575 |
| 3576 __ Bind(&base_is_nan); |
| 3577 __ movd(result, base); // base is NaN, return NaN. |
| 3549 __ b(&skip_call); | 3578 __ b(&skip_call); |
| 3550 } | 3579 } |
| 3551 __ Bind(&do_call); | 3580 __ Bind(&do_call); |
| 3552 // double values are passed and returned in vfp registers. | 3581 // double values are passed and returned in vfp registers. |
| 3553 __ CallRuntime(TargetFunction()); | 3582 __ CallRuntime(TargetFunction()); |
| 3554 __ Bind(&skip_call); | 3583 __ Bind(&skip_call); |
| 3555 } | 3584 } |
| 3556 | 3585 |
| 3557 | 3586 |
| 3558 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 3587 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4073 compiler->GenerateCall(token_pos(), | 4102 compiler->GenerateCall(token_pos(), |
| 4074 &label, | 4103 &label, |
| 4075 PcDescriptors::kOther, | 4104 PcDescriptors::kOther, |
| 4076 locs()); | 4105 locs()); |
| 4077 __ Drop(2); // Discard type arguments and receiver. | 4106 __ Drop(2); // Discard type arguments and receiver. |
| 4078 } | 4107 } |
| 4079 | 4108 |
| 4080 } // namespace dart | 4109 } // namespace dart |
| 4081 | 4110 |
| 4082 #endif // defined TARGET_ARCH_MIPS | 4111 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |