| 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 3619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3630 | 3630 |
| 3631 | 3631 |
| 3632 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3632 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3633 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); | 3633 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); |
| 3634 } | 3634 } |
| 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 = 0; | 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 summary->set_out(Location::RequiresFpuRegister()); |
| 3646 summary->set_temp(0, Location::RequiresRegister()); |
| 3646 return summary; | 3647 return summary; |
| 3647 } | 3648 } |
| 3648 ASSERT(result_cid() == kSmiCid); | 3649 ASSERT(result_cid() == kSmiCid); |
| 3649 UNIMPLEMENTED(); | 3650 UNIMPLEMENTED(); |
| 3650 return NULL; | 3651 return NULL; |
| 3651 } | 3652 } |
| 3652 | 3653 |
| 3653 | 3654 |
| 3654 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3655 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3656 ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
| 3657 (op_kind() == MethodRecognizer::kMathMax)); |
| 3655 if (result_cid() == kDoubleCid) { | 3658 if (result_cid() == kDoubleCid) { |
| 3656 Label done, is_left, is_nan; | 3659 Label done, returns_left, returns_nan, are_equal; |
| 3657 XmmRegister left = locs()->in(0).fpu_reg(); | 3660 XmmRegister left = locs()->in(0).fpu_reg(); |
| 3658 XmmRegister right = locs()->in(1).fpu_reg(); | 3661 XmmRegister right = locs()->in(1).fpu_reg(); |
| 3659 XmmRegister result = locs()->out().fpu_reg(); | 3662 XmmRegister result = locs()->out().fpu_reg(); |
| 3663 Register temp = locs()->temp(0).reg(); |
| 3660 __ comisd(left, right); | 3664 __ comisd(left, right); |
| 3661 __ j(PARITY_EVEN, &is_nan, Assembler::kNearJump); | 3665 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); |
| 3662 Condition double_condition; | 3666 __ j(EQUAL, &are_equal, Assembler::kNearJump); |
| 3663 if (op_kind() == MethodRecognizer::kMathMin) { | 3667 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); |
| 3664 double_condition = TokenKindToDoubleCondition(Token::kLT); | 3668 const Condition double_condition = |
| 3665 } else { | 3669 is_min ? TokenKindToDoubleCondition(Token::kLT) |
| 3666 ASSERT(op_kind() == MethodRecognizer::kMathMax); | 3670 : TokenKindToDoubleCondition(Token::kGT); |
| 3667 double_condition = TokenKindToDoubleCondition(Token::kGT); | 3671 __ j(double_condition, &returns_left, Assembler::kNearJump); |
| 3668 } | |
| 3669 __ j(double_condition, &is_left, Assembler::kNearJump); | |
| 3670 __ movsd(result, right); | 3672 __ movsd(result, right); |
| 3671 __ jmp(&done, Assembler::kNearJump); | 3673 __ jmp(&done, Assembler::kNearJump); |
| 3672 __ Bind(&is_left); | 3674 |
| 3675 __ Bind(&returns_left); |
| 3673 __ movsd(result, left); | 3676 __ movsd(result, left); |
| 3674 __ jmp(&done); | 3677 __ jmp(&done, Assembler::kNearJump); |
| 3675 __ Bind(&is_nan); | 3678 |
| 3679 __ Bind(&returns_nan); |
| 3676 static double kNaN = NAN; | 3680 static double kNaN = NAN; |
| 3677 __ movsd(result, Address::Absolute(reinterpret_cast<uword>(&kNaN))); | 3681 __ movsd(result, Address::Absolute(reinterpret_cast<uword>(&kNaN))); |
| 3682 __ jmp(&done, Assembler::kNearJump); |
| 3683 |
| 3684 __ Bind(&are_equal); |
| 3685 Label left_is_negative; |
| 3686 // Check for negative zero: -0.0 is equal 0.0 but min or max must return |
| 3687 // -0.0 or 0.0 respectively. |
| 3688 // Check for negative left value (get the sign bit): |
| 3689 // - min -> left is negative ? left : right. |
| 3690 // - max -> left is negative ? right : left |
| 3691 // Check the sign bit. |
| 3692 __ movmskpd(temp, left); |
| 3693 __ testl(temp, Immediate(1)); |
| 3694 __ j(NOT_ZERO, &left_is_negative, Assembler::kNearJump); |
| 3695 // Left is positive. |
| 3696 __ movsd(result, (is_min ? right : left)); |
| 3697 __ jmp(&done, Assembler::kNearJump); |
| 3698 |
| 3699 __ Bind(&left_is_negative); |
| 3700 __ movsd(result, (is_min ? left : right)); |
| 3678 __ Bind(&done); | 3701 __ Bind(&done); |
| 3679 return; | 3702 return; |
| 3680 } | 3703 } |
| 3681 ASSERT(result_cid() == kSmiCid); | 3704 ASSERT(result_cid() == kSmiCid); |
| 3682 UNIMPLEMENTED(); | 3705 UNIMPLEMENTED(); |
| 3683 } | 3706 } |
| 3684 | 3707 |
| 3685 | 3708 |
| 3686 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3709 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 3687 const intptr_t kNumInputs = 1; | 3710 const intptr_t kNumInputs = 1; |
| (...skipping 1110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4798 PcDescriptors::kOther, | 4821 PcDescriptors::kOther, |
| 4799 locs()); | 4822 locs()); |
| 4800 __ Drop(2); // Discard type arguments and receiver. | 4823 __ Drop(2); // Discard type arguments and receiver. |
| 4801 } | 4824 } |
| 4802 | 4825 |
| 4803 } // namespace dart | 4826 } // namespace dart |
| 4804 | 4827 |
| 4805 #undef __ | 4828 #undef __ |
| 4806 | 4829 |
| 4807 #endif // defined TARGET_ARCH_IA32 | 4830 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |