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

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

Issue 19792007: Recognize Math's min and max function for doubles and inline the operation. (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 3329 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698