Chromium Code Reviews| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 3624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3635 | 3635 |
| 3636 | 3636 |
| 3637 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3637 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { |
| 3638 if (result_cid() == kDoubleCid) { | 3638 if (result_cid() == kDoubleCid) { |
| 3639 const intptr_t kNumInputs = 2; | 3639 const intptr_t kNumInputs = 2; |
| 3640 const intptr_t kNumTemps = 1; | 3640 const intptr_t kNumTemps = 1; |
| 3641 LocationSummary* summary = | 3641 LocationSummary* summary = |
| 3642 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3642 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3643 summary->set_in(0, Location::RequiresFpuRegister()); | 3643 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3644 summary->set_in(1, Location::RequiresFpuRegister()); | 3644 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3645 summary->set_out(Location::RequiresFpuRegister()); | 3645 // Reuse the left register so that code can be made shorter. |
| 3646 summary->set_out(Location::SameAsFirstInput()); | |
| 3646 summary->set_temp(0, Location::RequiresRegister()); | 3647 summary->set_temp(0, Location::RequiresRegister()); |
| 3647 return summary; | 3648 return summary; |
| 3648 } | 3649 } |
| 3649 ASSERT(result_cid() == kSmiCid); | 3650 ASSERT(result_cid() == kSmiCid); |
| 3650 UNIMPLEMENTED(); | 3651 const intptr_t kNumInputs = 2; |
| 3651 return NULL; | 3652 const intptr_t kNumTemps = 0; |
| 3653 LocationSummary* summary = | |
| 3654 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 3655 summary->set_in(0, Location::RequiresRegister()); | |
| 3656 summary->set_in(1, Location::RequiresRegister()); | |
| 3657 // Reuse the left register so that code can be made shorter. | |
| 3658 summary->set_out(Location::SameAsFirstInput()); | |
| 3659 return summary; | |
| 3652 } | 3660 } |
| 3653 | 3661 |
| 3654 | 3662 |
| 3655 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3663 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3656 ASSERT((op_kind() == MethodRecognizer::kMathMin) || | 3664 ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
| 3657 (op_kind() == MethodRecognizer::kMathMax)); | 3665 (op_kind() == MethodRecognizer::kMathMax)); |
| 3666 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); | |
| 3658 if (result_cid() == kDoubleCid) { | 3667 if (result_cid() == kDoubleCid) { |
| 3659 Label done, returns_left, returns_nan, are_equal; | 3668 Label done, returns_nan, are_equal; |
| 3660 XmmRegister left = locs()->in(0).fpu_reg(); | 3669 XmmRegister left = locs()->in(0).fpu_reg(); |
| 3661 XmmRegister right = locs()->in(1).fpu_reg(); | 3670 XmmRegister right = locs()->in(1).fpu_reg(); |
| 3662 XmmRegister result = locs()->out().fpu_reg(); | 3671 XmmRegister result = locs()->out().fpu_reg(); |
| 3663 Register temp = locs()->temp(0).reg(); | 3672 Register temp = locs()->temp(0).reg(); |
| 3664 __ comisd(left, right); | 3673 __ comisd(left, right); |
| 3665 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); | 3674 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); |
| 3666 __ j(EQUAL, &are_equal, Assembler::kNearJump); | 3675 __ j(EQUAL, &are_equal, Assembler::kNearJump); |
| 3667 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); | |
| 3668 const Condition double_condition = | 3676 const Condition double_condition = |
| 3669 is_min ? TokenKindToDoubleCondition(Token::kLT) | 3677 is_min ? TokenKindToDoubleCondition(Token::kLT) |
| 3670 : TokenKindToDoubleCondition(Token::kGT); | 3678 : TokenKindToDoubleCondition(Token::kGT); |
| 3671 __ j(double_condition, &returns_left, Assembler::kNearJump); | 3679 ASSERT(left == result); |
| 3680 __ j(double_condition, &done, Assembler::kNearJump); | |
| 3672 __ movsd(result, right); | 3681 __ movsd(result, right); |
| 3673 __ jmp(&done, Assembler::kNearJump); | 3682 __ jmp(&done, Assembler::kNearJump); |
| 3674 | 3683 |
| 3675 __ Bind(&returns_left); | |
| 3676 __ movsd(result, left); | |
| 3677 __ jmp(&done, Assembler::kNearJump); | |
| 3678 | |
| 3679 __ Bind(&returns_nan); | 3684 __ Bind(&returns_nan); |
| 3680 static double kNaN = NAN; | 3685 static double kNaN = NAN; |
| 3681 __ movsd(result, Address::Absolute(reinterpret_cast<uword>(&kNaN))); | 3686 __ movsd(result, Address::Absolute(reinterpret_cast<uword>(&kNaN))); |
| 3682 __ jmp(&done, Assembler::kNearJump); | 3687 __ jmp(&done, Assembler::kNearJump); |
| 3683 | 3688 |
| 3684 __ Bind(&are_equal); | 3689 __ Bind(&are_equal); |
| 3685 Label left_is_negative; | 3690 Label left_is_negative; |
| 3686 // Check for negative zero: -0.0 is equal 0.0 but min or max must return | 3691 // Check for negative zero: -0.0 is equal 0.0 but min or max must return |
| 3687 // -0.0 or 0.0 respectively. | 3692 // -0.0 or 0.0 respectively. |
| 3688 // Check for negative left value (get the sign bit): | 3693 // Check for negative left value (get the sign bit): |
| 3689 // - min -> left is negative ? left : right. | 3694 // - min -> left is negative ? left : right. |
| 3690 // - max -> left is negative ? right : left | 3695 // - max -> left is negative ? right : left |
| 3691 // Check the sign bit. | 3696 // Check the sign bit. |
| 3692 __ movmskpd(temp, left); | 3697 __ movmskpd(temp, left); |
| 3693 __ testl(temp, Immediate(1)); | 3698 __ testl(temp, Immediate(1)); |
| 3694 __ j(NOT_ZERO, &left_is_negative, Assembler::kNearJump); | 3699 ASSERT(left == result); |
| 3695 // Left is positive. | 3700 if (is_min) { |
| 3696 __ movsd(result, (is_min ? right : left)); | 3701 __ j(NOT_ZERO, &done, Assembler::kNearJump); // Negative -> return left. |
| 3697 __ jmp(&done, Assembler::kNearJump); | 3702 } else { |
| 3698 | 3703 __ j(ZERO, &done, Assembler::kNearJump); // Positive -> return left. |
| 3699 __ Bind(&left_is_negative); | 3704 } |
| 3700 __ movsd(result, (is_min ? left : right)); | 3705 __ movsd(result, right); |
| 3701 __ Bind(&done); | 3706 __ Bind(&done); |
| 3702 return; | 3707 return; |
| 3703 } | 3708 } |
| 3709 | |
| 3710 Label done; | |
| 3704 ASSERT(result_cid() == kSmiCid); | 3711 ASSERT(result_cid() == kSmiCid); |
| 3705 UNIMPLEMENTED(); | 3712 Register left = locs()->in(0).reg(); |
| 3713 Register right = locs()->in(1).reg(); | |
| 3714 Register result = locs()->out().reg(); | |
| 3715 __ cmpl(left, right); | |
| 3716 if (is_min) { | |
| 3717 ASSERT(result == left); | |
| 3718 __ j(LESS_EQUAL, &done, Assembler::kNearJump); | |
|
sra1
2013/07/23 20:53:27
CMOVLE result, right
Or is there some problem wit
srdjan
2013/07/23 21:22:21
Good suggestion. Currently we do not have cmovcc i
| |
| 3719 } else { | |
| 3720 __ j(GREATER_EQUAL, &done, Assembler::kNearJump); | |
| 3721 } | |
| 3722 __ movl(result, right); | |
| 3723 __ Bind(&done); | |
| 3706 } | 3724 } |
| 3707 | 3725 |
| 3708 | 3726 |
| 3709 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3727 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 3710 const intptr_t kNumInputs = 1; | 3728 const intptr_t kNumInputs = 1; |
| 3711 return LocationSummary::Make(kNumInputs, | 3729 return LocationSummary::Make(kNumInputs, |
| 3712 Location::SameAsFirstInput(), | 3730 Location::SameAsFirstInput(), |
| 3713 LocationSummary::kNoCall); | 3731 LocationSummary::kNoCall); |
| 3714 } | 3732 } |
| 3715 | 3733 |
| (...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4821 PcDescriptors::kOther, | 4839 PcDescriptors::kOther, |
| 4822 locs()); | 4840 locs()); |
| 4823 __ Drop(2); // Discard type arguments and receiver. | 4841 __ Drop(2); // Discard type arguments and receiver. |
| 4824 } | 4842 } |
| 4825 | 4843 |
| 4826 } // namespace dart | 4844 } // namespace dart |
| 4827 | 4845 |
| 4828 #undef __ | 4846 #undef __ |
| 4829 | 4847 |
| 4830 #endif // defined TARGET_ARCH_IA32 | 4848 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |