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 3337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3348 | 3348 |
| 3349 | 3349 |
| 3350 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3350 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { |
| 3351 if (result_cid() == kDoubleCid) { | 3351 if (result_cid() == kDoubleCid) { |
| 3352 const intptr_t kNumInputs = 2; | 3352 const intptr_t kNumInputs = 2; |
| 3353 const intptr_t kNumTemps = 1; | 3353 const intptr_t kNumTemps = 1; |
| 3354 LocationSummary* summary = | 3354 LocationSummary* summary = |
| 3355 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3355 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3356 summary->set_in(0, Location::RequiresFpuRegister()); | 3356 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3357 summary->set_in(1, Location::RequiresFpuRegister()); | 3357 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3358 // Reuse the left register so that code can be made shorter. | |
| 3359 summary->set_out(Location::SameAsFirstInput()); | |
| 3358 summary->set_temp(0, Location::RequiresRegister()); | 3360 summary->set_temp(0, Location::RequiresRegister()); |
| 3359 summary->set_out(Location::RequiresFpuRegister()); | |
| 3360 return summary; | 3361 return summary; |
| 3361 } | 3362 } |
| 3362 ASSERT(result_cid() == kSmiCid); | 3363 ASSERT(result_cid() == kSmiCid); |
| 3363 UNIMPLEMENTED(); | 3364 const intptr_t kNumInputs = 2; |
| 3364 return NULL; | 3365 const intptr_t kNumTemps = 0; |
| 3366 LocationSummary* summary = | |
| 3367 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 3368 summary->set_in(0, Location::RequiresRegister()); | |
| 3369 summary->set_in(1, Location::RequiresRegister()); | |
| 3370 // Reuse the left register so that code can be made shorter. | |
| 3371 summary->set_out(Location::SameAsFirstInput()); | |
| 3372 return summary; | |
| 3365 } | 3373 } |
| 3366 | 3374 |
| 3367 | 3375 |
| 3368 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3376 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3369 ASSERT((op_kind() == MethodRecognizer::kMathMin) || | 3377 ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
| 3370 (op_kind() == MethodRecognizer::kMathMax)); | 3378 (op_kind() == MethodRecognizer::kMathMax)); |
| 3379 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); | |
| 3371 if (result_cid() == kDoubleCid) { | 3380 if (result_cid() == kDoubleCid) { |
| 3372 Label done, returns_nan, are_equal; | 3381 Label done, returns_nan, are_equal; |
| 3373 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3382 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3374 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 3383 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 3375 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3384 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 3376 Register temp = locs()->temp(0).reg(); | 3385 Register temp = locs()->temp(0).reg(); |
| 3377 __ vcmpd(left, right); | 3386 __ vcmpd(left, right); |
| 3378 __ vmstat(); | 3387 __ vmstat(); |
| 3379 __ b(&returns_nan, VS); | 3388 __ b(&returns_nan, VS); |
| 3380 __ b(&are_equal, EQ); | 3389 __ b(&are_equal, EQ); |
| 3381 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); | |
| 3382 const Condition double_condition = | |
| 3383 is_min ? TokenKindToDoubleCondition(Token::kLT) | |
| 3384 : TokenKindToDoubleCondition(Token::kGT); | |
| 3385 const Condition neg_double_condition = | 3390 const Condition neg_double_condition = |
| 3386 is_min ? TokenKindToDoubleCondition(Token::kGTE) | 3391 is_min ? TokenKindToDoubleCondition(Token::kGTE) |
| 3387 : TokenKindToDoubleCondition(Token::kLTE); | 3392 : TokenKindToDoubleCondition(Token::kLTE); |
| 3388 __ vmovd(result, left, double_condition); | 3393 ASSERT(left == result); |
| 3389 __ vmovd(result, right, neg_double_condition); | 3394 __ vmovd(result, right, neg_double_condition); |
| 3390 __ b(&done); | 3395 __ b(&done); |
| 3391 | 3396 |
| 3392 __ Bind(&returns_nan); | 3397 __ Bind(&returns_nan); |
| 3393 __ LoadDImmediate(result, NAN, temp); | 3398 __ LoadDImmediate(result, NAN, temp); |
| 3394 __ b(&done); | 3399 __ b(&done); |
| 3395 | 3400 |
| 3396 __ Bind(&are_equal); | 3401 __ Bind(&are_equal); |
| 3397 // Check for negative zero: -0.0 is equal 0.0 but min or max must return | 3402 // Check for negative zero: -0.0 is equal 0.0 but min or max must return |
| 3398 // -0.0 or 0.0 respectively. | 3403 // -0.0 or 0.0 respectively. |
| 3399 // Check for negative left value (get the sign bit): | 3404 // Check for negative left value (get the sign bit): |
| 3400 // - min -> left is negative ? left : right. | 3405 // - min -> left is negative ? left : right. |
| 3401 // - max -> left is negative ? right : left | 3406 // - max -> left is negative ? right : left |
| 3402 // Check the sign bit. | 3407 // Check the sign bit. |
| 3403 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp. | 3408 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp. |
| 3404 __ cmp(temp, ShifterOperand(0)); | 3409 __ cmp(temp, ShifterOperand(0)); |
| 3405 if (is_min) { | 3410 if (is_min) { |
| 3406 __ vmovd(result, left, LT); | 3411 ASSERT(left == result); |
| 3407 __ vmovd(result, right, GE); | 3412 __ vmovd(result, right, GE); |
| 3408 } else { | 3413 } else { |
| 3409 __ vmovd(result, right, LT); | 3414 __ vmovd(result, right, LT); |
| 3410 __ vmovd(result, left, GE); | 3415 ASSERT(left == result); |
| 3411 } | 3416 } |
| 3412 __ Bind(&done); | 3417 __ Bind(&done); |
| 3413 return; | 3418 return; |
| 3414 } | 3419 } |
| 3420 | |
| 3415 ASSERT(result_cid() == kSmiCid); | 3421 ASSERT(result_cid() == kSmiCid); |
| 3416 UNIMPLEMENTED(); | 3422 Register left = locs()->in(0).reg(); |
| 3423 Register right = locs()->in(1).reg(); | |
| 3424 Register result = locs()->out().reg(); | |
| 3425 __ cmp(left, ShifterOperand(right)); | |
| 3426 ASSERT(result == left); | |
| 3427 if (is_min) { | |
| 3428 __ mov(result, ShifterOperand(right), GE); | |
|
regis
2013/07/23 19:45:47
GT would be more intuitive than GE, but it does no
srdjan
2013/07/23 20:34:01
Done.
| |
| 3429 } else { | |
| 3430 __ mov(result, ShifterOperand(right), LT); | |
| 3431 } | |
| 3417 } | 3432 } |
| 3418 | 3433 |
| 3419 | 3434 |
| 3420 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3435 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 3421 const intptr_t kNumInputs = 1; | 3436 const intptr_t kNumInputs = 1; |
| 3422 const intptr_t kNumTemps = 0; | 3437 const intptr_t kNumTemps = 0; |
| 3423 LocationSummary* summary = | 3438 LocationSummary* summary = |
| 3424 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3439 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3425 summary->set_in(0, Location::RequiresRegister()); | 3440 summary->set_in(0, Location::RequiresRegister()); |
| 3426 // We make use of 3-operand instructions by not requiring result register | 3441 // We make use of 3-operand instructions by not requiring result register |
| (...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4108 compiler->GenerateCall(token_pos(), | 4123 compiler->GenerateCall(token_pos(), |
| 4109 &label, | 4124 &label, |
| 4110 PcDescriptors::kOther, | 4125 PcDescriptors::kOther, |
| 4111 locs()); | 4126 locs()); |
| 4112 __ Drop(2); // Discard type arguments and receiver. | 4127 __ Drop(2); // Discard type arguments and receiver. |
| 4113 } | 4128 } |
| 4114 | 4129 |
| 4115 } // namespace dart | 4130 } // namespace dart |
| 4116 | 4131 |
| 4117 #endif // defined TARGET_ARCH_ARM | 4132 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |