Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(599)

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 19482023: Fix math min/max for -0.0 case. Enable min_max_test to run in optimizing compiler as well. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 3701 matching lines...) Expand 10 before | Expand all | Expand 10 after
3712 summary->set_out(Location::RequiresFpuRegister()); 3712 summary->set_out(Location::RequiresFpuRegister());
3713 return summary; 3713 return summary;
3714 } 3714 }
3715 ASSERT(result_cid() == kSmiCid); 3715 ASSERT(result_cid() == kSmiCid);
3716 UNIMPLEMENTED(); 3716 UNIMPLEMENTED();
3717 return NULL; 3717 return NULL;
3718 } 3718 }
3719 3719
3720 3720
3721 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3721 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3722 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
3723 (op_kind() == MethodRecognizer::kMathMax));
3722 if (result_cid() == kDoubleCid) { 3724 if (result_cid() == kDoubleCid) {
3723 Label done, is_left, is_nan; 3725 Label done, returns_left, returns_nan, are_equal;
3724 XmmRegister left = locs()->in(0).fpu_reg(); 3726 XmmRegister left = locs()->in(0).fpu_reg();
3725 XmmRegister right = locs()->in(1).fpu_reg(); 3727 XmmRegister right = locs()->in(1).fpu_reg();
3726 XmmRegister result = locs()->out().fpu_reg(); 3728 XmmRegister result = locs()->out().fpu_reg();
3727 Register temp = locs()->temp(0).reg(); 3729 Register temp = locs()->temp(0).reg();
3728 __ comisd(left, right); 3730 __ comisd(left, right);
3729 __ j(PARITY_EVEN, &is_nan, Assembler::kNearJump); 3731 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump);
3730 Condition double_condition; 3732 __ j(EQUAL, &are_equal, Assembler::kNearJump);
3731 if (op_kind() == MethodRecognizer::kMathMin) { 3733 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3732 double_condition = TokenKindToDoubleCondition(Token::kLT); 3734 const Condition double_condition =
3733 } else { 3735 is_min ? TokenKindToDoubleCondition(Token::kLT)
3734 ASSERT(op_kind() == MethodRecognizer::kMathMax); 3736 : TokenKindToDoubleCondition(Token::kGT);
3735 double_condition = TokenKindToDoubleCondition(Token::kGT); 3737 __ j(double_condition, &returns_left, Assembler::kNearJump);
3736 }
3737 __ j(double_condition, &is_left, Assembler::kNearJump);
3738 __ movsd(result, right); 3738 __ movsd(result, right);
3739 __ jmp(&done, Assembler::kNearJump); 3739 __ jmp(&done, Assembler::kNearJump);
3740 __ Bind(&is_left); 3740
3741 __ Bind(&returns_left);
3741 __ movsd(result, left); 3742 __ movsd(result, left);
3742 __ jmp(&done); 3743 __ jmp(&done, Assembler::kNearJump);
3743 __ Bind(&is_nan); 3744
3745 __ Bind(&returns_nan);
3744 static double kNaN = NAN; 3746 static double kNaN = NAN;
3745 __ movq(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN))); 3747 __ movq(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN)));
3746 __ movsd(result, Address(temp, 0)); 3748 __ movsd(result, Address(temp, 0));
3749 __ jmp(&done, Assembler::kNearJump);
3750
3751 __ Bind(&are_equal);
3752 Label left_is_negative;
3753 // Check for negative zero: -0.0 is equal 0.0 but min or max must return
3754 // -0.0 or 0.0 respectively.
3755 // Check for negative left value (get the sign bit):
3756 // - min -> left is negative ? left : right.
3757 // - max -> left is negative ? right : left
3758 // Check the sign bit.
3759 __ movmskpd(temp, left);
3760 __ testq(temp, Immediate(1));
3761 __ j(NOT_ZERO, &left_is_negative, Assembler::kNearJump);
3762 // Left is positive.
3763 __ movsd(result, (is_min ? right : left));
3764 __ jmp(&done, Assembler::kNearJump);
3765
3766 __ Bind(&left_is_negative);
3767 __ movsd(result, (is_min ? left : right));
3747 __ Bind(&done); 3768 __ Bind(&done);
3748 return; 3769 return;
3749 } 3770 }
3750 ASSERT(result_cid() == kSmiCid); 3771 ASSERT(result_cid() == kSmiCid);
3751 UNIMPLEMENTED(); 3772 UNIMPLEMENTED();
3752 } 3773 }
3753 3774
3754 3775
3755 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3776 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3756 Register value = locs()->in(0).reg(); 3777 Register value = locs()->in(0).reg();
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
4472 PcDescriptors::kOther, 4493 PcDescriptors::kOther,
4473 locs()); 4494 locs());
4474 __ Drop(2); // Discard type arguments and receiver. 4495 __ Drop(2); // Discard type arguments and receiver.
4475 } 4496 }
4476 4497
4477 } // namespace dart 4498 } // namespace dart
4478 4499
4479 #undef __ 4500 #undef __
4480 4501
4481 #endif // defined TARGET_ARCH_X64 4502 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698