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 "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 3545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3556 } else if (right_cid == kSmiCid) { | 3556 } else if (right_cid == kSmiCid) { |
| 3557 __ tst(left, Operand(kSmiTagMask)); | 3557 __ tst(left, Operand(kSmiTagMask)); |
| 3558 } else { | 3558 } else { |
| 3559 __ orr(IP, left, Operand(right)); | 3559 __ orr(IP, left, Operand(right)); |
| 3560 __ tst(IP, Operand(kSmiTagMask)); | 3560 __ tst(IP, Operand(kSmiTagMask)); |
| 3561 } | 3561 } |
| 3562 __ b(deopt, EQ); | 3562 __ b(deopt, EQ); |
| 3563 } | 3563 } |
| 3564 | 3564 |
| 3565 | 3565 |
| 3566 LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3566 LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate, |
| 3567 bool opt) const { | 3567 bool opt) const { |
| 3568 const intptr_t kNumInputs = 1; | 3568 const intptr_t kNumInputs = 1; |
| 3569 const intptr_t kNumTemps = 1; | 3569 const intptr_t kNumTemps = 1; |
| 3570 LocationSummary* summary = new(isolate) LocationSummary( | 3570 LocationSummary* summary = new(isolate) LocationSummary( |
| 3571 isolate, kNumInputs, | 3571 isolate, kNumInputs, |
| 3572 kNumTemps, | 3572 kNumTemps, |
| 3573 LocationSummary::kCallOnSlowPath); | 3573 LocationSummary::kCallOnSlowPath); |
| 3574 summary->set_in(0, Location::RequiresFpuRegister()); | 3574 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3575 summary->set_temp(0, Location::RequiresRegister()); | 3575 summary->set_temp(0, Location::RequiresRegister()); |
| 3576 summary->set_out(0, Location::RequiresRegister()); | 3576 summary->set_out(0, Location::RequiresRegister()); |
| 3577 return summary; | 3577 return summary; |
| 3578 } | 3578 } |
| 3579 | 3579 |
| 3580 | 3580 |
| 3581 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3581 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3582 const Register out_reg = locs()->out(0).reg(); | 3582 const Register out_reg = locs()->out(0).reg(); |
| 3583 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3583 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 3584 | 3584 |
| 3585 BoxAllocationSlowPath::Allocate( | 3585 BoxAllocationSlowPath::Allocate( |
| 3586 compiler, | 3586 compiler, |
| 3587 this, | 3587 this, |
| 3588 compiler->double_class(), | 3588 compiler->BoxClassFor(from_representation()), |
| 3589 out_reg, | 3589 out_reg, |
| 3590 locs()->temp(0).reg()); | 3590 locs()->temp(0).reg()); |
| 3591 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 3591 |
| 3592 } | 3592 switch (from_representation()) { |
| 3593 | 3593 case kUnboxedDouble: |
| 3594 | 3594 __ StoreDToOffset( |
| 3595 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3595 value, out_reg, ValueOffset() - kHeapObjectTag); |
| 3596 break; | |
| 3597 case kUnboxedFloat32x4: | |
| 3598 case kUnboxedFloat64x2: | |
| 3599 case kUnboxedInt32x4: | |
| 3600 __ StoreMultipleDToOffset( | |
| 3601 value, 2, out_reg, ValueOffset() - kHeapObjectTag); | |
| 3602 break; | |
| 3603 default: | |
| 3604 UNREACHABLE(); | |
| 3605 break; | |
| 3606 } | |
| 3607 } | |
| 3608 | |
| 3609 | |
| 3610 LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate, | |
| 3596 bool opt) const { | 3611 bool opt) const { |
| 3612 const bool needs_temp = CanDeoptimize(); | |
| 3597 const intptr_t kNumInputs = 1; | 3613 const intptr_t kNumInputs = 1; |
| 3598 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3599 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); | |
| 3600 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 3614 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 3601 LocationSummary* summary = new(isolate) LocationSummary( | 3615 LocationSummary* summary = new(isolate) LocationSummary( |
| 3602 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3616 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3603 summary->set_in(0, Location::RequiresRegister()); | 3617 summary->set_in(0, Location::RequiresRegister()); |
| 3604 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); | 3618 if (needs_temp) { |
| 3605 summary->set_out(0, Location::RequiresFpuRegister()); | 3619 summary->set_temp(0, Location::RequiresRegister()); |
| 3620 } | |
| 3621 if (representation() == kUnboxedMint) { | |
| 3622 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | |
| 3623 Location::RequiresRegister())); | |
| 3624 } else { | |
| 3625 summary->set_out(0, Location::RequiresFpuRegister()); | |
| 3626 } | |
| 3606 return summary; | 3627 return summary; |
| 3607 } | 3628 } |
| 3608 | 3629 |
| 3609 | 3630 |
| 3610 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3631 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { |
| 3611 CompileType* value_type = value()->Type(); | 3632 const Register box = locs()->in(0).reg(); |
| 3612 const intptr_t value_cid = value_type->ToCid(); | 3633 |
| 3613 const Register value = locs()->in(0).reg(); | 3634 switch (representation()) { |
| 3614 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 3635 case kUnboxedMint: { |
| 3615 | 3636 PairLocation* result = locs()->out(0).AsPairLocation(); |
| 3616 if (value_cid == kDoubleCid) { | 3637 __ LoadFromOffset(kWord, |
| 3617 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); | 3638 result->At(0).reg(), |
| 3618 } else if (value_cid == kSmiCid) { | 3639 box, |
| 3619 __ SmiUntag(IP, value); | 3640 ValueOffset() - kHeapObjectTag); |
| 3620 __ vmovdr(DTMP, 0, IP); | 3641 __ LoadFromOffset(kWord, |
| 3621 __ vcvtdi(result, STMP); | 3642 result->At(1).reg(), |
| 3643 box, | |
| 3644 ValueOffset() - kHeapObjectTag + kWordSize); | |
| 3645 break; | |
| 3646 } | |
| 3647 | |
| 3648 case kUnboxedDouble: { | |
| 3649 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | |
| 3650 __ LoadDFromOffset( | |
| 3651 result, box, ValueOffset() - kHeapObjectTag); | |
| 3652 break; | |
| 3653 } | |
| 3654 | |
| 3655 case kUnboxedFloat32x4: | |
| 3656 case kUnboxedFloat64x2: | |
| 3657 case kUnboxedInt32x4: { | |
| 3658 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | |
| 3659 __ LoadMultipleDFromOffset( | |
| 3660 result, 2, box, ValueOffset() - kHeapObjectTag); | |
| 3661 break; | |
| 3662 } | |
| 3663 | |
| 3664 default: | |
| 3665 UNREACHABLE(); | |
| 3666 break; | |
| 3667 } | |
| 3668 } | |
| 3669 | |
| 3670 | |
| 3671 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { | |
| 3672 const Register box = locs()->in(0).reg(); | |
| 3673 | |
| 3674 switch (representation()) { | |
| 3675 case kUnboxedMint: { | |
| 3676 PairLocation* result = locs()->out(0).AsPairLocation(); | |
| 3677 __ SmiUntag(result->At(0).reg(), box); | |
| 3678 __ SignFill(result->At(1).reg(), result->At(0).reg()); | |
| 3679 break; | |
| 3680 } | |
| 3681 | |
| 3682 case kUnboxedDouble: { | |
| 3683 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | |
| 3684 __ SmiUntag(IP, box); | |
| 3685 __ vmovdr(DTMP, 0, IP); | |
| 3686 __ vcvtdi(result, STMP); | |
| 3687 break; | |
| 3688 } | |
| 3689 | |
| 3690 default: | |
| 3691 UNREACHABLE(); | |
| 3692 break; | |
| 3693 } | |
| 3694 } | |
| 3695 | |
| 3696 | |
| 3697 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3698 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3699 const intptr_t box_cid = BoxCid(); | |
| 3700 | |
| 3701 if (value_cid == box_cid) { | |
| 3702 EmitLoadFromBox(compiler); | |
| 3703 } else if (CanConvertSmi() && (value_cid == kSmiCid)) { | |
| 3704 EmitSmiConversion(compiler); | |
| 3622 } else { | 3705 } else { |
| 3623 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3706 const Register box = locs()->in(0).reg(); |
| 3624 ICData::kDeoptBinaryDoubleOp); | |
| 3625 const Register temp = locs()->temp(0).reg(); | 3707 const Register temp = locs()->temp(0).reg(); |
| 3626 if (value_type->is_nullable() && | 3708 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), |
| 3627 (value_type->ToNullableCid() == kDoubleCid)) { | 3709 ICData::kDeoptCheckClass); |
| 3628 __ CompareImmediate(value, reinterpret_cast<intptr_t>(Object::null())); | 3710 Label is_smi; |
| 3711 | |
| 3712 if ((value()->Type()->ToNullableCid() == box_cid) && | |
| 3713 value()->Type()->is_nullable()) { | |
| 3714 __ CompareImmediate(box, reinterpret_cast<intptr_t>(Object::null())); | |
| 3629 __ b(deopt, EQ); | 3715 __ b(deopt, EQ); |
| 3630 // It must be double now. | |
| 3631 __ LoadDFromOffset(result, value, | |
| 3632 Double::value_offset() - kHeapObjectTag); | |
| 3633 } else { | 3716 } else { |
| 3634 Label is_smi, done; | 3717 __ tst(box, Operand(kSmiTagMask)); |
| 3635 __ tst(value, Operand(kSmiTagMask)); | 3718 __ b(CanConvertSmi() ? &is_smi : deopt, EQ); |
| 3636 __ b(&is_smi, EQ); | 3719 __ CompareClassId(box, box_cid, temp); |
| 3637 __ CompareClassId(value, kDoubleCid, temp); | |
| 3638 __ b(deopt, NE); | 3720 __ b(deopt, NE); |
| 3639 __ LoadDFromOffset(result, value, | 3721 } |
| 3640 Double::value_offset() - kHeapObjectTag); | 3722 |
| 3723 EmitLoadFromBox(compiler); | |
| 3724 | |
| 3725 if (is_smi.IsLinked()) { | |
| 3726 Label done; | |
| 3641 __ b(&done); | 3727 __ b(&done); |
| 3642 __ Bind(&is_smi); | 3728 __ Bind(&is_smi); |
| 3643 __ SmiUntag(IP, value); | 3729 EmitSmiConversion(compiler); |
| 3644 __ vmovdr(DTMP, 0, IP); | |
| 3645 __ vcvtdi(result, STMP); | |
| 3646 __ Bind(&done); | 3730 __ Bind(&done); |
| 3647 } | 3731 } |
| 3648 } | 3732 } |
| 3649 } | 3733 } |
| 3650 | 3734 |
| 3651 | 3735 |
| 3652 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3736 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate, |
| 3653 bool opt) const { | 3737 bool opt) const { |
| 3738 ASSERT((from_representation() == kUnboxedInt32) || | |
| 3739 (from_representation() == kUnboxedUint32)); | |
| 3654 const intptr_t kNumInputs = 1; | 3740 const intptr_t kNumInputs = 1; |
| 3655 const intptr_t kNumTemps = 1; | 3741 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; |
| 3656 LocationSummary* summary = new(isolate) LocationSummary( | 3742 LocationSummary* summary = new(isolate) LocationSummary( |
| 3657 isolate, kNumInputs, | 3743 isolate, |
| 3658 kNumTemps, | 3744 kNumInputs, |
| 3659 LocationSummary::kCallOnSlowPath); | 3745 kNumTemps, |
| 3660 summary->set_in(0, Location::RequiresFpuRegister()); | 3746 ValueFitsSmi() ? LocationSummary::kNoCall |
| 3661 summary->set_temp(0, Location::RequiresRegister()); | 3747 : LocationSummary::kCallOnSlowPath); |
| 3748 summary->set_in(0, Location::RequiresRegister()); | |
| 3749 if (!ValueFitsSmi()) { | |
| 3750 summary->set_temp(0, Location::RequiresRegister()); | |
| 3751 } | |
| 3662 summary->set_out(0, Location::RequiresRegister()); | 3752 summary->set_out(0, Location::RequiresRegister()); |
| 3663 return summary; | 3753 return summary; |
| 3664 } | 3754 } |
| 3665 | 3755 |
| 3666 | 3756 |
| 3667 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3757 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3668 const Register out_reg = locs()->out(0).reg(); | 3758 Register value = locs()->in(0).reg(); |
| 3669 const QRegister value = locs()->in(0).fpu_reg(); | 3759 Register out = locs()->out(0).reg(); |
| 3670 const DRegister dvalue0 = EvenDRegisterOf(value); | 3760 ASSERT(value != out); |
| 3761 | |
| 3762 __ SmiTag(out, value); | |
| 3763 if (!ValueFitsSmi()) { | |
| 3764 Register temp = locs()->temp(0).reg(); | |
| 3765 Label done; | |
| 3766 if (from_representation() == kUnboxedInt32) { | |
| 3767 __ cmp(value, Operand(out, ASR, 1)); | |
| 3768 } else { | |
| 3769 ASSERT(from_representation() == kUnboxedUint32); | |
| 3770 // Note: better to test upper bits instead of comparing with | |
| 3771 // kSmiMax as kSmiMax does not fit into immediate operand. | |
| 3772 __ TestImmediate(value, 0xC0000000); | |
| 3773 } | |
| 3774 __ b(&done, EQ); | |
| 3775 BoxAllocationSlowPath::Allocate( | |
| 3776 compiler, | |
| 3777 this, | |
| 3778 compiler->mint_class(), | |
| 3779 out, | |
| 3780 temp); | |
| 3781 if (from_representation() == kUnboxedInt32) { | |
| 3782 __ Asr(temp, value, Operand(kBitsPerWord - 1)); | |
| 3783 } else { | |
| 3784 ASSERT(from_representation() == kUnboxedUint32); | |
| 3785 __ eor(temp, temp, Operand(temp)); | |
| 3786 } | |
| 3787 __ StoreToOffset(kWord, | |
| 3788 value, | |
| 3789 out, | |
| 3790 Mint::value_offset() - kHeapObjectTag); | |
| 3791 __ StoreToOffset(kWord, | |
| 3792 temp, | |
| 3793 out, | |
| 3794 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 3795 __ Bind(&done); | |
| 3796 } | |
| 3797 } | |
| 3798 | |
| 3799 | |
| 3800 LocationSummary* BoxInt64Instr::MakeLocationSummary(Isolate* isolate, | |
| 3801 bool opt) const { | |
| 3802 const intptr_t kNumInputs = 1; | |
| 3803 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; | |
| 3804 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3805 isolate, | |
| 3806 kNumInputs, | |
| 3807 kNumTemps, | |
| 3808 ValueFitsSmi() ? LocationSummary::kNoCall | |
| 3809 : LocationSummary::kCallOnSlowPath); | |
| 3810 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | |
| 3811 Location::RequiresRegister())); | |
| 3812 if (!ValueFitsSmi()) { | |
| 3813 summary->set_temp(0, Location::RequiresRegister()); | |
| 3814 } | |
| 3815 summary->set_out(0, Location::RequiresRegister()); | |
| 3816 return summary; | |
| 3817 } | |
| 3818 | |
| 3819 | |
| 3820 void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3821 if (ValueFitsSmi()) { | |
| 3822 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | |
| 3823 Register value_lo = value_pair->At(0).reg(); | |
| 3824 Register out_reg = locs()->out(0).reg(); | |
| 3825 __ SmiTag(out_reg, value_lo); | |
| 3826 return; | |
| 3827 } | |
| 3828 | |
| 3829 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | |
| 3830 Register value_lo = value_pair->At(0).reg(); | |
| 3831 Register value_hi = value_pair->At(1).reg(); | |
| 3832 Register tmp = locs()->temp(0).reg(); | |
| 3833 Register out_reg = locs()->out(0).reg(); | |
| 3834 | |
| 3835 Label done; | |
| 3836 __ SmiTag(out_reg, value_lo); | |
| 3837 __ cmp(value_lo, Operand(out_reg, ASR, kSmiTagSize)); | |
| 3838 __ cmp(value_hi, Operand(out_reg, ASR, 31), EQ); | |
| 3839 __ b(&done, EQ); | |
| 3671 | 3840 |
| 3672 BoxAllocationSlowPath::Allocate( | 3841 BoxAllocationSlowPath::Allocate( |
| 3673 compiler, | 3842 compiler, |
| 3674 this, | 3843 this, |
| 3675 compiler->float32x4_class(), | 3844 compiler->mint_class(), |
| 3676 out_reg, | 3845 out_reg, |
| 3677 locs()->temp(0).reg()); | 3846 tmp); |
| 3678 __ StoreMultipleDToOffset(dvalue0, 2, out_reg, | 3847 __ StoreToOffset(kWord, |
| 3679 Float32x4::value_offset() - kHeapObjectTag); | 3848 value_lo, |
| 3680 } | 3849 out_reg, |
| 3681 | 3850 Mint::value_offset() - kHeapObjectTag); |
| 3682 | 3851 __ StoreToOffset(kWord, |
| 3683 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3852 value_hi, |
| 3684 bool opt) const { | 3853 out_reg, |
| 3685 const intptr_t value_cid = value()->Type()->ToCid(); | 3854 Mint::value_offset() - kHeapObjectTag + kWordSize); |
| 3855 __ Bind(&done); | |
| 3856 } | |
| 3857 | |
| 3858 | |
| 3859 static void LoadInt32FromMint(FlowGraphCompiler* compiler, | |
| 3860 Register mint, | |
| 3861 Register result, | |
| 3862 Register temp, | |
| 3863 Label* deopt) { | |
| 3864 __ LoadFromOffset(kWord, | |
| 3865 result, | |
| 3866 mint, | |
| 3867 Mint::value_offset() - kHeapObjectTag); | |
| 3868 if (deopt != NULL) { | |
| 3869 __ LoadFromOffset(kWord, | |
| 3870 temp, | |
| 3871 mint, | |
| 3872 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 3873 __ cmp(temp, Operand(result, ASR, kBitsPerWord - 1)); | |
| 3874 __ b(deopt, NE); | |
| 3875 } | |
| 3876 } | |
| 3877 | |
| 3878 | |
| 3879 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate, | |
| 3880 bool opt) const { | |
|
Florian Schneider
2014/10/30 15:43:23
Indentation.
Vyacheslav Egorov (Google)
2014/10/30 17:57:39
Done.
| |
| 3881 ASSERT((representation() == kUnboxedInt32) || | |
| 3882 (representation() == kUnboxedUint32)); | |
| 3883 ASSERT((representation() != kUnboxedUint32) || is_truncating()); | |
| 3686 const intptr_t kNumInputs = 1; | 3884 const intptr_t kNumInputs = 1; |
| 3687 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; | 3885 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; |
| 3688 LocationSummary* summary = new(isolate) LocationSummary( | 3886 LocationSummary* summary = new(isolate) LocationSummary( |
| 3689 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3887 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3690 summary->set_in(0, Location::RequiresRegister()); | 3888 summary->set_in(0, Location::RequiresRegister()); |
| 3691 if (kNumTemps > 0) { | 3889 if (kNumTemps > 0) { |
| 3692 ASSERT(kNumTemps == 1); | |
| 3693 summary->set_temp(0, Location::RequiresRegister()); | 3890 summary->set_temp(0, Location::RequiresRegister()); |
| 3694 } | 3891 } |
| 3695 summary->set_out(0, Location::RequiresFpuRegister()); | 3892 summary->set_out(0, Location::RequiresRegister()); |
| 3696 return summary; | 3893 return summary; |
| 3697 } | 3894 } |
| 3698 | 3895 |
| 3699 | 3896 |
| 3700 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3897 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3701 const intptr_t value_cid = value()->Type()->ToCid(); | 3898 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3702 const Register value = locs()->in(0).reg(); | 3899 const Register value = locs()->in(0).reg(); |
| 3703 const QRegister result = locs()->out(0).fpu_reg(); | 3900 const Register out = locs()->out(0).reg(); |
| 3704 | 3901 const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; |
| 3705 if (value_cid != kFloat32x4Cid) { | 3902 Label* deopt = CanDeoptimize() ? |
| 3706 const Register temp = locs()->temp(0).reg(); | 3903 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL; |
| 3707 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | 3904 Label* out_of_range = !is_truncating() ? deopt : NULL; |
| 3708 __ tst(value, Operand(kSmiTagMask)); | 3905 ASSERT(value != out); |
| 3709 __ b(deopt, EQ); | 3906 |
| 3710 __ CompareClassId(value, kFloat32x4Cid, temp); | 3907 if (value_cid == kSmiCid) { |
| 3908 __ SmiUntag(out, value); | |
| 3909 } else if (value_cid == kMintCid) { | |
| 3910 LoadInt32FromMint(compiler, value, out, temp, out_of_range); | |
| 3911 } else { | |
| 3912 Label done; | |
| 3913 __ SmiUntag(out, value, &done); | |
| 3914 __ CompareClassId(value, kMintCid, temp); | |
| 3711 __ b(deopt, NE); | 3915 __ b(deopt, NE); |
| 3712 } | 3916 LoadInt32FromMint(compiler, value, out, temp, out_of_range); |
| 3713 | 3917 __ Bind(&done); |
| 3714 const DRegister dresult0 = EvenDRegisterOf(result); | 3918 } |
| 3715 __ LoadMultipleDFromOffset(dresult0, 2, value, | 3919 } |
| 3716 Float32x4::value_offset() - kHeapObjectTag); | 3920 |
| 3717 } | 3921 |
| 3718 | |
| 3719 | |
| 3720 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, | |
| 3721 bool opt) const { | |
| 3722 const intptr_t kNumInputs = 1; | |
| 3723 const intptr_t kNumTemps = 1; | |
| 3724 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3725 isolate, kNumInputs, | |
| 3726 kNumTemps, | |
| 3727 LocationSummary::kCallOnSlowPath); | |
| 3728 summary->set_in(0, Location::RequiresFpuRegister()); | |
| 3729 summary->set_temp(0, Location::RequiresRegister()); | |
| 3730 summary->set_out(0, Location::RequiresRegister()); | |
| 3731 return summary; | |
| 3732 } | |
| 3733 | |
| 3734 | |
| 3735 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3736 const Register out_reg = locs()->out(0).reg(); | |
| 3737 const QRegister value = locs()->in(0).fpu_reg(); | |
| 3738 const DRegister dvalue0 = EvenDRegisterOf(value); | |
| 3739 | |
| 3740 BoxAllocationSlowPath::Allocate( | |
| 3741 compiler, | |
| 3742 this, | |
| 3743 compiler->float64x2_class(), | |
| 3744 out_reg, | |
| 3745 locs()->temp(0).reg()); | |
| 3746 __ StoreMultipleDToOffset(dvalue0, 2, out_reg, | |
| 3747 Float64x2::value_offset() - kHeapObjectTag); | |
| 3748 } | |
| 3749 | |
| 3750 | |
| 3751 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, | |
| 3752 bool opt) const { | |
| 3753 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3754 const intptr_t kNumInputs = 1; | |
| 3755 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; | |
| 3756 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3757 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 3758 summary->set_in(0, Location::RequiresRegister()); | |
| 3759 if (kNumTemps > 0) { | |
| 3760 ASSERT(kNumTemps == 1); | |
| 3761 summary->set_temp(0, Location::RequiresRegister()); | |
| 3762 } | |
| 3763 summary->set_out(0, Location::RequiresFpuRegister()); | |
| 3764 return summary; | |
| 3765 } | |
| 3766 | |
| 3767 | |
| 3768 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3769 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3770 const Register value = locs()->in(0).reg(); | |
| 3771 const QRegister result = locs()->out(0).fpu_reg(); | |
| 3772 | |
| 3773 if (value_cid != kFloat64x2Cid) { | |
| 3774 const Register temp = locs()->temp(0).reg(); | |
| 3775 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), | |
| 3776 ICData::kDeoptCheckClass); | |
| 3777 __ tst(value, Operand(kSmiTagMask)); | |
| 3778 __ b(deopt, EQ); | |
| 3779 __ CompareClassId(value, kFloat64x2Cid, temp); | |
| 3780 __ b(deopt, NE); | |
| 3781 } | |
| 3782 | |
| 3783 const DRegister dresult0 = EvenDRegisterOf(result); | |
| 3784 __ LoadMultipleDFromOffset(dresult0, 2, value, | |
| 3785 Float64x2::value_offset() - kHeapObjectTag); | |
| 3786 } | |
| 3787 | |
| 3788 | |
| 3789 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate, | |
| 3790 bool opt) const { | |
| 3791 const intptr_t kNumInputs = 1; | |
| 3792 const intptr_t kNumTemps = 1; | |
| 3793 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3794 isolate, kNumInputs, | |
| 3795 kNumTemps, | |
| 3796 LocationSummary::kCallOnSlowPath); | |
| 3797 summary->set_in(0, Location::RequiresFpuRegister()); | |
| 3798 summary->set_temp(0, Location::RequiresRegister()); | |
| 3799 summary->set_out(0, Location::RequiresRegister()); | |
| 3800 return summary; | |
| 3801 } | |
| 3802 | |
| 3803 | |
| 3804 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3805 const Register out_reg = locs()->out(0).reg(); | |
| 3806 const QRegister value = locs()->in(0).fpu_reg(); | |
| 3807 const DRegister dvalue0 = EvenDRegisterOf(value); | |
| 3808 | |
| 3809 BoxAllocationSlowPath::Allocate( | |
| 3810 compiler, | |
| 3811 this, | |
| 3812 compiler->int32x4_class(), | |
| 3813 out_reg, | |
| 3814 locs()->temp(0).reg()); | |
| 3815 __ StoreMultipleDToOffset(dvalue0, 2, out_reg, | |
| 3816 Int32x4::value_offset() - kHeapObjectTag); | |
| 3817 } | |
| 3818 | |
| 3819 | |
| 3820 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate, | |
| 3821 bool opt) const { | |
| 3822 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3823 const intptr_t kNumInputs = 1; | |
| 3824 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; | |
| 3825 LocationSummary* summary = new(isolate) LocationSummary( | |
| 3826 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 3827 summary->set_in(0, Location::RequiresRegister()); | |
| 3828 if (kNumTemps > 0) { | |
| 3829 ASSERT(kNumTemps == 1); | |
| 3830 summary->set_temp(0, Location::RequiresRegister()); | |
| 3831 } | |
| 3832 summary->set_out(0, Location::RequiresFpuRegister()); | |
| 3833 return summary; | |
| 3834 } | |
| 3835 | |
| 3836 | |
| 3837 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3838 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 3839 const Register value = locs()->in(0).reg(); | |
| 3840 const QRegister result = locs()->out(0).fpu_reg(); | |
| 3841 | |
| 3842 if (value_cid != kInt32x4Cid) { | |
| 3843 const Register temp = locs()->temp(0).reg(); | |
| 3844 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), | |
| 3845 ICData::kDeoptCheckClass); | |
| 3846 __ tst(value, Operand(kSmiTagMask)); | |
| 3847 __ b(deopt, EQ); | |
| 3848 __ CompareClassId(value, kInt32x4Cid, temp); | |
| 3849 __ b(deopt, NE); | |
| 3850 } | |
| 3851 | |
| 3852 const DRegister dresult0 = EvenDRegisterOf(result); | |
| 3853 __ LoadMultipleDFromOffset(dresult0, 2, value, | |
| 3854 Int32x4::value_offset() - kHeapObjectTag); | |
| 3855 } | |
| 3856 | |
| 3857 | |
| 3858 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, | 3922 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, |
| 3859 bool opt) const { | 3923 bool opt) const { |
| 3860 const intptr_t kNumInputs = 2; | 3924 const intptr_t kNumInputs = 2; |
| 3861 const intptr_t kNumTemps = 0; | 3925 const intptr_t kNumTemps = 0; |
| 3862 LocationSummary* summary = new(isolate) LocationSummary( | 3926 LocationSummary* summary = new(isolate) LocationSummary( |
| 3863 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3927 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3864 summary->set_in(0, Location::RequiresFpuRegister()); | 3928 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3865 summary->set_in(1, Location::RequiresFpuRegister()); | 3929 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3866 summary->set_out(0, Location::RequiresFpuRegister()); | 3930 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3867 return summary; | 3931 return summary; |
| (...skipping 2119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5987 __ b(overflow, HI); | 6051 __ b(overflow, HI); |
| 5988 | 6052 |
| 5989 __ Bind(&check_lower); | 6053 __ Bind(&check_lower); |
| 5990 __ CompareImmediate(result_hi, -0x00200000); | 6054 __ CompareImmediate(result_hi, -0x00200000); |
| 5991 __ b(overflow, LT); | 6055 __ b(overflow, LT); |
| 5992 // Anything in the lower part would make the number bigger than the lower | 6056 // Anything in the lower part would make the number bigger than the lower |
| 5993 // bound, so we are done. | 6057 // bound, so we are done. |
| 5994 } | 6058 } |
| 5995 | 6059 |
| 5996 | 6060 |
| 5997 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, | |
| 5998 bool opt) const { | |
| 5999 const intptr_t kNumInputs = 1; | |
| 6000 const intptr_t kNumTemps = 1; | |
| 6001 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6002 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 6003 summary->set_in(0, Location::RequiresRegister()); | |
| 6004 summary->set_temp(0, Location::RequiresRegister()); | |
| 6005 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | |
| 6006 Location::RequiresRegister())); | |
| 6007 return summary; | |
| 6008 } | |
| 6009 | |
| 6010 | |
| 6011 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6012 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 6013 const Register value = locs()->in(0).reg(); | |
| 6014 PairLocation* result_pair = locs()->out(0).AsPairLocation(); | |
| 6015 Register result_lo = result_pair->At(0).reg(); | |
| 6016 Register result_hi = result_pair->At(1).reg(); | |
| 6017 ASSERT(value != result_lo); | |
| 6018 ASSERT(value != result_hi); | |
| 6019 | |
| 6020 __ Comment("UnboxIntegerInstr"); | |
| 6021 if (value_cid == kMintCid) { | |
| 6022 // Load low word. | |
| 6023 __ LoadFromOffset(kWord, | |
| 6024 result_lo, | |
| 6025 value, | |
| 6026 Mint::value_offset() - kHeapObjectTag); | |
| 6027 // Load high word. | |
| 6028 __ LoadFromOffset(kWord, | |
| 6029 result_hi, | |
| 6030 value, | |
| 6031 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 6032 } else if (value_cid == kSmiCid) { | |
| 6033 // Load Smi into result_lo. | |
| 6034 __ mov(result_lo, Operand(value)); | |
| 6035 // Untag. | |
| 6036 __ SmiUntag(result_lo); | |
| 6037 __ SignFill(result_hi, result_lo); | |
| 6038 } else { | |
| 6039 const Register temp = locs()->temp(0).reg(); | |
| 6040 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), | |
| 6041 ICData::kDeoptUnboxInteger); | |
| 6042 Label is_smi, done; | |
| 6043 __ tst(value, Operand(kSmiTagMask)); | |
| 6044 __ b(&is_smi, EQ); | |
| 6045 __ CompareClassId(value, kMintCid, temp); | |
| 6046 __ b(deopt, NE); | |
| 6047 | |
| 6048 // It's a Mint. | |
| 6049 // Load low word. | |
| 6050 __ LoadFromOffset(kWord, | |
| 6051 result_lo, | |
| 6052 value, | |
| 6053 Mint::value_offset() - kHeapObjectTag); | |
| 6054 // Load high word. | |
| 6055 __ LoadFromOffset(kWord, | |
| 6056 result_hi, | |
| 6057 value, | |
| 6058 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 6059 __ b(&done); | |
| 6060 | |
| 6061 // It's a Smi. | |
| 6062 __ Bind(&is_smi); | |
| 6063 // Load Smi into result_lo. | |
| 6064 __ mov(result_lo, Operand(value)); | |
| 6065 // Untag. | |
| 6066 __ SmiUntag(result_lo); | |
| 6067 // Sign extend result_lo into result_hi. | |
| 6068 __ SignFill(result_hi, result_lo); | |
| 6069 __ Bind(&done); | |
| 6070 } | |
| 6071 } | |
| 6072 | |
| 6073 | |
| 6074 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, | |
| 6075 bool opt) const { | |
| 6076 const intptr_t kNumInputs = 1; | |
| 6077 const intptr_t kNumTemps = is_smi() ? 0 : 1; | |
| 6078 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6079 isolate, kNumInputs, | |
| 6080 kNumTemps, | |
| 6081 is_smi() | |
| 6082 ? LocationSummary::kNoCall | |
| 6083 : LocationSummary::kCallOnSlowPath); | |
| 6084 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | |
| 6085 Location::RequiresRegister())); | |
| 6086 if (!is_smi()) { | |
| 6087 summary->set_temp(0, Location::RequiresRegister()); | |
| 6088 } | |
| 6089 summary->set_out(0, Location::RequiresRegister()); | |
| 6090 return summary; | |
| 6091 } | |
| 6092 | |
| 6093 | |
| 6094 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6095 if (is_smi()) { | |
| 6096 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | |
| 6097 Register value_lo = value_pair->At(0).reg(); | |
| 6098 Register out_reg = locs()->out(0).reg(); | |
| 6099 __ mov(out_reg, Operand(value_lo)); | |
| 6100 __ SmiTag(out_reg); | |
| 6101 return; | |
| 6102 } | |
| 6103 | |
| 6104 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | |
| 6105 Register value_lo = value_pair->At(0).reg(); | |
| 6106 Register value_hi = value_pair->At(1).reg(); | |
| 6107 Register tmp = locs()->temp(0).reg(); | |
| 6108 Register out_reg = locs()->out(0).reg(); | |
| 6109 | |
| 6110 // Unboxed operations produce smis or mint-sized values. | |
| 6111 // Check if value fits into a smi. | |
| 6112 __ Comment("BoxIntegerInstr"); | |
| 6113 Label not_smi, done, maybe_pos_smi, maybe_neg_smi, is_smi; | |
| 6114 // Check high word. | |
| 6115 __ CompareImmediate(value_hi, 0); | |
| 6116 __ b(&maybe_pos_smi, EQ); | |
| 6117 | |
| 6118 __ CompareImmediate(value_hi, -1); | |
| 6119 __ b(&maybe_neg_smi, EQ); | |
| 6120 __ b(¬_smi); | |
| 6121 | |
| 6122 __ Bind(&maybe_pos_smi); | |
| 6123 __ CompareImmediate(value_lo, kSmiMax); | |
| 6124 __ b(&is_smi, LS); // unsigned lower or same. | |
| 6125 __ b(¬_smi); | |
| 6126 | |
| 6127 __ Bind(&maybe_neg_smi); | |
| 6128 __ CompareImmediate(value_lo, 0); | |
| 6129 __ b(¬_smi, GE); | |
| 6130 __ CompareImmediate(value_lo, kSmiMin); | |
| 6131 __ b(¬_smi, LT); | |
| 6132 | |
| 6133 // lo is a Smi. Tag it and return. | |
| 6134 __ Bind(&is_smi); | |
| 6135 __ mov(out_reg, Operand(value_lo)); | |
| 6136 __ SmiTag(out_reg); | |
| 6137 __ b(&done); | |
| 6138 | |
| 6139 // Not a smi. Box it. | |
| 6140 __ Bind(¬_smi); | |
| 6141 BoxAllocationSlowPath::Allocate( | |
| 6142 compiler, | |
| 6143 this, | |
| 6144 compiler->mint_class(), | |
| 6145 out_reg, | |
| 6146 tmp); | |
| 6147 __ StoreToOffset(kWord, | |
| 6148 value_lo, | |
| 6149 out_reg, | |
| 6150 Mint::value_offset() - kHeapObjectTag); | |
| 6151 __ StoreToOffset(kWord, | |
| 6152 value_hi, | |
| 6153 out_reg, | |
| 6154 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 6155 __ Bind(&done); | |
| 6156 } | |
| 6157 | |
| 6158 | |
| 6159 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | 6061 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
| 6160 bool opt) const { | 6062 bool opt) const { |
| 6161 const intptr_t kNumInputs = 2; | 6063 const intptr_t kNumInputs = 2; |
| 6162 const intptr_t kNumTemps = 0; | 6064 const intptr_t kNumTemps = 0; |
| 6163 LocationSummary* summary = new(isolate) LocationSummary( | 6065 LocationSummary* summary = new(isolate) LocationSummary( |
| 6164 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6066 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6165 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 6067 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 6166 Location::RequiresRegister())); | 6068 Location::RequiresRegister())); |
| 6167 summary->set_in(1, Location::Pair(Location::RequiresRegister(), | 6069 summary->set_in(1, Location::Pair(Location::RequiresRegister(), |
| 6168 Location::RequiresRegister())); | 6070 Location::RequiresRegister())); |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6570 Register left = locs()->in(0).reg(); | 6472 Register left = locs()->in(0).reg(); |
| 6571 Register out = locs()->out(0).reg(); | 6473 Register out = locs()->out(0).reg(); |
| 6572 ASSERT(left != out); | 6474 ASSERT(left != out); |
| 6573 | 6475 |
| 6574 ASSERT(op_kind() == Token::kBIT_NOT); | 6476 ASSERT(op_kind() == Token::kBIT_NOT); |
| 6575 | 6477 |
| 6576 __ mvn(out, Operand(left)); | 6478 __ mvn(out, Operand(left)); |
| 6577 } | 6479 } |
| 6578 | 6480 |
| 6579 | 6481 |
| 6580 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate, | |
| 6581 bool opt) const { | |
| 6582 ASSERT((from_representation() == kUnboxedInt32) || | |
| 6583 (from_representation() == kUnboxedUint32)); | |
| 6584 const intptr_t kNumInputs = 1; | |
| 6585 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; | |
| 6586 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6587 isolate, | |
| 6588 kNumInputs, | |
| 6589 kNumTemps, | |
| 6590 ValueFitsSmi() ? LocationSummary::kNoCall | |
| 6591 : LocationSummary::kCallOnSlowPath); | |
| 6592 summary->set_in(0, Location::RequiresRegister()); | |
| 6593 if (!ValueFitsSmi()) { | |
| 6594 summary->set_temp(0, Location::RequiresRegister()); | |
| 6595 } | |
| 6596 summary->set_out(0, Location::RequiresRegister()); | |
| 6597 return summary; | |
| 6598 } | |
| 6599 | |
| 6600 | |
| 6601 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6602 Register value = locs()->in(0).reg(); | |
| 6603 Register out = locs()->out(0).reg(); | |
| 6604 ASSERT(value != out); | |
| 6605 | |
| 6606 __ SmiTag(out, value); | |
| 6607 if (!ValueFitsSmi()) { | |
| 6608 Register temp = locs()->temp(0).reg(); | |
| 6609 Label done; | |
| 6610 if (from_representation() == kUnboxedInt32) { | |
| 6611 __ cmp(value, Operand(out, ASR, 1)); | |
| 6612 } else { | |
| 6613 ASSERT(from_representation() == kUnboxedUint32); | |
| 6614 // Note: better to test upper bits instead of comparing with | |
| 6615 // kSmiMax as kSmiMax does not fit into immediate operand. | |
| 6616 __ TestImmediate(value, 0xC0000000); | |
| 6617 } | |
| 6618 __ b(&done, EQ); | |
| 6619 BoxAllocationSlowPath::Allocate( | |
| 6620 compiler, | |
| 6621 this, | |
| 6622 compiler->mint_class(), | |
| 6623 out, | |
| 6624 temp); | |
| 6625 if (from_representation() == kUnboxedInt32) { | |
| 6626 __ Asr(temp, value, Operand(kBitsPerWord - 1)); | |
| 6627 } else { | |
| 6628 ASSERT(from_representation() == kUnboxedUint32); | |
| 6629 __ eor(temp, temp, Operand(temp)); | |
| 6630 } | |
| 6631 __ StoreToOffset(kWord, | |
| 6632 value, | |
| 6633 out, | |
| 6634 Mint::value_offset() - kHeapObjectTag); | |
| 6635 __ StoreToOffset(kWord, | |
| 6636 temp, | |
| 6637 out, | |
| 6638 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 6639 __ Bind(&done); | |
| 6640 } | |
| 6641 } | |
| 6642 | |
| 6643 | |
| 6644 static void LoadInt32FromMint(FlowGraphCompiler* compiler, | |
| 6645 Register mint, | |
| 6646 Register result, | |
| 6647 Register temp, | |
| 6648 Label* deopt) { | |
| 6649 __ LoadFromOffset(kWord, | |
| 6650 result, | |
| 6651 mint, | |
| 6652 Mint::value_offset() - kHeapObjectTag); | |
| 6653 if (deopt != NULL) { | |
| 6654 __ LoadFromOffset(kWord, | |
| 6655 temp, | |
| 6656 mint, | |
| 6657 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 6658 __ cmp(temp, Operand(result, ASR, kBitsPerWord - 1)); | |
| 6659 __ b(deopt, NE); | |
| 6660 } | |
| 6661 } | |
| 6662 | |
| 6663 | |
| 6664 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, | |
| 6665 bool opt) const { | |
| 6666 ASSERT((representation() == kUnboxedInt32) || | |
| 6667 (representation() == kUnboxedUint32)); | |
| 6668 ASSERT((representation() != kUnboxedUint32) || is_truncating()); | |
| 6669 const intptr_t kNumInputs = 1; | |
| 6670 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; | |
| 6671 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6672 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 6673 summary->set_in(0, Location::RequiresRegister()); | |
| 6674 if (kNumTemps > 0) { | |
| 6675 summary->set_temp(0, Location::RequiresRegister()); | |
| 6676 } | |
| 6677 summary->set_out(0, Location::RequiresRegister()); | |
| 6678 return summary; | |
| 6679 } | |
| 6680 | |
| 6681 | |
| 6682 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6683 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 6684 const Register value = locs()->in(0).reg(); | |
| 6685 const Register out = locs()->out(0).reg(); | |
| 6686 const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; | |
| 6687 Label* deopt = CanDeoptimize() ? | |
| 6688 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL; | |
| 6689 Label* out_of_range = !is_truncating() ? deopt : NULL; | |
| 6690 ASSERT(value != out); | |
| 6691 | |
| 6692 if (value_cid == kSmiCid) { | |
| 6693 __ SmiUntag(out, value); | |
| 6694 } else if (value_cid == kMintCid) { | |
| 6695 LoadInt32FromMint(compiler, value, out, temp, out_of_range); | |
| 6696 } else { | |
| 6697 Label done; | |
| 6698 __ SmiUntag(out, value, &done); | |
| 6699 __ CompareClassId(value, kMintCid, temp); | |
| 6700 __ b(deopt, NE); | |
| 6701 LoadInt32FromMint(compiler, value, out, temp, out_of_range); | |
| 6702 __ Bind(&done); | |
| 6703 } | |
| 6704 } | |
| 6705 | |
| 6706 | |
| 6707 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 6482 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
| 6708 bool opt) const { | 6483 bool opt) const { |
| 6709 const intptr_t kNumInputs = 1; | 6484 const intptr_t kNumInputs = 1; |
| 6710 const intptr_t kNumTemps = 0; | 6485 const intptr_t kNumTemps = 0; |
| 6711 LocationSummary* summary = new(isolate) LocationSummary( | 6486 LocationSummary* summary = new(isolate) LocationSummary( |
| 6712 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6487 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6713 if (from() == kUnboxedMint) { | 6488 if (from() == kUnboxedMint) { |
| 6714 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); | 6489 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); |
| 6715 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 6490 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 6716 Location::RequiresRegister())); | 6491 Location::RequiresRegister())); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6987 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 6762 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 6988 #if defined(DEBUG) | 6763 #if defined(DEBUG) |
| 6989 __ LoadImmediate(R4, kInvalidObjectPointer); | 6764 __ LoadImmediate(R4, kInvalidObjectPointer); |
| 6990 __ LoadImmediate(R5, kInvalidObjectPointer); | 6765 __ LoadImmediate(R5, kInvalidObjectPointer); |
| 6991 #endif | 6766 #endif |
| 6992 } | 6767 } |
| 6993 | 6768 |
| 6994 } // namespace dart | 6769 } // namespace dart |
| 6995 | 6770 |
| 6996 #endif // defined TARGET_ARCH_ARM | 6771 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |