| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 3690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3701 | 3701 |
| 3702 | 3702 |
| 3703 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3703 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { |
| 3704 if (result_cid() == kDoubleCid) { | 3704 if (result_cid() == kDoubleCid) { |
| 3705 const intptr_t kNumInputs = 2; | 3705 const intptr_t kNumInputs = 2; |
| 3706 const intptr_t kNumTemps = 1; | 3706 const intptr_t kNumTemps = 1; |
| 3707 LocationSummary* summary = | 3707 LocationSummary* summary = |
| 3708 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3708 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3709 summary->set_in(0, Location::RequiresFpuRegister()); | 3709 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3710 summary->set_in(1, Location::RequiresFpuRegister()); | 3710 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3711 // Reuse the left register so that code can be made shorter. |
| 3712 summary->set_out(Location::SameAsFirstInput()); |
| 3711 summary->set_temp(0, Location::RequiresRegister()); | 3713 summary->set_temp(0, Location::RequiresRegister()); |
| 3712 summary->set_out(Location::RequiresFpuRegister()); | |
| 3713 return summary; | 3714 return summary; |
| 3714 } | 3715 } |
| 3715 ASSERT(result_cid() == kSmiCid); | 3716 ASSERT(result_cid() == kSmiCid); |
| 3716 UNIMPLEMENTED(); | 3717 const intptr_t kNumInputs = 2; |
| 3717 return NULL; | 3718 const intptr_t kNumTemps = 0; |
| 3719 LocationSummary* summary = |
| 3720 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3721 summary->set_in(0, Location::RequiresRegister()); |
| 3722 summary->set_in(1, Location::RequiresRegister()); |
| 3723 // Reuse the left register so that code can be made shorter. |
| 3724 summary->set_out(Location::SameAsFirstInput()); |
| 3725 return summary; |
| 3718 } | 3726 } |
| 3719 | 3727 |
| 3720 | 3728 |
| 3721 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3729 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3722 ASSERT((op_kind() == MethodRecognizer::kMathMin) || | 3730 ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
| 3723 (op_kind() == MethodRecognizer::kMathMax)); | 3731 (op_kind() == MethodRecognizer::kMathMax)); |
| 3732 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); |
| 3724 if (result_cid() == kDoubleCid) { | 3733 if (result_cid() == kDoubleCid) { |
| 3725 Label done, returns_left, returns_nan, are_equal; | 3734 Label done, returns_nan, are_equal; |
| 3726 XmmRegister left = locs()->in(0).fpu_reg(); | 3735 XmmRegister left = locs()->in(0).fpu_reg(); |
| 3727 XmmRegister right = locs()->in(1).fpu_reg(); | 3736 XmmRegister right = locs()->in(1).fpu_reg(); |
| 3728 XmmRegister result = locs()->out().fpu_reg(); | 3737 XmmRegister result = locs()->out().fpu_reg(); |
| 3729 Register temp = locs()->temp(0).reg(); | 3738 Register temp = locs()->temp(0).reg(); |
| 3730 __ comisd(left, right); | 3739 __ comisd(left, right); |
| 3731 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); | 3740 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); |
| 3732 __ j(EQUAL, &are_equal, Assembler::kNearJump); | 3741 __ j(EQUAL, &are_equal, Assembler::kNearJump); |
| 3733 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); | |
| 3734 const Condition double_condition = | 3742 const Condition double_condition = |
| 3735 is_min ? TokenKindToDoubleCondition(Token::kLT) | 3743 is_min ? TokenKindToDoubleCondition(Token::kLT) |
| 3736 : TokenKindToDoubleCondition(Token::kGT); | 3744 : TokenKindToDoubleCondition(Token::kGT); |
| 3737 __ j(double_condition, &returns_left, Assembler::kNearJump); | 3745 ASSERT(left == result); |
| 3746 __ j(double_condition, &done, Assembler::kNearJump); |
| 3738 __ movsd(result, right); | 3747 __ movsd(result, right); |
| 3739 __ jmp(&done, Assembler::kNearJump); | 3748 __ jmp(&done, Assembler::kNearJump); |
| 3740 | 3749 |
| 3741 __ Bind(&returns_left); | |
| 3742 __ movsd(result, left); | |
| 3743 __ jmp(&done, Assembler::kNearJump); | |
| 3744 | |
| 3745 __ Bind(&returns_nan); | 3750 __ Bind(&returns_nan); |
| 3746 static double kNaN = NAN; | 3751 static double kNaN = NAN; |
| 3747 __ movq(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN))); | 3752 __ movq(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN))); |
| 3748 __ movsd(result, Address(temp, 0)); | 3753 __ movsd(result, Address(temp, 0)); |
| 3749 __ jmp(&done, Assembler::kNearJump); | 3754 __ jmp(&done, Assembler::kNearJump); |
| 3750 | 3755 |
| 3751 __ Bind(&are_equal); | 3756 __ Bind(&are_equal); |
| 3752 Label left_is_negative; | 3757 Label left_is_negative; |
| 3753 // Check for negative zero: -0.0 is equal 0.0 but min or max must return | 3758 // Check for negative zero: -0.0 is equal 0.0 but min or max must return |
| 3754 // -0.0 or 0.0 respectively. | 3759 // -0.0 or 0.0 respectively. |
| 3755 // Check for negative left value (get the sign bit): | 3760 // Check for negative left value (get the sign bit): |
| 3756 // - min -> left is negative ? left : right. | 3761 // - min -> left is negative ? left : right. |
| 3757 // - max -> left is negative ? right : left | 3762 // - max -> left is negative ? right : left |
| 3758 // Check the sign bit. | 3763 // Check the sign bit. |
| 3759 __ movmskpd(temp, left); | 3764 __ movmskpd(temp, left); |
| 3760 __ testq(temp, Immediate(1)); | 3765 __ testq(temp, Immediate(1)); |
| 3761 __ j(NOT_ZERO, &left_is_negative, Assembler::kNearJump); | 3766 if (is_min) { |
| 3762 // Left is positive. | 3767 ASSERT(left == result); |
| 3763 __ movsd(result, (is_min ? right : left)); | 3768 __ j(NOT_ZERO, &done, Assembler::kNearJump); // Negative -> return left. |
| 3764 __ jmp(&done, Assembler::kNearJump); | 3769 } else { |
| 3765 | 3770 ASSERT(left == result); |
| 3766 __ Bind(&left_is_negative); | 3771 __ j(ZERO, &done, Assembler::kNearJump); // Positive -> return left. |
| 3767 __ movsd(result, (is_min ? left : right)); | 3772 } |
| 3773 __ movsd(result, right); |
| 3768 __ Bind(&done); | 3774 __ Bind(&done); |
| 3769 return; | 3775 return; |
| 3770 } | 3776 } |
| 3777 |
| 3778 Label done; |
| 3771 ASSERT(result_cid() == kSmiCid); | 3779 ASSERT(result_cid() == kSmiCid); |
| 3772 UNIMPLEMENTED(); | 3780 Register left = locs()->in(0).reg(); |
| 3781 Register right = locs()->in(1).reg(); |
| 3782 Register result = locs()->out().reg(); |
| 3783 __ cmpq(left, right); |
| 3784 ASSERT(result == left); |
| 3785 if (is_min) { |
| 3786 __ j(LESS_EQUAL, &done, Assembler::kNearJump); |
| 3787 } else { |
| 3788 __ j(GREATER_EQUAL, &done, Assembler::kNearJump); |
| 3789 } |
| 3790 __ movq(result, right); |
| 3791 __ Bind(&done); |
| 3773 } | 3792 } |
| 3774 | 3793 |
| 3775 | 3794 |
| 3776 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3795 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3777 Register value = locs()->in(0).reg(); | 3796 Register value = locs()->in(0).reg(); |
| 3778 ASSERT(value == locs()->out().reg()); | 3797 ASSERT(value == locs()->out().reg()); |
| 3779 switch (op_kind()) { | 3798 switch (op_kind()) { |
| 3780 case Token::kNEGATE: { | 3799 case Token::kNEGATE: { |
| 3781 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3800 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3782 kDeoptUnaryOp); | 3801 kDeoptUnaryOp); |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4493 PcDescriptors::kOther, | 4512 PcDescriptors::kOther, |
| 4494 locs()); | 4513 locs()); |
| 4495 __ Drop(2); // Discard type arguments and receiver. | 4514 __ Drop(2); // Discard type arguments and receiver. |
| 4496 } | 4515 } |
| 4497 | 4516 |
| 4498 } // namespace dart | 4517 } // namespace dart |
| 4499 | 4518 |
| 4500 #undef __ | 4519 #undef __ |
| 4501 | 4520 |
| 4502 #endif // defined TARGET_ARCH_X64 | 4521 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |