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 3329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3340 } | 3340 } |
| 3341 | 3341 |
| 3342 | 3342 |
| 3343 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3343 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3344 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3344 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3345 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3345 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 3346 __ vsqrtd(result, val); | 3346 __ vsqrtd(result, val); |
| 3347 } | 3347 } |
| 3348 | 3348 |
| 3349 | 3349 |
| 3350 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | |
| 3351 if (result_cid() == kDoubleCid) { | |
| 3352 const intptr_t kNumInputs = 2; | |
| 3353 const intptr_t kNumTemps = 1; | |
| 3354 LocationSummary* summary = | |
| 3355 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 3356 summary->set_in(0, Location::RequiresFpuRegister()); | |
| 3357 summary->set_in(1, Location::RequiresFpuRegister()); | |
| 3358 summary->set_temp(0, Location::RequiresRegister()); | |
| 3359 summary->set_out(Location::RequiresFpuRegister()); | |
| 3360 return summary; | |
| 3361 } | |
| 3362 ASSERT(result_cid() == kSmiCid); | |
| 3363 UNIMPLEMENTED(); | |
| 3364 return NULL; | |
| 3365 } | |
| 3366 | |
| 3367 | |
| 3368 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3369 if (result_cid() == kDoubleCid) { | |
| 3370 Label done, is_left, is_nan; | |
| 3371 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); | |
| 3372 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); | |
| 3373 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | |
| 3374 Register temp = locs()->temp(0).reg(); | |
| 3375 __ vcmpd(left, right); | |
| 3376 __ vmstat(); | |
| 3377 __ b(&is_nan, VS); | |
| 3378 Condition double_condition; | |
| 3379 if (op_kind() == MethodRecognizer::kMathMin) { | |
| 3380 double_condition = TokenKindToDoubleCondition(Token::kLT); | |
| 3381 } else { | |
| 3382 ASSERT(op_kind() == MethodRecognizer::kMathMax); | |
| 3383 double_condition = TokenKindToDoubleCondition(Token::kGT); | |
| 3384 } | |
| 3385 __ b(&is_left, double_condition); | |
| 3386 __ vmovd(result, right); | |
| 3387 __ b(&done); | |
| 3388 __ Bind(&is_left); | |
| 3389 __ vmovd(result, left); | |
|
regis
2013/07/22 16:22:03
You could make both vmovd instructions conditional
srdjan
2013/07/22 16:42:48
Done.
| |
| 3390 __ b(&done); | |
|
zra
2013/07/22 16:21:02
__ vmovd(result, left, double_condition);
__ vmovd
srdjan
2013/07/22 16:42:48
Done.
| |
| 3391 __ Bind(&is_nan); | |
| 3392 static double kNaN = NAN; | |
|
zra
2013/07/22 16:21:02
__ LoadDImmediate(result, NAN);
srdjan
2013/07/22 16:42:48
Done.
| |
| 3393 __ LoadImmediate(temp, reinterpret_cast<int32_t>(&kNaN)); | |
| 3394 __ vldrd(result, Address(temp, 0)); | |
| 3395 __ Bind(&done); | |
| 3396 return; | |
| 3397 } | |
| 3398 ASSERT(result_cid() == kSmiCid); | |
| 3399 UNIMPLEMENTED(); | |
| 3400 } | |
| 3401 | |
| 3402 | |
| 3350 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3403 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 3351 const intptr_t kNumInputs = 1; | 3404 const intptr_t kNumInputs = 1; |
| 3352 const intptr_t kNumTemps = 0; | 3405 const intptr_t kNumTemps = 0; |
| 3353 LocationSummary* summary = | 3406 LocationSummary* summary = |
| 3354 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3407 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3355 summary->set_in(0, Location::RequiresRegister()); | 3408 summary->set_in(0, Location::RequiresRegister()); |
| 3356 // We make use of 3-operand instructions by not requiring result register | 3409 // We make use of 3-operand instructions by not requiring result register |
| 3357 // to be identical to first input register as on Intel. | 3410 // to be identical to first input register as on Intel. |
| 3358 summary->set_out(Location::RequiresRegister()); | 3411 summary->set_out(Location::RequiresRegister()); |
| 3359 return summary; | 3412 return summary; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3525 result->set_in(0, Location::FpuRegisterLocation(Q0)); | 3578 result->set_in(0, Location::FpuRegisterLocation(Q0)); |
| 3526 if (InputCount() == 2) { | 3579 if (InputCount() == 2) { |
| 3527 result->set_in(1, Location::FpuRegisterLocation(Q1)); | 3580 result->set_in(1, Location::FpuRegisterLocation(Q1)); |
| 3528 } | 3581 } |
| 3529 result->set_out(Location::FpuRegisterLocation(Q0)); | 3582 result->set_out(Location::FpuRegisterLocation(Q0)); |
| 3530 return result; | 3583 return result; |
| 3531 } | 3584 } |
| 3532 | 3585 |
| 3533 | 3586 |
| 3534 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3587 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3535 // For pow-function return NAN if exponent is NAN. | 3588 // For pow-function return NaN if exponent is NaN. |
| 3536 Label do_call, skip_call; | 3589 Label do_call, skip_call; |
| 3537 if (recognized_kind() == MethodRecognizer::kDoublePow) { | 3590 if (recognized_kind() == MethodRecognizer::kDoublePow) { |
| 3538 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 3591 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 3539 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3592 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 3540 __ vcmpd(exp, exp); | 3593 __ vcmpd(exp, exp); |
| 3541 __ vmstat(); | 3594 __ vmstat(); |
| 3542 __ b(&do_call, VC); // NaN -> false; | 3595 __ b(&do_call, VC); // NaN -> false; |
| 3543 // Exponent is NaN, return NaN. | 3596 // Exponent is NaN, return NaN. |
| 3544 __ vmovd(result, exp); | 3597 __ vmovd(result, exp); |
| 3545 __ b(&skip_call); | 3598 __ b(&skip_call); |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4038 compiler->GenerateCall(token_pos(), | 4091 compiler->GenerateCall(token_pos(), |
| 4039 &label, | 4092 &label, |
| 4040 PcDescriptors::kOther, | 4093 PcDescriptors::kOther, |
| 4041 locs()); | 4094 locs()); |
| 4042 __ Drop(2); // Discard type arguments and receiver. | 4095 __ Drop(2); // Discard type arguments and receiver. |
| 4043 } | 4096 } |
| 4044 | 4097 |
| 4045 } // namespace dart | 4098 } // namespace dart |
| 4046 | 4099 |
| 4047 #endif // defined TARGET_ARCH_ARM | 4100 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |