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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 3311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3322 } else { | 3322 } else { |
| 3323 Register temp = locs()->temp(0).reg(); | 3323 Register temp = locs()->temp(0).reg(); |
| 3324 __ movl(temp, left); | 3324 __ movl(temp, left); |
| 3325 __ orl(temp, right); | 3325 __ orl(temp, right); |
| 3326 __ testl(temp, Immediate(kSmiTagMask)); | 3326 __ testl(temp, Immediate(kSmiTagMask)); |
| 3327 } | 3327 } |
| 3328 __ j(ZERO, deopt); | 3328 __ j(ZERO, deopt); |
| 3329 } | 3329 } |
| 3330 | 3330 |
| 3331 | 3331 |
| 3332 | 3332 LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate, |
| 3333 | |
| 3334 | |
| 3335 LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, | |
| 3336 bool opt) const { | 3333 bool opt) const { |
| 3337 const intptr_t kNumInputs = 1; | 3334 const intptr_t kNumInputs = 1; |
| 3338 const intptr_t kNumTemps = 0; | 3335 const intptr_t kNumTemps = 0; |
| 3339 LocationSummary* summary = new(isolate) LocationSummary( | 3336 LocationSummary* summary = new(isolate) LocationSummary( |
| 3340 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | 3337 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
| 3341 summary->set_in(0, Location::RequiresFpuRegister()); | 3338 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3342 summary->set_out(0, Location::RequiresRegister()); | 3339 summary->set_out(0, Location::RequiresRegister()); |
| 3343 return summary; | 3340 return summary; |
| 3344 } | 3341 } |
| 3345 | 3342 |
| 3346 | 3343 |
| 3347 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3344 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3348 Register out_reg = locs()->out(0).reg(); | 3345 Register out_reg = locs()->out(0).reg(); |
| 3349 XmmRegister value = locs()->in(0).fpu_reg(); | 3346 XmmRegister value = locs()->in(0).fpu_reg(); |
| 3347 | |
| 3350 BoxAllocationSlowPath::Allocate( | 3348 BoxAllocationSlowPath::Allocate( |
| 3351 compiler, this, compiler->double_class(), out_reg, kNoRegister); | 3349 compiler, |
| 3352 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); | 3350 this, |
| 3353 } | 3351 compiler->BoxClassFor(from_representation()), |
| 3354 | 3352 out_reg, |
| 3355 | 3353 kNoRegister); |
| 3356 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3354 |
| 3355 switch (from_representation()) { | |
| 3356 case kUnboxedDouble: | |
| 3357 __ movsd(FieldAddress(out_reg, ValueOffset()), value); | |
| 3358 break; | |
| 3359 case kUnboxedFloat32x4: | |
| 3360 case kUnboxedFloat64x2: | |
| 3361 case kUnboxedInt32x4: | |
| 3362 __ movups(FieldAddress(out_reg, ValueOffset()), value); | |
| 3363 break; | |
| 3364 default: | |
| 3365 UNREACHABLE(); | |
| 3366 break; | |
| 3367 } | |
| 3368 } | |
| 3369 | |
| 3370 | |
| 3371 LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate, | |
| 3357 bool opt) const { | 3372 bool opt) const { |
| 3373 const bool needs_temp = CanDeoptimize() || | |
| 3374 (CanConvertSmi() && (value()->Type()->ToCid() == kSmiCid)); | |
| 3375 | |
| 3358 const intptr_t kNumInputs = 1; | 3376 const intptr_t kNumInputs = 1; |
| 3359 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3360 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); | |
| 3361 const bool needs_writable_input = (value_cid == kSmiCid); | |
| 3362 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 3377 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 3363 LocationSummary* summary = new(isolate) LocationSummary( | 3378 LocationSummary* summary = new(isolate) LocationSummary( |
| 3364 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3379 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3365 summary->set_in(0, needs_writable_input | 3380 summary->set_in(0, Location::RequiresRegister()); |
| 3366 ? Location::WritableRegister() | 3381 if (needs_temp) { |
| 3367 : Location::RequiresRegister()); | 3382 summary->set_temp(0, Location::RequiresRegister()); |
| 3368 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); | 3383 } |
| 3369 summary->set_out(0, Location::RequiresFpuRegister()); | 3384 if (representation() == kUnboxedMint) { |
| 3385 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), | |
| 3386 Location::RegisterLocation(EDX))); | |
| 3387 } else { | |
| 3388 summary->set_out(0, Location::RequiresFpuRegister()); | |
| 3389 } | |
| 3370 return summary; | 3390 return summary; |
| 3371 } | 3391 } |
| 3372 | 3392 |
| 3373 | 3393 |
| 3374 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3394 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { |
| 3375 CompileType* value_type = value()->Type(); | 3395 const Register box = locs()->in(0).reg(); |
| 3376 const intptr_t value_cid = value_type->ToCid(); | 3396 |
| 3377 const Register value = locs()->in(0).reg(); | 3397 switch (representation()) { |
| 3378 const XmmRegister result = locs()->out(0).fpu_reg(); | 3398 case kUnboxedMint: { |
| 3379 | 3399 PairLocation* result = locs()->out(0).AsPairLocation(); |
| 3380 if (value_cid == kDoubleCid) { | 3400 __ movl(result->At(0).reg(), FieldAddress(box, ValueOffset())); |
| 3381 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3401 __ movl(result->At(1).reg(), |
| 3382 } else if (value_cid == kSmiCid) { | 3402 FieldAddress(box, ValueOffset() + kWordSize)); |
| 3383 __ SmiUntag(value); // Untag input before conversion. | 3403 break; |
| 3384 __ cvtsi2sd(result, value); | 3404 } |
| 3405 | |
| 3406 case kUnboxedDouble: { | |
| 3407 const FpuRegister result = locs()->out(0).fpu_reg(); | |
| 3408 __ movsd(result, FieldAddress(box, ValueOffset())); | |
| 3409 break; | |
| 3410 } | |
| 3411 | |
| 3412 case kUnboxedFloat32x4: | |
| 3413 case kUnboxedFloat64x2: | |
| 3414 case kUnboxedInt32x4: { | |
| 3415 const FpuRegister result = locs()->out(0).fpu_reg(); | |
| 3416 __ movups(result, FieldAddress(box, ValueOffset())); | |
| 3417 break; | |
| 3418 } | |
| 3419 | |
| 3420 default: | |
| 3421 UNREACHABLE(); | |
| 3422 break; | |
| 3423 } | |
| 3424 } | |
| 3425 | |
| 3426 | |
| 3427 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { | |
| 3428 const Register box = locs()->in(0).reg(); | |
| 3429 | |
| 3430 switch (representation()) { | |
| 3431 case kUnboxedMint: { | |
| 3432 PairLocation* result = locs()->out(0).AsPairLocation(); | |
| 3433 ASSERT(result->At(0).reg() == EAX); | |
| 3434 ASSERT(result->At(1).reg() == EDX); | |
| 3435 __ movl(EAX, box); | |
| 3436 __ SmiUntag(EAX); | |
| 3437 __ cdq(); | |
| 3438 break; | |
| 3439 } | |
| 3440 | |
| 3441 case kUnboxedDouble: { | |
| 3442 const Register temp = locs()->temp(0).reg(); | |
| 3443 const FpuRegister result = locs()->out(0).fpu_reg(); | |
| 3444 __ movl(temp, box); | |
| 3445 __ SmiUntag(temp); | |
| 3446 __ cvtsi2sd(result, temp); | |
| 3447 break; | |
| 3448 } | |
| 3449 | |
| 3450 default: | |
| 3451 UNREACHABLE(); | |
| 3452 break; | |
| 3453 } | |
| 3454 } | |
| 3455 | |
| 3456 | |
| 3457 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3458 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3459 const intptr_t box_cid = BoxCid(); | |
| 3460 | |
| 3461 if (value_cid == box_cid) { | |
| 3462 EmitLoadFromBox(compiler); | |
| 3463 } else if (CanConvertSmi() && (value_cid == kSmiCid)) { | |
| 3464 EmitSmiConversion(compiler); | |
| 3385 } else { | 3465 } else { |
| 3466 const Register box = locs()->in(0).reg(); | |
| 3467 const Register temp = locs()->temp(0).reg(); | |
| 3386 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), | 3468 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), |
| 3387 ICData::kDeoptBinaryDoubleOp); | 3469 ICData::kDeoptCheckClass); |
| 3388 Register temp = locs()->temp(0).reg(); | 3470 Label is_smi; |
| 3389 if (value_type->is_nullable() && | 3471 |
| 3390 (value_type->ToNullableCid() == kDoubleCid)) { | 3472 if ((value()->Type()->ToNullableCid() == box_cid) && |
| 3473 value()->Type()->is_nullable()) { | |
| 3391 const Immediate& raw_null = | 3474 const Immediate& raw_null = |
| 3392 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 3475 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 3393 __ cmpl(value, raw_null); | 3476 __ cmpl(box, raw_null); |
| 3394 __ j(EQUAL, deopt); | 3477 __ j(EQUAL, deopt); |
| 3395 // It must be double now. | |
| 3396 __ movsd(result, FieldAddress(value, Double::value_offset())); | |
| 3397 } else { | 3478 } else { |
| 3398 Label is_smi, done; | 3479 __ testl(box, Immediate(kSmiTagMask)); |
| 3399 __ testl(value, Immediate(kSmiTagMask)); | 3480 __ j(ZERO, CanConvertSmi() ? &is_smi : deopt); |
| 3400 __ j(ZERO, &is_smi); | 3481 __ CompareClassId(box, box_cid, temp); |
| 3401 __ CompareClassId(value, kDoubleCid, temp); | |
| 3402 __ j(NOT_EQUAL, deopt); | 3482 __ j(NOT_EQUAL, deopt); |
| 3403 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3483 } |
| 3484 | |
| 3485 EmitLoadFromBox(compiler); | |
| 3486 | |
| 3487 if (is_smi.IsLinked()) { | |
| 3488 Label done; | |
| 3404 __ jmp(&done); | 3489 __ jmp(&done); |
| 3405 __ Bind(&is_smi); | 3490 __ Bind(&is_smi); |
| 3406 __ movl(temp, value); | 3491 EmitSmiConversion(compiler); |
| 3407 __ SmiUntag(temp); | |
| 3408 __ cvtsi2sd(result, temp); | |
| 3409 __ Bind(&done); | 3492 __ Bind(&done); |
| 3410 } | 3493 } |
| 3411 } | 3494 } |
| 3412 } | 3495 } |
| 3413 | 3496 |
| 3414 | 3497 |
| 3415 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3498 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate, |
| 3416 bool opt) const { | |
| 3417 const intptr_t kNumInputs = 1; | |
| 3418 const intptr_t kNumTemps = 0; | |
| 3419 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3420 isolate, kNumInputs, | |
| 3421 kNumTemps, | |
| 3422 LocationSummary::kCallOnSlowPath); | |
| 3423 summary->set_in(0, Location::RequiresFpuRegister()); | |
| 3424 summary->set_out(0, Location::RequiresRegister()); | |
| 3425 return summary; | |
| 3426 } | |
| 3427 | |
| 3428 | |
| 3429 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3430 Register out_reg = locs()->out(0).reg(); | |
| 3431 XmmRegister value = locs()->in(0).fpu_reg(); | |
| 3432 | |
| 3433 BoxAllocationSlowPath::Allocate( | |
| 3434 compiler, this, compiler->float32x4_class(), out_reg, kNoRegister); | |
| 3435 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); | |
| 3436 } | |
| 3437 | |
| 3438 | |
| 3439 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | |
| 3440 bool opt) const { | |
| 3441 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3442 const intptr_t kNumInputs = 1; | |
| 3443 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; | |
| 3444 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3445 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 3446 summary->set_in(0, Location::RequiresRegister()); | |
| 3447 if (kNumTemps > 0) { | |
| 3448 ASSERT(kNumTemps == 1); | |
| 3449 summary->set_temp(0, Location::RequiresRegister()); | |
| 3450 } | |
| 3451 summary->set_out(0, Location::RequiresFpuRegister()); | |
| 3452 return summary; | |
| 3453 } | |
| 3454 | |
| 3455 | |
| 3456 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3457 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3458 const Register value = locs()->in(0).reg(); | |
| 3459 const XmmRegister result = locs()->out(0).fpu_reg(); | |
| 3460 | |
| 3461 if (value_cid != kFloat32x4Cid) { | |
| 3462 const Register temp = locs()->temp(0).reg(); | |
| 3463 Label* deopt = | |
| 3464 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass); | |
| 3465 __ testl(value, Immediate(kSmiTagMask)); | |
| 3466 __ j(ZERO, deopt); | |
| 3467 __ CompareClassId(value, kFloat32x4Cid, temp); | |
| 3468 __ j(NOT_EQUAL, deopt); | |
| 3469 } | |
| 3470 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | |
| 3471 } | |
| 3472 | |
| 3473 | |
| 3474 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, | |
| 3475 bool opt) const { | |
| 3476 const intptr_t kNumInputs = 1; | |
| 3477 const intptr_t kNumTemps = 0; | |
| 3478 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3479 isolate, kNumInputs, | |
| 3480 kNumTemps, | |
| 3481 LocationSummary::kCallOnSlowPath); | |
| 3482 summary->set_in(0, Location::RequiresFpuRegister()); | |
| 3483 summary->set_out(0, Location::RequiresRegister()); | |
| 3484 return summary; | |
| 3485 } | |
| 3486 | |
| 3487 | |
| 3488 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3489 Register out_reg = locs()->out(0).reg(); | |
| 3490 XmmRegister value = locs()->in(0).fpu_reg(); | |
| 3491 | |
| 3492 BoxAllocationSlowPath::Allocate( | |
| 3493 compiler, this, compiler->float64x2_class(), out_reg, kNoRegister); | |
| 3494 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); | |
| 3495 } | |
| 3496 | |
| 3497 | |
| 3498 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, | |
| 3499 bool opt) const { | |
| 3500 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3501 const intptr_t kNumInputs = 1; | |
| 3502 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; | |
| 3503 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3504 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 3505 summary->set_in(0, Location::RequiresRegister()); | |
| 3506 if (kNumTemps > 0) { | |
| 3507 ASSERT(kNumTemps == 1); | |
| 3508 summary->set_temp(0, Location::RequiresRegister()); | |
| 3509 } | |
| 3510 summary->set_out(0, Location::RequiresFpuRegister()); | |
| 3511 return summary; | |
| 3512 } | |
| 3513 | |
| 3514 | |
| 3515 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3516 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3517 const Register value = locs()->in(0).reg(); | |
| 3518 const XmmRegister result = locs()->out(0).fpu_reg(); | |
| 3519 | |
| 3520 if (value_cid != kFloat64x2Cid) { | |
| 3521 const Register temp = locs()->temp(0).reg(); | |
| 3522 Label* deopt = | |
| 3523 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass); | |
| 3524 __ testl(value, Immediate(kSmiTagMask)); | |
| 3525 __ j(ZERO, deopt); | |
| 3526 __ CompareClassId(value, kFloat64x2Cid, temp); | |
| 3527 __ j(NOT_EQUAL, deopt); | |
| 3528 } | |
| 3529 __ movups(result, FieldAddress(value, Float64x2::value_offset())); | |
| 3530 } | |
| 3531 | |
| 3532 | |
| 3533 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate, | |
| 3534 bool opt) const { | 3499 bool opt) const { |
|
Florian Schneider
2014/10/30 15:43:23
Indentation.
Vyacheslav Egorov (Google)
2014/10/30 17:57:39
Done.
Vyacheslav Egorov (Google)
2014/10/30 17:57:39
Done.
| |
| 3535 const intptr_t kNumInputs = 1; | 3500 const intptr_t kNumInputs = 1; |
| 3536 const intptr_t kNumTemps = 0; | 3501 const intptr_t kNumTemps = 0; |
| 3537 LocationSummary* summary = new(isolate) LocationSummary( | 3502 LocationSummary* summary = new(isolate) LocationSummary( |
| 3503 isolate, kNumInputs, kNumTemps, | |
| 3504 ValueFitsSmi() ? LocationSummary::kNoCall | |
| 3505 : LocationSummary::kCallOnSlowPath); | |
| 3506 const bool needs_writable_input = ValueFitsSmi() || | |
| 3507 (from_representation() == kUnboxedUint32); | |
| 3508 summary->set_in(0, needs_writable_input ? Location::RequiresRegister() | |
| 3509 : Location::WritableRegister()); | |
| 3510 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() | |
| 3511 : Location::RequiresRegister()); | |
| 3512 return summary; | |
| 3513 } | |
| 3514 | |
| 3515 | |
| 3516 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3517 const Register value = locs()->in(0).reg(); | |
| 3518 const Register out = locs()->out(0).reg(); | |
| 3519 | |
| 3520 __ MoveRegister(out, value); | |
| 3521 __ shll(out, Immediate(kSmiTagSize)); | |
| 3522 if (!ValueFitsSmi()) { | |
| 3523 Label done; | |
| 3524 ASSERT(value != out); | |
| 3525 if (from_representation() == kUnboxedInt32) { | |
| 3526 __ j(NO_OVERFLOW, &done); | |
| 3527 } else { | |
| 3528 __ testl(value, Immediate(0xC0000000)); | |
| 3529 __ j(ZERO, &done); | |
| 3530 } | |
| 3531 | |
| 3532 // Allocate a mint. | |
| 3533 // Value input is writable register and has to be manually preserved | |
| 3534 // on the slow path. | |
| 3535 locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32); | |
| 3536 BoxAllocationSlowPath::Allocate( | |
| 3537 compiler, this, compiler->mint_class(), out, kNoRegister); | |
| 3538 __ movl(FieldAddress(out, Mint::value_offset()), value); | |
| 3539 if (from_representation() == kUnboxedInt32) { | |
| 3540 __ sarl(value, Immediate(31)); // Sign extend. | |
| 3541 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); | |
| 3542 } else { | |
| 3543 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), | |
| 3544 Immediate(0)); | |
| 3545 } | |
| 3546 __ Bind(&done); | |
| 3547 } | |
| 3548 } | |
| 3549 | |
| 3550 | |
| 3551 LocationSummary* BoxInt64Instr::MakeLocationSummary(Isolate* isolate, | |
| 3552 bool opt) const { | |
| 3553 const intptr_t kNumInputs = 1; | |
| 3554 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; | |
| 3555 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3538 isolate, kNumInputs, | 3556 isolate, kNumInputs, |
| 3539 kNumTemps, | 3557 kNumTemps, |
| 3540 LocationSummary::kCallOnSlowPath); | 3558 ValueFitsSmi() |
| 3541 summary->set_in(0, Location::RequiresFpuRegister()); | 3559 ? LocationSummary::kNoCall |
| 3560 : LocationSummary::kCallOnSlowPath); | |
| 3561 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | |
| 3562 Location::RequiresRegister())); | |
| 3563 if (!ValueFitsSmi()) { | |
| 3564 summary->set_temp(0, Location::RequiresRegister()); | |
| 3565 } | |
| 3542 summary->set_out(0, Location::RequiresRegister()); | 3566 summary->set_out(0, Location::RequiresRegister()); |
| 3543 return summary; | 3567 return summary; |
| 3544 } | 3568 } |
| 3545 | 3569 |
| 3546 | 3570 |
| 3547 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3571 void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3572 if (ValueFitsSmi()) { | |
| 3573 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | |
| 3574 Register value_lo = value_pair->At(0).reg(); | |
| 3575 Register out_reg = locs()->out(0).reg(); | |
| 3576 __ movl(out_reg, value_lo); | |
| 3577 __ SmiTag(out_reg); | |
| 3578 return; | |
| 3579 } | |
| 3580 | |
| 3581 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | |
| 3582 Register value_lo = value_pair->At(0).reg(); | |
| 3583 Register value_hi = value_pair->At(1).reg(); | |
| 3548 Register out_reg = locs()->out(0).reg(); | 3584 Register out_reg = locs()->out(0).reg(); |
| 3549 XmmRegister value = locs()->in(0).fpu_reg(); | 3585 |
| 3586 // Copy value_hi into out_reg as a temporary. | |
| 3587 // We modify value_lo but restore it before using it. | |
| 3588 __ movl(out_reg, value_hi); | |
| 3589 | |
| 3590 // Unboxed operations produce smis or mint-sized values. | |
| 3591 // Check if value fits into a smi. | |
| 3592 Label not_smi, done; | |
| 3593 | |
| 3594 // 1. Compute (x + -kMinSmi) which has to be in the range | |
| 3595 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi. | |
| 3596 __ addl(value_lo, Immediate(0x40000000)); | |
| 3597 __ adcl(out_reg, Immediate(0)); | |
| 3598 // 2. Unsigned compare to -kMinSmi+kMaxSmi. | |
| 3599 __ cmpl(value_lo, Immediate(0x80000000)); | |
| 3600 __ sbbl(out_reg, Immediate(0)); | |
| 3601 __ j(ABOVE_EQUAL, ¬_smi); | |
| 3602 // 3. Restore lower half if result is a smi. | |
| 3603 __ subl(value_lo, Immediate(0x40000000)); | |
| 3604 __ movl(out_reg, value_lo); | |
| 3605 __ SmiTag(out_reg); | |
| 3606 __ jmp(&done); | |
| 3607 __ Bind(¬_smi); | |
| 3608 // 3. Restore lower half of input before using it. | |
| 3609 __ subl(value_lo, Immediate(0x40000000)); | |
| 3550 | 3610 |
| 3551 BoxAllocationSlowPath::Allocate( | 3611 BoxAllocationSlowPath::Allocate( |
| 3552 compiler, this, compiler->int32x4_class(), out_reg, kNoRegister); | 3612 compiler, this, compiler->mint_class(), out_reg, kNoRegister); |
| 3553 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); | 3613 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); |
| 3554 } | 3614 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); |
| 3555 | 3615 __ Bind(&done); |
| 3556 | 3616 } |
| 3557 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate, | 3617 |
| 3558 bool opt) const { | 3618 |
| 3619 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate, | |
| 3620 bool opt) const { | |
| 3559 const intptr_t value_cid = value()->Type()->ToCid(); | 3621 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3560 const intptr_t kNumInputs = 1; | 3622 const intptr_t kNumInputs = 1; |
| 3561 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; | 3623 intptr_t kNumTemps = 0; |
| 3624 | |
| 3625 if (CanDeoptimize()) { | |
| 3626 if ((value_cid != kSmiCid) && | |
| 3627 (value_cid != kMintCid) && | |
| 3628 !is_truncating()) { | |
| 3629 kNumTemps = 2; | |
| 3630 } else { | |
| 3631 kNumTemps = 1; | |
| 3632 } | |
| 3633 } | |
| 3634 | |
| 3562 LocationSummary* summary = new(isolate) LocationSummary( | 3635 LocationSummary* summary = new(isolate) LocationSummary( |
| 3563 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3636 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3564 summary->set_in(0, Location::RequiresRegister()); | 3637 summary->set_in(0, Location::RequiresRegister()); |
| 3565 if (kNumTemps > 0) { | 3638 for (int i = 0; i < kNumTemps; i++) { |
| 3566 ASSERT(kNumTemps == 1); | 3639 summary->set_temp(i, Location::RequiresRegister()); |
| 3567 summary->set_temp(0, Location::RequiresRegister()); | 3640 } |
| 3568 } | 3641 summary->set_out(0, ((value_cid == kSmiCid) || (value_cid != kMintCid)) ? |
| 3569 summary->set_out(0, Location::RequiresFpuRegister()); | 3642 Location::SameAsFirstInput() : Location::RequiresRegister()); |
| 3570 return summary; | 3643 return summary; |
| 3571 } | 3644 } |
| 3572 | 3645 |
| 3573 | 3646 |
| 3574 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3647 static void LoadInt32FromMint(FlowGraphCompiler* compiler, |
| 3648 Register result, | |
| 3649 const Address& lo, | |
| 3650 const Address& hi, | |
| 3651 Register temp, | |
| 3652 Label* deopt) { | |
| 3653 __ movl(result, lo); | |
| 3654 if (deopt != NULL) { | |
| 3655 ASSERT(temp != result); | |
| 3656 __ movl(temp, result); | |
| 3657 __ sarl(temp, Immediate(31)); | |
| 3658 __ cmpl(temp, hi); | |
| 3659 __ j(NOT_EQUAL, deopt); | |
| 3660 } | |
| 3661 } | |
| 3662 | |
| 3663 | |
| 3664 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3575 const intptr_t value_cid = value()->Type()->ToCid(); | 3665 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3576 const Register value = locs()->in(0).reg(); | 3666 Register value = locs()->in(0).reg(); |
| 3577 const XmmRegister result = locs()->out(0).fpu_reg(); | 3667 const Register result = locs()->out(0).reg(); |
| 3578 | 3668 const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; |
| 3579 if (value_cid != kInt32x4Cid) { | 3669 Label* deopt = CanDeoptimize() ? |
| 3580 const Register temp = locs()->temp(0).reg(); | 3670 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL; |
| 3581 Label* deopt = | 3671 Label* out_of_range = !is_truncating() ? deopt : NULL; |
| 3582 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass); | 3672 |
| 3583 __ testl(value, Immediate(kSmiTagMask)); | 3673 const intptr_t lo_offset = Mint::value_offset(); |
| 3584 __ j(ZERO, deopt); | 3674 const intptr_t hi_offset = Mint::value_offset() + kWordSize; |
| 3585 __ CompareClassId(value, kInt32x4Cid, temp); | 3675 |
| 3676 if (value_cid == kSmiCid) { | |
| 3677 ASSERT(value == result); | |
| 3678 __ SmiUntag(value); | |
| 3679 } else if (value_cid == kMintCid) { | |
| 3680 ASSERT((value != result) || (out_of_range == NULL)); | |
| 3681 LoadInt32FromMint(compiler, | |
| 3682 result, | |
| 3683 FieldAddress(value, lo_offset), | |
| 3684 FieldAddress(value, hi_offset), | |
| 3685 temp, | |
| 3686 out_of_range); | |
| 3687 } else { | |
| 3688 ASSERT(value == result); | |
| 3689 Label done; | |
| 3690 __ SmiUntagOrCheckClass(value, kMintCid, temp, &done); | |
| 3586 __ j(NOT_EQUAL, deopt); | 3691 __ j(NOT_EQUAL, deopt); |
| 3587 } | 3692 if (out_of_range != NULL) { |
| 3588 __ movups(result, FieldAddress(value, Int32x4::value_offset())); | 3693 Register value_temp = locs()->temp(1).reg(); |
| 3589 } | 3694 __ movl(value_temp, value); |
| 3590 | 3695 value = value_temp; |
| 3696 } | |
| 3697 LoadInt32FromMint(compiler, | |
| 3698 result, | |
| 3699 Address(value, TIMES_2, lo_offset), | |
| 3700 Address(value, TIMES_2, hi_offset), | |
| 3701 temp, | |
| 3702 out_of_range); | |
| 3703 __ Bind(&done); | |
| 3704 } | |
| 3705 } | |
| 3591 | 3706 |
| 3592 | 3707 |
| 3593 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, | 3708 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, |
| 3594 bool opt) const { | 3709 bool opt) const { |
| 3595 const intptr_t kNumInputs = 2; | 3710 const intptr_t kNumInputs = 2; |
| 3596 const intptr_t kNumTemps = 0; | 3711 const intptr_t kNumTemps = 0; |
| 3597 LocationSummary* summary = new(isolate) LocationSummary( | 3712 LocationSummary* summary = new(isolate) LocationSummary( |
| 3598 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3713 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3599 summary->set_in(0, Location::RequiresFpuRegister()); | 3714 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3600 summary->set_in(1, Location::RequiresFpuRegister()); | 3715 summary->set_in(1, Location::RequiresFpuRegister()); |
| (...skipping 2035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5636 __ j(ABOVE_EQUAL, deopt); | 5751 __ j(ABOVE_EQUAL, deopt); |
| 5637 } else { | 5752 } else { |
| 5638 Register index = index_loc.reg(); | 5753 Register index = index_loc.reg(); |
| 5639 Register length = length_loc.reg(); | 5754 Register length = length_loc.reg(); |
| 5640 __ cmpl(length, index); | 5755 __ cmpl(length, index); |
| 5641 __ j(BELOW_EQUAL, deopt); | 5756 __ j(BELOW_EQUAL, deopt); |
| 5642 } | 5757 } |
| 5643 } | 5758 } |
| 5644 | 5759 |
| 5645 | 5760 |
| 5646 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, | |
| 5647 bool opt) const { | |
| 5648 const intptr_t kNumInputs = 1; | |
| 5649 const intptr_t kNumTemps = 0; | |
| 5650 LocationSummary* summary = new(isolate) LocationSummary( | |
| 5651 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 5652 summary->set_in(0, Location::RequiresRegister()); | |
| 5653 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), | |
| 5654 Location::RegisterLocation(EDX))); | |
| 5655 return summary; | |
| 5656 } | |
| 5657 | |
| 5658 | |
| 5659 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 5660 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 5661 const Register value = locs()->in(0).reg(); | |
| 5662 PairLocation* result_pair = locs()->out(0).AsPairLocation(); | |
| 5663 Register result_lo = result_pair->At(0).reg(); | |
| 5664 Register result_hi = result_pair->At(1).reg(); | |
| 5665 | |
| 5666 ASSERT(value != result_lo); | |
| 5667 ASSERT(value != result_hi); | |
| 5668 ASSERT(result_lo == EAX); | |
| 5669 ASSERT(result_hi == EDX); | |
| 5670 | |
| 5671 if (value_cid == kMintCid) { | |
| 5672 __ movl(result_lo, FieldAddress(value, Mint::value_offset())); | |
| 5673 __ movl(result_hi, FieldAddress(value, Mint::value_offset() + kWordSize)); | |
| 5674 } else if (value_cid == kSmiCid) { | |
| 5675 __ movl(result_lo, value); | |
| 5676 __ SmiUntag(result_lo); | |
| 5677 // Sign extend into result_hi. | |
| 5678 __ cdq(); | |
| 5679 } else { | |
| 5680 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), | |
| 5681 ICData::kDeoptUnboxInteger); | |
| 5682 Label is_smi, done; | |
| 5683 __ testl(value, Immediate(kSmiTagMask)); | |
| 5684 __ j(ZERO, &is_smi); | |
| 5685 __ CompareClassId(value, kMintCid, result_lo); | |
| 5686 __ j(NOT_EQUAL, deopt); | |
| 5687 __ movl(result_lo, FieldAddress(value, Mint::value_offset())); | |
| 5688 __ movl(result_hi, FieldAddress(value, Mint::value_offset() + kWordSize)); | |
| 5689 __ jmp(&done); | |
| 5690 __ Bind(&is_smi); | |
| 5691 __ movl(result_lo, value); | |
| 5692 __ SmiUntag(result_lo); | |
| 5693 // Sign extend into result_hi. | |
| 5694 __ cdq(); | |
| 5695 __ Bind(&done); | |
| 5696 } | |
| 5697 } | |
| 5698 | |
| 5699 | |
| 5700 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, | |
| 5701 bool opt) const { | |
| 5702 const intptr_t kNumInputs = 1; | |
| 5703 const intptr_t kNumTemps = is_smi() ? 0 : 1; | |
| 5704 LocationSummary* summary = new(isolate) LocationSummary( | |
| 5705 isolate, kNumInputs, | |
| 5706 kNumTemps, | |
| 5707 is_smi() | |
| 5708 ? LocationSummary::kNoCall | |
| 5709 : LocationSummary::kCallOnSlowPath); | |
| 5710 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | |
| 5711 Location::RequiresRegister())); | |
| 5712 if (!is_smi()) { | |
| 5713 summary->set_temp(0, Location::RequiresRegister()); | |
| 5714 } | |
| 5715 summary->set_out(0, Location::RequiresRegister()); | |
| 5716 return summary; | |
| 5717 } | |
| 5718 | |
| 5719 | |
| 5720 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 5721 if (is_smi()) { | |
| 5722 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | |
| 5723 Register value_lo = value_pair->At(0).reg(); | |
| 5724 Register out_reg = locs()->out(0).reg(); | |
| 5725 __ movl(out_reg, value_lo); | |
| 5726 __ SmiTag(out_reg); | |
| 5727 return; | |
| 5728 } | |
| 5729 | |
| 5730 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | |
| 5731 Register value_lo = value_pair->At(0).reg(); | |
| 5732 Register value_hi = value_pair->At(1).reg(); | |
| 5733 Register out_reg = locs()->out(0).reg(); | |
| 5734 | |
| 5735 // Copy value_hi into out_reg as a temporary. | |
| 5736 // We modify value_lo but restore it before using it. | |
| 5737 __ movl(out_reg, value_hi); | |
| 5738 | |
| 5739 // Unboxed operations produce smis or mint-sized values. | |
| 5740 // Check if value fits into a smi. | |
| 5741 Label not_smi, done; | |
| 5742 | |
| 5743 // 1. Compute (x + -kMinSmi) which has to be in the range | |
| 5744 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi. | |
| 5745 __ addl(value_lo, Immediate(0x40000000)); | |
| 5746 __ adcl(out_reg, Immediate(0)); | |
| 5747 // 2. Unsigned compare to -kMinSmi+kMaxSmi. | |
| 5748 __ cmpl(value_lo, Immediate(0x80000000)); | |
| 5749 __ sbbl(out_reg, Immediate(0)); | |
| 5750 __ j(ABOVE_EQUAL, ¬_smi); | |
| 5751 // 3. Restore lower half if result is a smi. | |
| 5752 __ subl(value_lo, Immediate(0x40000000)); | |
| 5753 __ movl(out_reg, value_lo); | |
| 5754 __ SmiTag(out_reg); | |
| 5755 __ jmp(&done); | |
| 5756 __ Bind(¬_smi); | |
| 5757 // 3. Restore lower half of input before using it. | |
| 5758 __ subl(value_lo, Immediate(0x40000000)); | |
| 5759 | |
| 5760 BoxAllocationSlowPath::Allocate( | |
| 5761 compiler, this, compiler->mint_class(), out_reg, kNoRegister); | |
| 5762 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); | |
| 5763 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); | |
| 5764 __ Bind(&done); | |
| 5765 } | |
| 5766 | |
| 5767 | |
| 5768 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | 5761 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| 5769 bool opt) const { | 5762 bool opt) const { |
| 5770 const intptr_t kNumInputs = 2; | 5763 const intptr_t kNumInputs = 2; |
| 5771 switch (op_kind()) { | 5764 switch (op_kind()) { |
| 5772 case Token::kBIT_AND: | 5765 case Token::kBIT_AND: |
| 5773 case Token::kBIT_OR: | 5766 case Token::kBIT_OR: |
| 5774 case Token::kBIT_XOR: | 5767 case Token::kBIT_XOR: |
| 5775 case Token::kADD: | 5768 case Token::kADD: |
| 5776 case Token::kSUB: | 5769 case Token::kSUB: |
| 5777 case Token::kMUL: { | 5770 case Token::kMUL: { |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6214 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6207 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6215 Register out = locs()->out(0).reg(); | 6208 Register out = locs()->out(0).reg(); |
| 6216 ASSERT(locs()->in(0).reg() == out); | 6209 ASSERT(locs()->in(0).reg() == out); |
| 6217 | 6210 |
| 6218 ASSERT(op_kind() == Token::kBIT_NOT); | 6211 ASSERT(op_kind() == Token::kBIT_NOT); |
| 6219 | 6212 |
| 6220 __ notl(out); | 6213 __ notl(out); |
| 6221 } | 6214 } |
| 6222 | 6215 |
| 6223 | 6216 |
| 6224 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate, | |
| 6225 bool opt) const { | |
| 6226 const intptr_t kNumInputs = 1; | |
| 6227 const intptr_t kNumTemps = 0; | |
| 6228 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6229 isolate, kNumInputs, kNumTemps, | |
| 6230 ValueFitsSmi() ? LocationSummary::kNoCall | |
| 6231 : LocationSummary::kCallOnSlowPath); | |
| 6232 const bool needs_writable_input = ValueFitsSmi() || | |
| 6233 (from_representation() == kUnboxedUint32); | |
| 6234 summary->set_in(0, needs_writable_input ? Location::RequiresRegister() | |
| 6235 : Location::WritableRegister()); | |
| 6236 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() | |
| 6237 : Location::RequiresRegister()); | |
| 6238 return summary; | |
| 6239 } | |
| 6240 | |
| 6241 | |
| 6242 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6243 const Register value = locs()->in(0).reg(); | |
| 6244 const Register out = locs()->out(0).reg(); | |
| 6245 | |
| 6246 __ MoveRegister(out, value); | |
| 6247 __ shll(out, Immediate(kSmiTagSize)); | |
| 6248 if (!ValueFitsSmi()) { | |
| 6249 Label done; | |
| 6250 ASSERT(value != out); | |
| 6251 if (from_representation() == kUnboxedInt32) { | |
| 6252 __ j(NO_OVERFLOW, &done); | |
| 6253 } else { | |
| 6254 __ testl(value, Immediate(0xC0000000)); | |
| 6255 __ j(ZERO, &done); | |
| 6256 } | |
| 6257 | |
| 6258 // Allocate a mint. | |
| 6259 // Value input is writable register and has to be manually preserved | |
| 6260 // on the slow path. | |
| 6261 locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32); | |
| 6262 BoxAllocationSlowPath::Allocate( | |
| 6263 compiler, this, compiler->mint_class(), out, kNoRegister); | |
| 6264 __ movl(FieldAddress(out, Mint::value_offset()), value); | |
| 6265 if (from_representation() == kUnboxedInt32) { | |
| 6266 __ sarl(value, Immediate(31)); // Sign extend. | |
| 6267 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); | |
| 6268 } else { | |
| 6269 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), | |
| 6270 Immediate(0)); | |
| 6271 } | |
| 6272 __ Bind(&done); | |
| 6273 } | |
| 6274 } | |
| 6275 | |
| 6276 | |
| 6277 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, | |
| 6278 bool opt) const { | |
| 6279 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 6280 const intptr_t kNumInputs = 1; | |
| 6281 intptr_t kNumTemps = 0; | |
| 6282 | |
| 6283 if (CanDeoptimize()) { | |
| 6284 if ((value_cid != kSmiCid) && | |
| 6285 (value_cid != kMintCid) && | |
| 6286 !is_truncating()) { | |
| 6287 kNumTemps = 2; | |
| 6288 } else { | |
| 6289 kNumTemps = 1; | |
| 6290 } | |
| 6291 } | |
| 6292 | |
| 6293 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6294 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 6295 summary->set_in(0, Location::RequiresRegister()); | |
| 6296 for (int i = 0; i < kNumTemps; i++) { | |
| 6297 summary->set_temp(i, Location::RequiresRegister()); | |
| 6298 } | |
| 6299 summary->set_out(0, ((value_cid == kSmiCid) || (value_cid != kMintCid)) ? | |
| 6300 Location::SameAsFirstInput() : Location::RequiresRegister()); | |
| 6301 return summary; | |
| 6302 } | |
| 6303 | |
| 6304 | |
| 6305 static void LoadInt32FromMint(FlowGraphCompiler* compiler, | |
| 6306 Register result, | |
| 6307 const Address& lo, | |
| 6308 const Address& hi, | |
| 6309 Register temp, | |
| 6310 Label* deopt) { | |
| 6311 __ movl(result, lo); | |
| 6312 if (deopt != NULL) { | |
| 6313 ASSERT(temp != result); | |
| 6314 __ movl(temp, result); | |
| 6315 __ sarl(temp, Immediate(31)); | |
| 6316 __ cmpl(temp, hi); | |
| 6317 __ j(NOT_EQUAL, deopt); | |
| 6318 } | |
| 6319 } | |
| 6320 | |
| 6321 | |
| 6322 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6323 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 6324 Register value = locs()->in(0).reg(); | |
| 6325 const Register result = locs()->out(0).reg(); | |
| 6326 const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; | |
| 6327 Label* deopt = CanDeoptimize() ? | |
| 6328 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL; | |
| 6329 Label* out_of_range = !is_truncating() ? deopt : NULL; | |
| 6330 | |
| 6331 const intptr_t lo_offset = Mint::value_offset(); | |
| 6332 const intptr_t hi_offset = Mint::value_offset() + kWordSize; | |
| 6333 | |
| 6334 if (value_cid == kSmiCid) { | |
| 6335 ASSERT(value == result); | |
| 6336 __ SmiUntag(value); | |
| 6337 } else if (value_cid == kMintCid) { | |
| 6338 ASSERT((value != result) || (out_of_range == NULL)); | |
| 6339 LoadInt32FromMint(compiler, | |
| 6340 result, | |
| 6341 FieldAddress(value, lo_offset), | |
| 6342 FieldAddress(value, hi_offset), | |
| 6343 temp, | |
| 6344 out_of_range); | |
| 6345 } else { | |
| 6346 ASSERT(value == result); | |
| 6347 Label done; | |
| 6348 __ SmiUntagOrCheckClass(value, kMintCid, temp, &done); | |
| 6349 __ j(NOT_EQUAL, deopt); | |
| 6350 if (out_of_range != NULL) { | |
| 6351 Register value_temp = locs()->temp(1).reg(); | |
| 6352 __ movl(value_temp, value); | |
| 6353 value = value_temp; | |
| 6354 } | |
| 6355 LoadInt32FromMint(compiler, | |
| 6356 result, | |
| 6357 Address(value, TIMES_2, lo_offset), | |
| 6358 Address(value, TIMES_2, hi_offset), | |
| 6359 temp, | |
| 6360 out_of_range); | |
| 6361 __ Bind(&done); | |
| 6362 } | |
| 6363 } | |
| 6364 | |
| 6365 | |
| 6366 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 6217 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
| 6367 bool opt) const { | 6218 bool opt) const { |
| 6368 const intptr_t kNumInputs = 1; | 6219 const intptr_t kNumInputs = 1; |
| 6369 const intptr_t kNumTemps = 0; | 6220 const intptr_t kNumTemps = 0; |
| 6370 LocationSummary* summary = new(isolate) LocationSummary( | 6221 LocationSummary* summary = new(isolate) LocationSummary( |
| 6371 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6222 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6372 if ((from() == kUnboxedInt32 || from() == kUnboxedUint32) && | 6223 if ((from() == kUnboxedInt32 || from() == kUnboxedUint32) && |
| 6373 (to() == kUnboxedInt32 || to() == kUnboxedUint32)) { | 6224 (to() == kUnboxedInt32 || to() == kUnboxedUint32)) { |
| 6374 summary->set_in(0, Location::RequiresRegister()); | 6225 summary->set_in(0, Location::RequiresRegister()); |
| 6375 summary->set_out(0, Location::SameAsFirstInput()); | 6226 summary->set_out(0, Location::SameAsFirstInput()); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 6400 // Representations are bitwise equivalent. | 6251 // Representations are bitwise equivalent. |
| 6401 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); | 6252 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); |
| 6402 if (CanDeoptimize()) { | 6253 if (CanDeoptimize()) { |
| 6403 Label* deopt = | 6254 Label* deopt = |
| 6404 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 6255 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6405 __ testl(locs()->out(0).reg(), locs()->out(0).reg()); | 6256 __ testl(locs()->out(0).reg(), locs()->out(0).reg()); |
| 6406 __ j(NEGATIVE, deopt); | 6257 __ j(NEGATIVE, deopt); |
| 6407 } | 6258 } |
| 6408 } else if (from() == kUnboxedMint) { | 6259 } else if (from() == kUnboxedMint) { |
| 6409 // TODO(vegorov) kUnboxedMint -> kInt32 conversion is currently usually | 6260 // TODO(vegorov) kUnboxedMint -> kInt32 conversion is currently usually |
| 6410 // dominated by a CheckSmi(BoxInteger(val)) which is an artifact of ordering | 6261 // dominated by a CheckSmi(BoxInt64(val)) which is an artifact of ordering |
| 6411 // of optimization passes and the way we check smi-ness of values. | 6262 // of optimization passes and the way we check smi-ness of values. |
| 6412 // Optimize it away. | 6263 // Optimize it away. |
| 6413 ASSERT(to() == kUnboxedInt32 || to() == kUnboxedUint32); | 6264 ASSERT(to() == kUnboxedInt32 || to() == kUnboxedUint32); |
| 6414 PairLocation* in_pair = locs()->in(0).AsPairLocation(); | 6265 PairLocation* in_pair = locs()->in(0).AsPairLocation(); |
| 6415 Register in_lo = in_pair->At(0).reg(); | 6266 Register in_lo = in_pair->At(0).reg(); |
| 6416 Register in_hi = in_pair->At(1).reg(); | 6267 Register in_hi = in_pair->At(1).reg(); |
| 6417 Register out = locs()->out(0).reg(); | 6268 Register out = locs()->out(0).reg(); |
| 6418 // Copy low word. | 6269 // Copy low word. |
| 6419 __ movl(out, in_lo); | 6270 __ movl(out, in_lo); |
| 6420 if (CanDeoptimize()) { | 6271 if (CanDeoptimize()) { |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6768 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6619 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6769 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6620 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6770 #endif | 6621 #endif |
| 6771 } | 6622 } |
| 6772 | 6623 |
| 6773 } // namespace dart | 6624 } // namespace dart |
| 6774 | 6625 |
| 6775 #undef __ | 6626 #undef __ |
| 6776 | 6627 |
| 6777 #endif // defined TARGET_ARCH_IA32 | 6628 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |