| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 3581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3592 | 3592 |
| 3593 | 3593 |
| 3594 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3594 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { |
| 3595 if (result_cid() == kDoubleCid) { | 3595 if (result_cid() == kDoubleCid) { |
| 3596 const intptr_t kNumInputs = 2; | 3596 const intptr_t kNumInputs = 2; |
| 3597 const intptr_t kNumTemps = 1; | 3597 const intptr_t kNumTemps = 1; |
| 3598 LocationSummary* summary = | 3598 LocationSummary* summary = |
| 3599 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3599 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3600 summary->set_in(0, Location::RequiresFpuRegister()); | 3600 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3601 summary->set_in(1, Location::RequiresFpuRegister()); | 3601 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3602 // Reuse the left register so that code can be made shorter. |
| 3603 summary->set_out(Location::SameAsFirstInput()); |
| 3602 summary->set_temp(0, Location::RequiresRegister()); | 3604 summary->set_temp(0, Location::RequiresRegister()); |
| 3603 summary->set_out(Location::RequiresFpuRegister()); | |
| 3604 return summary; | 3605 return summary; |
| 3605 } | 3606 } |
| 3606 ASSERT(result_cid() == kSmiCid); | 3607 ASSERT(result_cid() == kSmiCid); |
| 3607 UNIMPLEMENTED(); | 3608 const intptr_t kNumInputs = 2; |
| 3608 return NULL; | 3609 const intptr_t kNumTemps = 0; |
| 3610 LocationSummary* summary = |
| 3611 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3612 summary->set_in(0, Location::RequiresRegister()); |
| 3613 summary->set_in(1, Location::RequiresRegister()); |
| 3614 // Reuse the left register so that code can be made shorter. |
| 3615 summary->set_out(Location::SameAsFirstInput()); |
| 3616 return summary; |
| 3609 } | 3617 } |
| 3610 | 3618 |
| 3611 | 3619 |
| 3612 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3620 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3613 ASSERT((op_kind() == MethodRecognizer::kMathMin) || | 3621 ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
| 3614 (op_kind() == MethodRecognizer::kMathMax)); | 3622 (op_kind() == MethodRecognizer::kMathMax)); |
| 3623 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); |
| 3615 if (result_cid() == kDoubleCid) { | 3624 if (result_cid() == kDoubleCid) { |
| 3616 Label done, returns_nan, are_equal; | 3625 Label done, returns_nan, are_equal; |
| 3617 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3626 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3618 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 3627 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 3619 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3628 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 3620 Register temp = locs()->temp(0).reg(); | 3629 Register temp = locs()->temp(0).reg(); |
| 3621 __ vcmpd(left, right); | 3630 __ vcmpd(left, right); |
| 3622 __ vmstat(); | 3631 __ vmstat(); |
| 3623 __ b(&returns_nan, VS); | 3632 __ b(&returns_nan, VS); |
| 3624 __ b(&are_equal, EQ); | 3633 __ b(&are_equal, EQ); |
| 3625 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); | |
| 3626 const Condition double_condition = | |
| 3627 is_min ? TokenKindToDoubleCondition(Token::kLT) | |
| 3628 : TokenKindToDoubleCondition(Token::kGT); | |
| 3629 const Condition neg_double_condition = | 3634 const Condition neg_double_condition = |
| 3630 is_min ? TokenKindToDoubleCondition(Token::kGTE) | 3635 is_min ? TokenKindToDoubleCondition(Token::kGTE) |
| 3631 : TokenKindToDoubleCondition(Token::kLTE); | 3636 : TokenKindToDoubleCondition(Token::kLTE); |
| 3632 __ vmovd(result, left, double_condition); | 3637 ASSERT(left == result); |
| 3633 __ vmovd(result, right, neg_double_condition); | 3638 __ vmovd(result, right, neg_double_condition); |
| 3634 __ b(&done); | 3639 __ b(&done); |
| 3635 | 3640 |
| 3636 __ Bind(&returns_nan); | 3641 __ Bind(&returns_nan); |
| 3637 __ LoadDImmediate(result, NAN, temp); | 3642 __ LoadDImmediate(result, NAN, temp); |
| 3638 __ b(&done); | 3643 __ b(&done); |
| 3639 | 3644 |
| 3640 __ Bind(&are_equal); | 3645 __ Bind(&are_equal); |
| 3641 // Check for negative zero: -0.0 is equal 0.0 but min or max must return | 3646 // Check for negative zero: -0.0 is equal 0.0 but min or max must return |
| 3642 // -0.0 or 0.0 respectively. | 3647 // -0.0 or 0.0 respectively. |
| 3643 // Check for negative left value (get the sign bit): | 3648 // Check for negative left value (get the sign bit): |
| 3644 // - min -> left is negative ? left : right. | 3649 // - min -> left is negative ? left : right. |
| 3645 // - max -> left is negative ? right : left | 3650 // - max -> left is negative ? right : left |
| 3646 // Check the sign bit. | 3651 // Check the sign bit. |
| 3647 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp. | 3652 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp. |
| 3648 __ cmp(temp, ShifterOperand(0)); | 3653 __ cmp(temp, ShifterOperand(0)); |
| 3649 if (is_min) { | 3654 if (is_min) { |
| 3650 __ vmovd(result, left, LT); | 3655 ASSERT(left == result); |
| 3651 __ vmovd(result, right, GE); | 3656 __ vmovd(result, right, GE); |
| 3652 } else { | 3657 } else { |
| 3653 __ vmovd(result, right, LT); | 3658 __ vmovd(result, right, LT); |
| 3654 __ vmovd(result, left, GE); | 3659 ASSERT(left == result); |
| 3655 } | 3660 } |
| 3656 __ Bind(&done); | 3661 __ Bind(&done); |
| 3657 return; | 3662 return; |
| 3658 } | 3663 } |
| 3664 |
| 3659 ASSERT(result_cid() == kSmiCid); | 3665 ASSERT(result_cid() == kSmiCid); |
| 3660 UNIMPLEMENTED(); | 3666 Register left = locs()->in(0).reg(); |
| 3667 Register right = locs()->in(1).reg(); |
| 3668 Register result = locs()->out().reg(); |
| 3669 __ cmp(left, ShifterOperand(right)); |
| 3670 ASSERT(result == left); |
| 3671 if (is_min) { |
| 3672 __ mov(result, ShifterOperand(right), GT); |
| 3673 } else { |
| 3674 __ mov(result, ShifterOperand(right), LT); |
| 3675 } |
| 3661 } | 3676 } |
| 3662 | 3677 |
| 3663 | 3678 |
| 3664 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3679 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 3665 const intptr_t kNumInputs = 1; | 3680 const intptr_t kNumInputs = 1; |
| 3666 const intptr_t kNumTemps = 0; | 3681 const intptr_t kNumTemps = 0; |
| 3667 LocationSummary* summary = | 3682 LocationSummary* summary = |
| 3668 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3683 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3669 summary->set_in(0, Location::RequiresRegister()); | 3684 summary->set_in(0, Location::RequiresRegister()); |
| 3670 // We make use of 3-operand instructions by not requiring result register | 3685 // We make use of 3-operand instructions by not requiring result register |
| (...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4352 compiler->GenerateCall(token_pos(), | 4367 compiler->GenerateCall(token_pos(), |
| 4353 &label, | 4368 &label, |
| 4354 PcDescriptors::kOther, | 4369 PcDescriptors::kOther, |
| 4355 locs()); | 4370 locs()); |
| 4356 __ Drop(2); // Discard type arguments and receiver. | 4371 __ Drop(2); // Discard type arguments and receiver. |
| 4357 } | 4372 } |
| 4358 | 4373 |
| 4359 } // namespace dart | 4374 } // namespace dart |
| 4360 | 4375 |
| 4361 #endif // defined TARGET_ARCH_ARM | 4376 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |