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

Side by Side Diff: runtime/vm/intermediate_language_arm.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_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 3348 matching lines...) Expand 10 before | Expand all | Expand 10 after
3359 summary->set_out(Location::RequiresFpuRegister()); 3359 summary->set_out(Location::RequiresFpuRegister());
3360 return summary; 3360 return summary;
3361 } 3361 }
3362 ASSERT(result_cid() == kSmiCid); 3362 ASSERT(result_cid() == kSmiCid);
3363 UNIMPLEMENTED(); 3363 UNIMPLEMENTED();
3364 return NULL; 3364 return NULL;
3365 } 3365 }
3366 3366
3367 3367
3368 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3368 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3369 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
3370 (op_kind() == MethodRecognizer::kMathMax));
3369 if (result_cid() == kDoubleCid) { 3371 if (result_cid() == kDoubleCid) {
3370 Label done, is_nan; 3372 Label done, returns_nan, are_equal;
3371 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); 3373 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg());
3372 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); 3374 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg());
3373 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 3375 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
3374 Register temp = locs()->temp(0).reg(); 3376 Register temp = locs()->temp(0).reg();
3375 __ vcmpd(left, right); 3377 __ vcmpd(left, right);
3376 __ vmstat(); 3378 __ vmstat();
3377 __ b(&is_nan, VS); 3379 __ b(&returns_nan, VS);
3378 Condition double_condition, neg_double_condition; 3380 __ b(&are_equal, EQ);
3379 if (op_kind() == MethodRecognizer::kMathMin) { 3381 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3380 double_condition = TokenKindToDoubleCondition(Token::kLT); 3382 const Condition double_condition =
3381 neg_double_condition = TokenKindToDoubleCondition(Token::kGTE); 3383 is_min ? TokenKindToDoubleCondition(Token::kLT)
3382 } else { 3384 : TokenKindToDoubleCondition(Token::kGT);
3383 ASSERT(op_kind() == MethodRecognizer::kMathMax); 3385 const Condition neg_double_condition =
3384 double_condition = TokenKindToDoubleCondition(Token::kGT); 3386 is_min ? TokenKindToDoubleCondition(Token::kGTE)
3385 neg_double_condition = TokenKindToDoubleCondition(Token::kLTE); 3387 : TokenKindToDoubleCondition(Token::kLTE);
3386 }
3387 __ vmovd(result, left, double_condition); 3388 __ vmovd(result, left, double_condition);
3388 __ vmovd(result, right, neg_double_condition); 3389 __ vmovd(result, right, neg_double_condition);
3389 __ b(&done); 3390 __ b(&done);
3390 3391
3391 __ Bind(&is_nan); 3392 __ Bind(&returns_nan);
3392 __ LoadDImmediate(result, NAN, temp); 3393 __ LoadDImmediate(result, NAN, temp);
3394 __ b(&done);
3395
3396 __ Bind(&are_equal);
3397 // Check for negative zero: -0.0 is equal 0.0 but min or max must return
3398 // -0.0 or 0.0 respectively.
3399 // Check for negative left value (get the sign bit):
3400 // - min -> left is negative ? left : right.
3401 // - max -> left is negative ? right : left
3402 // Check the sign bit.
3403 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp.
3404 __ mov(temp, ShifterOperand(temp, LSR, 31));
3405 __ tst(temp, ShifterOperand(1)); // NE -> is negative.
regis 2013/07/22 20:55:11 You do not need to sign extend to test the sign bi
srdjan 2013/07/22 21:10:16 Done.
3406 if (is_min) {
3407 __ vmovd(result, left, NE);
3408 __ vmovd(result, right, EQ);
3409 } else {
3410 __ vmovd(result, right, NE);
3411 __ vmovd(result, left, EQ);
3412 }
3413
3393 __ Bind(&done); 3414 __ Bind(&done);
3394 return; 3415 return;
3395 } 3416 }
3396 ASSERT(result_cid() == kSmiCid); 3417 ASSERT(result_cid() == kSmiCid);
3397 UNIMPLEMENTED(); 3418 UNIMPLEMENTED();
3398 } 3419 }
3399 3420
3400 3421
3401 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 3422 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
3402 const intptr_t kNumInputs = 1; 3423 const intptr_t kNumInputs = 1;
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
4089 compiler->GenerateCall(token_pos(), 4110 compiler->GenerateCall(token_pos(),
4090 &label, 4111 &label,
4091 PcDescriptors::kOther, 4112 PcDescriptors::kOther,
4092 locs()); 4113 locs());
4093 __ Drop(2); // Discard type arguments and receiver. 4114 __ Drop(2); // Discard type arguments and receiver.
4094 } 4115 }
4095 4116
4096 } // namespace dart 4117 } // namespace dart
4097 4118
4098 #endif // defined TARGET_ARCH_ARM 4119 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698