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_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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |