| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 3255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3266 (CanConvertSmi() && (value()->Type()->ToCid() == kSmiCid)); | 3266 (CanConvertSmi() && (value()->Type()->ToCid() == kSmiCid)); |
| 3267 | 3267 |
| 3268 const intptr_t kNumInputs = 1; | 3268 const intptr_t kNumInputs = 1; |
| 3269 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 3269 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 3270 LocationSummary* summary = new (zone) | 3270 LocationSummary* summary = new (zone) |
| 3271 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3271 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3272 summary->set_in(0, Location::RequiresRegister()); | 3272 summary->set_in(0, Location::RequiresRegister()); |
| 3273 if (needs_temp) { | 3273 if (needs_temp) { |
| 3274 summary->set_temp(0, Location::RequiresRegister()); | 3274 summary->set_temp(0, Location::RequiresRegister()); |
| 3275 } | 3275 } |
| 3276 if (representation() == kUnboxedMint) { | 3276 if (representation() == kUnboxedInt64) { |
| 3277 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), | 3277 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
| 3278 Location::RegisterLocation(EDX))); | 3278 Location::RegisterLocation(EDX))); |
| 3279 } else { | 3279 } else { |
| 3280 summary->set_out(0, Location::RequiresFpuRegister()); | 3280 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3281 } | 3281 } |
| 3282 return summary; | 3282 return summary; |
| 3283 } | 3283 } |
| 3284 | 3284 |
| 3285 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { | 3285 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { |
| 3286 const Register box = locs()->in(0).reg(); | 3286 const Register box = locs()->in(0).reg(); |
| 3287 | 3287 |
| 3288 switch (representation()) { | 3288 switch (representation()) { |
| 3289 case kUnboxedMint: { | 3289 case kUnboxedInt64: { |
| 3290 PairLocation* result = locs()->out(0).AsPairLocation(); | 3290 PairLocation* result = locs()->out(0).AsPairLocation(); |
| 3291 __ movl(result->At(0).reg(), FieldAddress(box, ValueOffset())); | 3291 __ movl(result->At(0).reg(), FieldAddress(box, ValueOffset())); |
| 3292 __ movl(result->At(1).reg(), | 3292 __ movl(result->At(1).reg(), |
| 3293 FieldAddress(box, ValueOffset() + kWordSize)); | 3293 FieldAddress(box, ValueOffset() + kWordSize)); |
| 3294 break; | 3294 break; |
| 3295 } | 3295 } |
| 3296 | 3296 |
| 3297 case kUnboxedDouble: { | 3297 case kUnboxedDouble: { |
| 3298 const FpuRegister result = locs()->out(0).fpu_reg(); | 3298 const FpuRegister result = locs()->out(0).fpu_reg(); |
| 3299 __ movsd(result, FieldAddress(box, ValueOffset())); | 3299 __ movsd(result, FieldAddress(box, ValueOffset())); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3311 default: | 3311 default: |
| 3312 UNREACHABLE(); | 3312 UNREACHABLE(); |
| 3313 break; | 3313 break; |
| 3314 } | 3314 } |
| 3315 } | 3315 } |
| 3316 | 3316 |
| 3317 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { | 3317 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { |
| 3318 const Register box = locs()->in(0).reg(); | 3318 const Register box = locs()->in(0).reg(); |
| 3319 | 3319 |
| 3320 switch (representation()) { | 3320 switch (representation()) { |
| 3321 case kUnboxedMint: { | 3321 case kUnboxedInt64: { |
| 3322 PairLocation* result = locs()->out(0).AsPairLocation(); | 3322 PairLocation* result = locs()->out(0).AsPairLocation(); |
| 3323 ASSERT(result->At(0).reg() == EAX); | 3323 ASSERT(result->At(0).reg() == EAX); |
| 3324 ASSERT(result->At(1).reg() == EDX); | 3324 ASSERT(result->At(1).reg() == EDX); |
| 3325 __ movl(EAX, box); | 3325 __ movl(EAX, box); |
| 3326 __ SmiUntag(EAX); | 3326 __ SmiUntag(EAX); |
| 3327 __ cdq(); | 3327 __ cdq(); |
| 3328 break; | 3328 break; |
| 3329 } | 3329 } |
| 3330 | 3330 |
| 3331 case kUnboxedDouble: { | 3331 case kUnboxedDouble: { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3597 summary->set_in(0, Location::RequiresRegister()); | 3597 summary->set_in(0, Location::RequiresRegister()); |
| 3598 // The smi index is either untagged (element size == 1), or it is left smi | 3598 // The smi index is either untagged (element size == 1), or it is left smi |
| 3599 // tagged (for all element sizes > 1). | 3599 // tagged (for all element sizes > 1). |
| 3600 summary->set_in(1, (index_scale() == 1) ? Location::WritableRegister() | 3600 summary->set_in(1, (index_scale() == 1) ? Location::WritableRegister() |
| 3601 : Location::RequiresRegister()); | 3601 : Location::RequiresRegister()); |
| 3602 if (might_box) { | 3602 if (might_box) { |
| 3603 summary->set_temp(0, Location::RequiresRegister()); | 3603 summary->set_temp(0, Location::RequiresRegister()); |
| 3604 summary->set_temp(1, Location::RequiresRegister()); | 3604 summary->set_temp(1, Location::RequiresRegister()); |
| 3605 } | 3605 } |
| 3606 | 3606 |
| 3607 if (representation() == kUnboxedMint) { | 3607 if (representation() == kUnboxedInt64) { |
| 3608 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 3608 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 3609 Location::RequiresRegister())); | 3609 Location::RequiresRegister())); |
| 3610 } else { | 3610 } else { |
| 3611 ASSERT(representation() == kTagged); | 3611 ASSERT(representation() == kTagged); |
| 3612 summary->set_out(0, Location::RequiresRegister()); | 3612 summary->set_out(0, Location::RequiresRegister()); |
| 3613 } | 3613 } |
| 3614 | 3614 |
| 3615 return summary; | 3615 return summary; |
| 3616 } | 3616 } |
| 3617 | 3617 |
| 3618 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3618 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3619 // The string register points to the backing store for external strings. | 3619 // The string register points to the backing store for external strings. |
| 3620 const Register str = locs()->in(0).reg(); | 3620 const Register str = locs()->in(0).reg(); |
| 3621 const Location index = locs()->in(1); | 3621 const Location index = locs()->in(1); |
| 3622 | 3622 |
| 3623 Address element_address = Assembler::ElementAddressForRegIndex( | 3623 Address element_address = Assembler::ElementAddressForRegIndex( |
| 3624 IsExternal(), class_id(), index_scale(), str, index.reg()); | 3624 IsExternal(), class_id(), index_scale(), str, index.reg()); |
| 3625 | 3625 |
| 3626 if ((index_scale() == 1)) { | 3626 if ((index_scale() == 1)) { |
| 3627 __ SmiUntag(index.reg()); | 3627 __ SmiUntag(index.reg()); |
| 3628 } | 3628 } |
| 3629 | 3629 |
| 3630 if (representation() == kUnboxedMint) { | 3630 if (representation() == kUnboxedInt64) { |
| 3631 ASSERT(compiler->is_optimizing()); | 3631 ASSERT(compiler->is_optimizing()); |
| 3632 ASSERT(locs()->out(0).IsPairLocation()); | 3632 ASSERT(locs()->out(0).IsPairLocation()); |
| 3633 PairLocation* result_pair = locs()->out(0).AsPairLocation(); | 3633 PairLocation* result_pair = locs()->out(0).AsPairLocation(); |
| 3634 Register result1 = result_pair->At(0).reg(); | 3634 Register result1 = result_pair->At(0).reg(); |
| 3635 Register result2 = result_pair->At(1).reg(); | 3635 Register result2 = result_pair->At(1).reg(); |
| 3636 | 3636 |
| 3637 switch (class_id()) { | 3637 switch (class_id()) { |
| 3638 case kOneByteStringCid: | 3638 case kOneByteStringCid: |
| 3639 case kExternalOneByteStringCid: | 3639 case kExternalOneByteStringCid: |
| 3640 ASSERT(element_count() == 4); | 3640 ASSERT(element_count() == 4); |
| (...skipping 2048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5689 Register index = index_loc.reg(); | 5689 Register index = index_loc.reg(); |
| 5690 Register length = length_loc.reg(); | 5690 Register length = length_loc.reg(); |
| 5691 if (index_cid != kSmiCid) { | 5691 if (index_cid != kSmiCid) { |
| 5692 __ BranchIfNotSmi(index, deopt); | 5692 __ BranchIfNotSmi(index, deopt); |
| 5693 } | 5693 } |
| 5694 __ cmpl(length, index); | 5694 __ cmpl(length, index); |
| 5695 __ j(BELOW_EQUAL, deopt); | 5695 __ j(BELOW_EQUAL, deopt); |
| 5696 } | 5696 } |
| 5697 } | 5697 } |
| 5698 | 5698 |
| 5699 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, | 5699 LocationSummary* BinaryInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 5700 bool opt) const { | 5700 bool opt) const { |
| 5701 const intptr_t kNumInputs = 2; | 5701 const intptr_t kNumInputs = 2; |
| 5702 switch (op_kind()) { | 5702 switch (op_kind()) { |
| 5703 case Token::kBIT_AND: | 5703 case Token::kBIT_AND: |
| 5704 case Token::kBIT_OR: | 5704 case Token::kBIT_OR: |
| 5705 case Token::kBIT_XOR: | 5705 case Token::kBIT_XOR: |
| 5706 case Token::kADD: | 5706 case Token::kADD: |
| 5707 case Token::kSUB: | 5707 case Token::kSUB: |
| 5708 case Token::kMUL: { | 5708 case Token::kMUL: { |
| 5709 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; | 5709 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; |
| 5710 LocationSummary* summary = new (zone) LocationSummary( | 5710 LocationSummary* summary = new (zone) LocationSummary( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5721 summary->set_temp(0, Location::RequiresRegister()); | 5721 summary->set_temp(0, Location::RequiresRegister()); |
| 5722 } | 5722 } |
| 5723 return summary; | 5723 return summary; |
| 5724 } | 5724 } |
| 5725 default: | 5725 default: |
| 5726 UNREACHABLE(); | 5726 UNREACHABLE(); |
| 5727 return NULL; | 5727 return NULL; |
| 5728 } | 5728 } |
| 5729 } | 5729 } |
| 5730 | 5730 |
| 5731 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5731 void BinaryInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5732 PairLocation* left_pair = locs()->in(0).AsPairLocation(); | 5732 PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
| 5733 Register left_lo = left_pair->At(0).reg(); | 5733 Register left_lo = left_pair->At(0).reg(); |
| 5734 Register left_hi = left_pair->At(1).reg(); | 5734 Register left_hi = left_pair->At(1).reg(); |
| 5735 PairLocation* right_pair = locs()->in(1).AsPairLocation(); | 5735 PairLocation* right_pair = locs()->in(1).AsPairLocation(); |
| 5736 Register right_lo = right_pair->At(0).reg(); | 5736 Register right_lo = right_pair->At(0).reg(); |
| 5737 Register right_hi = right_pair->At(1).reg(); | 5737 Register right_hi = right_pair->At(1).reg(); |
| 5738 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 5738 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 5739 Register out_lo = out_pair->At(0).reg(); | 5739 Register out_lo = out_pair->At(0).reg(); |
| 5740 Register out_hi = out_pair->At(1).reg(); | 5740 Register out_hi = out_pair->At(1).reg(); |
| 5741 ASSERT(out_lo == left_lo); | 5741 ASSERT(out_lo == left_lo); |
| 5742 ASSERT(out_hi == left_hi); | 5742 ASSERT(out_hi == left_hi); |
| 5743 | 5743 |
| 5744 Label* deopt = NULL; | 5744 Label* deopt = NULL; |
| 5745 if (CanDeoptimize()) { | 5745 if (CanDeoptimize()) { |
| 5746 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 5746 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 5747 } | 5747 } |
| 5748 switch (op_kind()) { | 5748 switch (op_kind()) { |
| 5749 case Token::kBIT_AND: | 5749 case Token::kBIT_AND: |
| 5750 __ andl(left_lo, right_lo); | 5750 __ andl(left_lo, right_lo); |
| 5751 __ andl(left_hi, right_hi); | 5751 __ andl(left_hi, right_hi); |
| 5752 break; | 5752 break; |
| 5753 case Token::kBIT_OR: | 5753 case Token::kBIT_OR: |
| 5754 __ orl(left_lo, right_lo); | 5754 __ orl(left_lo, right_lo); |
| 5755 __ orl(left_hi, right_hi); | 5755 __ orl(left_hi, right_hi); |
| 5756 break; | 5756 break; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5790 __ imull(right_lo); // Result in EDX:EAX. | 5790 __ imull(right_lo); // Result in EDX:EAX. |
| 5791 ASSERT(out_lo == EAX); | 5791 ASSERT(out_lo == EAX); |
| 5792 ASSERT(out_hi == EDX); | 5792 ASSERT(out_hi == EDX); |
| 5793 break; | 5793 break; |
| 5794 } | 5794 } |
| 5795 default: | 5795 default: |
| 5796 UNREACHABLE(); | 5796 UNREACHABLE(); |
| 5797 } | 5797 } |
| 5798 } | 5798 } |
| 5799 | 5799 |
| 5800 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone, | 5800 LocationSummary* ShiftInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 5801 bool opt) const { | 5801 bool opt) const { |
| 5802 const intptr_t kNumInputs = 2; | 5802 const intptr_t kNumInputs = 2; |
| 5803 const intptr_t kNumTemps = | 5803 const intptr_t kNumTemps = |
| 5804 (op_kind() == Token::kSHL) && CanDeoptimize() ? 2 : 0; | 5804 (op_kind() == Token::kSHL) && CanDeoptimize() ? 2 : 0; |
| 5805 LocationSummary* summary = new (zone) | 5805 LocationSummary* summary = new (zone) |
| 5806 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5806 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5807 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 5807 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 5808 Location::RequiresRegister())); | 5808 Location::RequiresRegister())); |
| 5809 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); | 5809 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); |
| 5810 if ((op_kind() == Token::kSHL) && CanDeoptimize()) { | 5810 if ((op_kind() == Token::kSHL) && CanDeoptimize()) { |
| 5811 summary->set_temp(0, Location::RequiresRegister()); | 5811 summary->set_temp(0, Location::RequiresRegister()); |
| 5812 summary->set_temp(1, Location::RequiresRegister()); | 5812 summary->set_temp(1, Location::RequiresRegister()); |
| 5813 } | 5813 } |
| 5814 summary->set_out(0, Location::SameAsFirstInput()); | 5814 summary->set_out(0, Location::SameAsFirstInput()); |
| 5815 return summary; | 5815 return summary; |
| 5816 } | 5816 } |
| 5817 | 5817 |
| 5818 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5818 void ShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5819 PairLocation* left_pair = locs()->in(0).AsPairLocation(); | 5819 PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
| 5820 Register left_lo = left_pair->At(0).reg(); | 5820 Register left_lo = left_pair->At(0).reg(); |
| 5821 Register left_hi = left_pair->At(1).reg(); | 5821 Register left_hi = left_pair->At(1).reg(); |
| 5822 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 5822 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 5823 Register out_lo = out_pair->At(0).reg(); | 5823 Register out_lo = out_pair->At(0).reg(); |
| 5824 Register out_hi = out_pair->At(1).reg(); | 5824 Register out_hi = out_pair->At(1).reg(); |
| 5825 ASSERT(out_lo == left_lo); | 5825 ASSERT(out_lo == left_lo); |
| 5826 ASSERT(out_hi == left_hi); | 5826 ASSERT(out_hi == left_hi); |
| 5827 | 5827 |
| 5828 Label* deopt = NULL; | 5828 Label* deopt = NULL; |
| 5829 if (CanDeoptimize()) { | 5829 if (CanDeoptimize()) { |
| 5830 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 5830 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 5831 } | 5831 } |
| 5832 if (locs()->in(1).IsConstant()) { | 5832 if (locs()->in(1).IsConstant()) { |
| 5833 // Code for a constant shift amount. | 5833 // Code for a constant shift amount. |
| 5834 ASSERT(locs()->in(1).constant().IsSmi()); | 5834 ASSERT(locs()->in(1).constant().IsSmi()); |
| 5835 const int32_t shift = Smi::Cast(locs()->in(1).constant()).Value(); | 5835 const int32_t shift = Smi::Cast(locs()->in(1).constant()).Value(); |
| 5836 ASSERT(shift >= 0); | 5836 ASSERT(shift >= 0); |
| 5837 switch (op_kind()) { | 5837 switch (op_kind()) { |
| 5838 case Token::kSHR: { | 5838 case Token::kSHR: { |
| 5839 if (shift > 31) { | 5839 if (shift > 31) { |
| 5840 __ movl(left_lo, left_hi); // Shift by 32. | 5840 __ movl(left_lo, left_hi); // Shift by 32. |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5979 } | 5979 } |
| 5980 break; | 5980 break; |
| 5981 } | 5981 } |
| 5982 default: | 5982 default: |
| 5983 UNREACHABLE(); | 5983 UNREACHABLE(); |
| 5984 } | 5984 } |
| 5985 __ Bind(&done); | 5985 __ Bind(&done); |
| 5986 } | 5986 } |
| 5987 } | 5987 } |
| 5988 | 5988 |
| 5989 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone, | 5989 LocationSummary* UnaryInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 5990 bool opt) const { | 5990 bool opt) const { |
| 5991 const intptr_t kNumInputs = 1; | 5991 const intptr_t kNumInputs = 1; |
| 5992 const intptr_t kNumTemps = 0; | 5992 const intptr_t kNumTemps = 0; |
| 5993 LocationSummary* summary = new (zone) | 5993 LocationSummary* summary = new (zone) |
| 5994 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5994 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5995 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 5995 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 5996 Location::RequiresRegister())); | 5996 Location::RequiresRegister())); |
| 5997 summary->set_out(0, Location::SameAsFirstInput()); | 5997 summary->set_out(0, Location::SameAsFirstInput()); |
| 5998 return summary; | 5998 return summary; |
| 5999 } | 5999 } |
| 6000 | 6000 |
| 6001 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6001 void UnaryInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6002 ASSERT(op_kind() == Token::kBIT_NOT); | 6002 ASSERT(op_kind() == Token::kBIT_NOT); |
| 6003 PairLocation* left_pair = locs()->in(0).AsPairLocation(); | 6003 PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
| 6004 Register left_lo = left_pair->At(0).reg(); | 6004 Register left_lo = left_pair->At(0).reg(); |
| 6005 Register left_hi = left_pair->At(1).reg(); | 6005 Register left_hi = left_pair->At(1).reg(); |
| 6006 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6006 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6007 Register out_lo = out_pair->At(0).reg(); | 6007 Register out_lo = out_pair->At(0).reg(); |
| 6008 Register out_hi = out_pair->At(1).reg(); | 6008 Register out_hi = out_pair->At(1).reg(); |
| 6009 ASSERT(out_lo == left_lo); | 6009 ASSERT(out_lo == left_lo); |
| 6010 ASSERT(out_hi == left_hi); | 6010 ASSERT(out_hi == left_hi); |
| 6011 __ notl(left_lo); | 6011 __ notl(left_lo); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 6036 return summary; | 6036 return summary; |
| 6037 } | 6037 } |
| 6038 | 6038 |
| 6039 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6039 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6040 const intptr_t kShifterLimit = 31; | 6040 const intptr_t kShifterLimit = 31; |
| 6041 | 6041 |
| 6042 Register left = locs()->in(0).reg(); | 6042 Register left = locs()->in(0).reg(); |
| 6043 Register out = locs()->out(0).reg(); | 6043 Register out = locs()->out(0).reg(); |
| 6044 ASSERT(left == out); | 6044 ASSERT(left == out); |
| 6045 | 6045 |
| 6046 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 6046 Label* deopt = |
| 6047 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 6047 | 6048 |
| 6048 if (locs()->in(1).IsConstant()) { | 6049 if (locs()->in(1).IsConstant()) { |
| 6049 // Shifter is constant. | 6050 // Shifter is constant. |
| 6050 | 6051 |
| 6051 const Object& constant = locs()->in(1).constant(); | 6052 const Object& constant = locs()->in(1).constant(); |
| 6052 ASSERT(constant.IsSmi()); | 6053 ASSERT(constant.IsSmi()); |
| 6053 const intptr_t shift_value = Smi::Cast(constant).Value(); | 6054 const intptr_t shift_value = Smi::Cast(constant).Value(); |
| 6054 | 6055 |
| 6055 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). | 6056 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). |
| 6056 switch (op_kind()) { | 6057 switch (op_kind()) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6128 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone, | 6129 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone, |
| 6129 bool opt) const { | 6130 bool opt) const { |
| 6130 const intptr_t kNumInputs = 1; | 6131 const intptr_t kNumInputs = 1; |
| 6131 const intptr_t kNumTemps = 0; | 6132 const intptr_t kNumTemps = 0; |
| 6132 LocationSummary* summary = new (zone) | 6133 LocationSummary* summary = new (zone) |
| 6133 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6134 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6134 if ((from() == kUnboxedInt32 || from() == kUnboxedUint32) && | 6135 if ((from() == kUnboxedInt32 || from() == kUnboxedUint32) && |
| 6135 (to() == kUnboxedInt32 || to() == kUnboxedUint32)) { | 6136 (to() == kUnboxedInt32 || to() == kUnboxedUint32)) { |
| 6136 summary->set_in(0, Location::RequiresRegister()); | 6137 summary->set_in(0, Location::RequiresRegister()); |
| 6137 summary->set_out(0, Location::SameAsFirstInput()); | 6138 summary->set_out(0, Location::SameAsFirstInput()); |
| 6138 } else if (from() == kUnboxedMint) { | 6139 } else if (from() == kUnboxedInt64) { |
| 6139 summary->set_in( | 6140 summary->set_in( |
| 6140 0, Location::Pair(CanDeoptimize() ? Location::WritableRegister() | 6141 0, Location::Pair(CanDeoptimize() ? Location::WritableRegister() |
| 6141 : Location::RequiresRegister(), | 6142 : Location::RequiresRegister(), |
| 6142 Location::RequiresRegister())); | 6143 Location::RequiresRegister())); |
| 6143 summary->set_out(0, Location::RequiresRegister()); | 6144 summary->set_out(0, Location::RequiresRegister()); |
| 6144 } else if (from() == kUnboxedUint32) { | 6145 } else if (from() == kUnboxedUint32) { |
| 6145 summary->set_in(0, Location::RequiresRegister()); | 6146 summary->set_in(0, Location::RequiresRegister()); |
| 6146 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 6147 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 6147 Location::RequiresRegister())); | 6148 Location::RequiresRegister())); |
| 6148 } else if (from() == kUnboxedInt32) { | 6149 } else if (from() == kUnboxedInt32) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 6159 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); | 6160 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); |
| 6160 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { | 6161 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { |
| 6161 // Representations are bitwise equivalent. | 6162 // Representations are bitwise equivalent. |
| 6162 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); | 6163 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); |
| 6163 if (CanDeoptimize()) { | 6164 if (CanDeoptimize()) { |
| 6164 Label* deopt = | 6165 Label* deopt = |
| 6165 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 6166 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6166 __ testl(locs()->out(0).reg(), locs()->out(0).reg()); | 6167 __ testl(locs()->out(0).reg(), locs()->out(0).reg()); |
| 6167 __ j(NEGATIVE, deopt); | 6168 __ j(NEGATIVE, deopt); |
| 6168 } | 6169 } |
| 6169 } else if (from() == kUnboxedMint) { | 6170 } else if (from() == kUnboxedInt64) { |
| 6170 // TODO(vegorov) kUnboxedMint -> kInt32 conversion is currently usually | 6171 // TODO(vegorov) kUnboxedInt64 -> kInt32 conversion is currently usually |
| 6171 // dominated by a CheckSmi(BoxInt64(val)) which is an artifact of ordering | 6172 // dominated by a CheckSmi(BoxInt64(val)) which is an artifact of ordering |
| 6172 // of optimization passes and the way we check smi-ness of values. | 6173 // of optimization passes and the way we check smi-ness of values. |
| 6173 // Optimize it away. | 6174 // Optimize it away. |
| 6174 ASSERT(to() == kUnboxedInt32 || to() == kUnboxedUint32); | 6175 ASSERT(to() == kUnboxedInt32 || to() == kUnboxedUint32); |
| 6175 PairLocation* in_pair = locs()->in(0).AsPairLocation(); | 6176 PairLocation* in_pair = locs()->in(0).AsPairLocation(); |
| 6176 Register in_lo = in_pair->At(0).reg(); | 6177 Register in_lo = in_pair->At(0).reg(); |
| 6177 Register in_hi = in_pair->At(1).reg(); | 6178 Register in_hi = in_pair->At(1).reg(); |
| 6178 Register out = locs()->out(0).reg(); | 6179 Register out = locs()->out(0).reg(); |
| 6179 // Copy low word. | 6180 // Copy low word. |
| 6180 __ movl(out, in_lo); | 6181 __ movl(out, in_lo); |
| 6181 if (CanDeoptimize()) { | 6182 if (CanDeoptimize()) { |
| 6182 Label* deopt = | 6183 Label* deopt = |
| 6183 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 6184 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6184 __ sarl(in_lo, Immediate(31)); | 6185 __ sarl(in_lo, Immediate(31)); |
| 6185 __ cmpl(in_lo, in_hi); | 6186 __ cmpl(in_lo, in_hi); |
| 6186 __ j(NOT_EQUAL, deopt); | 6187 __ j(NOT_EQUAL, deopt); |
| 6187 } | 6188 } |
| 6188 } else if (from() == kUnboxedUint32) { | 6189 } else if (from() == kUnboxedUint32) { |
| 6189 ASSERT(to() == kUnboxedMint); | 6190 ASSERT(to() == kUnboxedInt64); |
| 6190 Register in = locs()->in(0).reg(); | 6191 Register in = locs()->in(0).reg(); |
| 6191 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6192 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6192 Register out_lo = out_pair->At(0).reg(); | 6193 Register out_lo = out_pair->At(0).reg(); |
| 6193 Register out_hi = out_pair->At(1).reg(); | 6194 Register out_hi = out_pair->At(1).reg(); |
| 6194 // Copy low word. | 6195 // Copy low word. |
| 6195 __ movl(out_lo, in); | 6196 __ movl(out_lo, in); |
| 6196 // Zero upper word. | 6197 // Zero upper word. |
| 6197 __ xorl(out_hi, out_hi); | 6198 __ xorl(out_hi, out_hi); |
| 6198 } else if (from() == kUnboxedInt32) { | 6199 } else if (from() == kUnboxedInt32) { |
| 6199 ASSERT(to() == kUnboxedMint); | 6200 ASSERT(to() == kUnboxedInt64); |
| 6200 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6201 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6201 Register out_lo = out_pair->At(0).reg(); | 6202 Register out_lo = out_pair->At(0).reg(); |
| 6202 Register out_hi = out_pair->At(1).reg(); | 6203 Register out_hi = out_pair->At(1).reg(); |
| 6203 ASSERT(locs()->in(0).reg() == EAX); | 6204 ASSERT(locs()->in(0).reg() == EAX); |
| 6204 ASSERT(out_lo == EAX && out_hi == EDX); | 6205 ASSERT(out_lo == EAX && out_hi == EDX); |
| 6205 __ cdq(); | 6206 __ cdq(); |
| 6206 } else { | 6207 } else { |
| 6207 UNREACHABLE(); | 6208 UNREACHABLE(); |
| 6208 } | 6209 } |
| 6209 } | 6210 } |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6497 ASSERT(!compiler->is_optimizing()); | 6498 ASSERT(!compiler->is_optimizing()); |
| 6498 __ Call(*StubCode::DebugStepCheck_entry()); | 6499 __ Call(*StubCode::DebugStepCheck_entry()); |
| 6499 compiler->EmitCallsiteMetaData(token_pos(), deopt_id_, stub_kind_, locs()); | 6500 compiler->EmitCallsiteMetaData(token_pos(), deopt_id_, stub_kind_, locs()); |
| 6500 } | 6501 } |
| 6501 | 6502 |
| 6502 } // namespace dart | 6503 } // namespace dart |
| 6503 | 6504 |
| 6504 #undef __ | 6505 #undef __ |
| 6505 | 6506 |
| 6506 #endif // defined TARGET_ARCH_IA32 | 6507 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |