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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 } | 289 } |
290 } | 290 } |
291 | 291 |
292 | 292 |
293 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, | 293 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, |
294 bool opt) const { | 294 bool opt) const { |
295 const intptr_t kNumInputs = 0; | 295 const intptr_t kNumInputs = 0; |
296 const intptr_t kNumTemps = (representation_ == kUnboxedInt32) ? 0 : 1; | 296 const intptr_t kNumTemps = (representation_ == kUnboxedInt32) ? 0 : 1; |
297 LocationSummary* locs = new(isolate) LocationSummary( | 297 LocationSummary* locs = new(isolate) LocationSummary( |
298 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 298 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
299 locs->set_out(0, Location::RequiresFpuRegister()); | 299 if (representation_ == kUnboxedInt32) { |
300 if (representation_ != kUnboxedInt32) { | 300 locs->set_out(0, Location::RequiresRegister()); |
| 301 } else { |
| 302 ASSERT(representation_ == kUnboxedDouble); |
| 303 locs->set_out(0, Location::RequiresFpuRegister()); |
| 304 } |
| 305 if (kNumTemps > 0) { |
301 locs->set_temp(0, Location::RequiresRegister()); | 306 locs->set_temp(0, Location::RequiresRegister()); |
302 } | 307 } |
303 return locs; | 308 return locs; |
304 } | 309 } |
305 | 310 |
306 | 311 |
307 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 312 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
308 // The register allocator drops constant definitions that have no uses. | 313 // The register allocator drops constant definitions that have no uses. |
309 if (!locs()->out(0).IsInvalid()) { | 314 if (!locs()->out(0).IsInvalid()) { |
310 switch (representation_) { | 315 switch (representation_) { |
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 case kOneByteStringCid: | 1365 case kOneByteStringCid: |
1361 case kTypedDataInt8ArrayCid: | 1366 case kTypedDataInt8ArrayCid: |
1362 case kTypedDataUint8ArrayCid: | 1367 case kTypedDataUint8ArrayCid: |
1363 case kExternalTypedDataUint8ArrayCid: | 1368 case kExternalTypedDataUint8ArrayCid: |
1364 case kTypedDataUint8ClampedArrayCid: | 1369 case kTypedDataUint8ClampedArrayCid: |
1365 case kExternalTypedDataUint8ClampedArrayCid: | 1370 case kExternalTypedDataUint8ClampedArrayCid: |
1366 case kTypedDataInt16ArrayCid: | 1371 case kTypedDataInt16ArrayCid: |
1367 case kTypedDataUint16ArrayCid: | 1372 case kTypedDataUint16ArrayCid: |
1368 return kTagged; | 1373 return kTagged; |
1369 case kTypedDataInt32ArrayCid: | 1374 case kTypedDataInt32ArrayCid: |
| 1375 return kUnboxedInt32; |
1370 case kTypedDataUint32ArrayCid: | 1376 case kTypedDataUint32ArrayCid: |
1371 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1377 return kUnboxedUint32; |
1372 case kTypedDataFloat32ArrayCid: | 1378 case kTypedDataFloat32ArrayCid: |
1373 case kTypedDataFloat64ArrayCid: | 1379 case kTypedDataFloat64ArrayCid: |
1374 return kUnboxedDouble; | 1380 return kUnboxedDouble; |
1375 case kTypedDataFloat32x4ArrayCid: | 1381 case kTypedDataFloat32x4ArrayCid: |
1376 return kUnboxedFloat32x4; | 1382 return kUnboxedFloat32x4; |
1377 case kTypedDataInt32x4ArrayCid: | 1383 case kTypedDataInt32x4ArrayCid: |
1378 return kUnboxedInt32x4; | 1384 return kUnboxedInt32x4; |
1379 case kTypedDataFloat64x2ArrayCid: | 1385 case kTypedDataFloat64x2ArrayCid: |
1380 return kUnboxedFloat64x2; | 1386 return kUnboxedFloat64x2; |
1381 default: | 1387 default: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1419 : Location::RegisterOrConstant(value())); | 1425 : Location::RegisterOrConstant(value())); |
1420 break; | 1426 break; |
1421 case kExternalTypedDataUint8ArrayCid: | 1427 case kExternalTypedDataUint8ArrayCid: |
1422 case kExternalTypedDataUint8ClampedArrayCid: | 1428 case kExternalTypedDataUint8ClampedArrayCid: |
1423 case kTypedDataInt8ArrayCid: | 1429 case kTypedDataInt8ArrayCid: |
1424 case kTypedDataUint8ArrayCid: | 1430 case kTypedDataUint8ArrayCid: |
1425 case kTypedDataUint8ClampedArrayCid: | 1431 case kTypedDataUint8ClampedArrayCid: |
1426 case kOneByteStringCid: | 1432 case kOneByteStringCid: |
1427 case kTypedDataInt16ArrayCid: | 1433 case kTypedDataInt16ArrayCid: |
1428 case kTypedDataUint16ArrayCid: | 1434 case kTypedDataUint16ArrayCid: |
1429 locs->set_in(2, Location::RequiresRegister()); | |
1430 break; | |
1431 case kTypedDataInt32ArrayCid: | 1435 case kTypedDataInt32ArrayCid: |
1432 case kTypedDataUint32ArrayCid: | 1436 case kTypedDataUint32ArrayCid: |
1433 // Smis are untagged in TMP register. Mints are stored in register pairs. | 1437 locs->set_in(2, Location::RequiresRegister()); |
1434 if (value()->IsSmiValue()) { | |
1435 locs->set_in(2, Location::RequiresRegister()); | |
1436 } else { | |
1437 // We only move the lower 32-bits so we don't care where the high bits | |
1438 // are located. | |
1439 locs->set_in(2, Location::Pair(Location::RequiresRegister(), | |
1440 Location::Any())); | |
1441 } | |
1442 break; | 1438 break; |
1443 case kTypedDataFloat32ArrayCid: | 1439 case kTypedDataFloat32ArrayCid: |
1444 // Need low register (<= Q7). | 1440 // Need low register (<= Q7). |
1445 locs->set_in(2, Location::FpuRegisterLocation(Q7)); | 1441 locs->set_in(2, Location::FpuRegisterLocation(Q7)); |
1446 break; | 1442 break; |
1447 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. | 1443 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. |
1448 case kTypedDataInt32x4ArrayCid: | 1444 case kTypedDataInt32x4ArrayCid: |
1449 case kTypedDataFloat32x4ArrayCid: | 1445 case kTypedDataFloat32x4ArrayCid: |
1450 case kTypedDataFloat64x2ArrayCid: | 1446 case kTypedDataFloat64x2ArrayCid: |
1451 locs->set_in(2, Location::RequiresFpuRegister()); | 1447 locs->set_in(2, Location::RequiresFpuRegister()); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1530 } | 1526 } |
1531 case kTypedDataInt16ArrayCid: | 1527 case kTypedDataInt16ArrayCid: |
1532 case kTypedDataUint16ArrayCid: { | 1528 case kTypedDataUint16ArrayCid: { |
1533 const Register value = locs()->in(2).reg(); | 1529 const Register value = locs()->in(2).reg(); |
1534 __ SmiUntag(IP, value); | 1530 __ SmiUntag(IP, value); |
1535 __ strh(IP, element_address); | 1531 __ strh(IP, element_address); |
1536 break; | 1532 break; |
1537 } | 1533 } |
1538 case kTypedDataInt32ArrayCid: | 1534 case kTypedDataInt32ArrayCid: |
1539 case kTypedDataUint32ArrayCid: { | 1535 case kTypedDataUint32ArrayCid: { |
1540 if (value()->IsSmiValue()) { | 1536 const Register value = locs()->in(2).reg(); |
1541 ASSERT(RequiredInputRepresentation(2) == kTagged); | 1537 __ str(value, element_address); |
1542 const Register value = locs()->in(2).reg(); | |
1543 __ SmiUntag(IP, value); | |
1544 __ str(IP, element_address); | |
1545 } else { | |
1546 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); | |
1547 PairLocation* value_pair = locs()->in(2).AsPairLocation(); | |
1548 Register value1 = value_pair->At(0).reg(); | |
1549 __ str(value1, element_address); | |
1550 } | |
1551 break; | 1538 break; |
1552 } | 1539 } |
1553 case kTypedDataFloat32ArrayCid: { | 1540 case kTypedDataFloat32ArrayCid: { |
1554 const SRegister value_reg = | 1541 const SRegister value_reg = |
1555 EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg())); | 1542 EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg())); |
1556 __ vstrs(value_reg, element_address); | 1543 __ vstrs(value_reg, element_address); |
1557 break; | 1544 break; |
1558 } | 1545 } |
1559 case kTypedDataFloat64ArrayCid: { | 1546 case kTypedDataFloat64ArrayCid: { |
1560 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg()); | 1547 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg()); |
(...skipping 5123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6684 Register left = locs()->in(0).reg(); | 6671 Register left = locs()->in(0).reg(); |
6685 Register out = locs()->out(0).reg(); | 6672 Register out = locs()->out(0).reg(); |
6686 ASSERT(left != out); | 6673 ASSERT(left != out); |
6687 | 6674 |
6688 ASSERT(op_kind() == Token::kBIT_NOT); | 6675 ASSERT(op_kind() == Token::kBIT_NOT); |
6689 | 6676 |
6690 __ mvn(out, Operand(left)); | 6677 __ mvn(out, Operand(left)); |
6691 } | 6678 } |
6692 | 6679 |
6693 | 6680 |
6694 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, | 6681 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate, |
6695 bool opt) const { | 6682 bool opt) const { |
6696 const intptr_t kNumInputs = 1; | 6683 ASSERT((from_representation() == kUnboxedInt32) || |
6697 const intptr_t kNumTemps = 1; | 6684 (from_representation() == kUnboxedUint32)); |
6698 LocationSummary* summary = new(isolate) LocationSummary( | |
6699 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | |
6700 summary->set_in(0, Location::RequiresRegister()); | |
6701 summary->set_temp(0, Location::RequiresRegister()); | |
6702 summary->set_out(0, Location::RequiresRegister()); | |
6703 return summary; | |
6704 } | |
6705 | |
6706 | |
6707 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6708 Register value = locs()->in(0).reg(); | |
6709 Register out = locs()->out(0).reg(); | |
6710 Register temp = locs()->temp(0).reg(); | |
6711 ASSERT(value != out); | |
6712 | |
6713 Label not_smi, done; | |
6714 | |
6715 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing. | |
6716 | |
6717 // Test if this value is <= kSmiMax. | |
6718 __ CompareImmediate(value, kSmiMax); | |
6719 __ b(¬_smi, HI); | |
6720 // Smi. | |
6721 __ mov(out, Operand(value)); | |
6722 __ SmiTag(out); | |
6723 __ b(&done); | |
6724 __ Bind(¬_smi); | |
6725 // Allocate a mint. | |
6726 BoxAllocationSlowPath::Allocate( | |
6727 compiler, | |
6728 this, | |
6729 compiler->mint_class(), | |
6730 out, | |
6731 temp); | |
6732 // Copy low word into mint. | |
6733 __ StoreToOffset(kWord, | |
6734 value, | |
6735 out, | |
6736 Mint::value_offset() - kHeapObjectTag); | |
6737 // Zero high word. | |
6738 __ eor(temp, temp, Operand(temp)); | |
6739 __ StoreToOffset(kWord, | |
6740 temp, | |
6741 out, | |
6742 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
6743 __ Bind(&done); | |
6744 } | |
6745 | |
6746 | |
6747 | |
6748 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | |
6749 bool opt) const { | |
6750 const intptr_t value_cid = value()->Type()->ToCid(); | |
6751 const intptr_t kNumInputs = 1; | |
6752 const intptr_t kNumTemps = | |
6753 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; | |
6754 LocationSummary* summary = new(isolate) LocationSummary( | |
6755 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
6756 summary->set_in(0, Location::RequiresRegister()); | |
6757 if (kNumTemps > 0) { | |
6758 summary->set_temp(0, Location::RequiresRegister()); | |
6759 } | |
6760 summary->set_out(0, Location::RequiresRegister()); | |
6761 return summary; | |
6762 } | |
6763 | |
6764 | |
6765 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6766 const intptr_t value_cid = value()->Type()->ToCid(); | |
6767 const Register value = locs()->in(0).reg(); | |
6768 const Register out = locs()->out(0).reg(); | |
6769 ASSERT(value != out); | |
6770 | |
6771 // TODO(johnmccutchan): Emit better code for constant inputs. | |
6772 if (value_cid == kMintCid) { | |
6773 __ LoadFromOffset(kWord, out, value, Mint::value_offset() - kHeapObjectTag); | |
6774 } else if (value_cid == kSmiCid) { | |
6775 __ mov(out, Operand(value)); | |
6776 __ SmiUntag(out); | |
6777 } else { | |
6778 Register temp = locs()->temp(0).reg(); | |
6779 Label* deopt = compiler->AddDeoptStub(deopt_id_, | |
6780 ICData::kDeoptUnboxInteger); | |
6781 Label done; | |
6782 __ tst(value, Operand(kSmiTagMask)); | |
6783 // Smi case. | |
6784 __ mov(out, Operand(value), EQ); | |
6785 __ SmiUntag(out, EQ); | |
6786 __ b(&done, EQ); | |
6787 // Mint case. | |
6788 __ CompareClassId(value, kMintCid, temp); | |
6789 __ b(deopt, NE); | |
6790 __ LoadFromOffset(kWord, out, value, Mint::value_offset() - kHeapObjectTag); | |
6791 __ Bind(&done); | |
6792 } | |
6793 } | |
6794 | |
6795 | |
6796 LocationSummary* BoxInt32Instr::MakeLocationSummary(Isolate* isolate, | |
6797 bool opt) const { | |
6798 const intptr_t kNumInputs = 1; | 6685 const intptr_t kNumInputs = 1; |
6799 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; | 6686 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; |
6800 LocationSummary* summary = new(isolate) LocationSummary( | 6687 LocationSummary* summary = new(isolate) LocationSummary( |
6801 isolate, | 6688 isolate, |
6802 kNumInputs, | 6689 kNumInputs, |
6803 kNumTemps, | 6690 kNumTemps, |
6804 ValueFitsSmi() ? LocationSummary::kNoCall | 6691 ValueFitsSmi() ? LocationSummary::kNoCall |
6805 : LocationSummary::kCallOnSlowPath); | 6692 : LocationSummary::kCallOnSlowPath); |
6806 summary->set_in(0, Location::RequiresRegister()); | 6693 summary->set_in(0, Location::RequiresRegister()); |
6807 if (!ValueFitsSmi()) { | 6694 if (!ValueFitsSmi()) { |
6808 summary->set_temp(0, Location::RequiresRegister()); | 6695 summary->set_temp(0, Location::RequiresRegister()); |
6809 } | 6696 } |
6810 summary->set_out(0, Location::RequiresRegister()); | 6697 summary->set_out(0, Location::RequiresRegister()); |
6811 return summary; | 6698 return summary; |
6812 } | 6699 } |
6813 | 6700 |
6814 | 6701 |
6815 void BoxInt32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6702 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6816 Register value = locs()->in(0).reg(); | 6703 Register value = locs()->in(0).reg(); |
6817 Register out = locs()->out(0).reg(); | 6704 Register out = locs()->out(0).reg(); |
6818 ASSERT(value != out); | 6705 ASSERT(value != out); |
6819 | 6706 |
6820 __ Lsl(out, value, 1); | 6707 __ SmiTag(out, value); |
6821 if (!ValueFitsSmi()) { | 6708 if (!ValueFitsSmi()) { |
6822 Register temp = locs()->temp(0).reg(); | 6709 Register temp = locs()->temp(0).reg(); |
6823 Label done; | 6710 Label done; |
6824 __ cmp(value, Operand(out, ASR, 1)); | 6711 if (from_representation() == kUnboxedInt32) { |
| 6712 __ cmp(value, Operand(out, ASR, 1)); |
| 6713 } else { |
| 6714 ASSERT(from_representation() == kUnboxedUint32); |
| 6715 // Note: better to test upper bits instead of comparing with |
| 6716 // kSmiMax as kSmiMax does not fit into immediate operand. |
| 6717 __ TestImmediate(value, 0xC0000000); |
| 6718 } |
6825 __ b(&done, EQ); | 6719 __ b(&done, EQ); |
6826 BoxAllocationSlowPath::Allocate( | 6720 BoxAllocationSlowPath::Allocate( |
6827 compiler, | 6721 compiler, |
6828 this, | 6722 this, |
6829 compiler->mint_class(), | 6723 compiler->mint_class(), |
6830 out, | 6724 out, |
6831 temp); | 6725 temp); |
6832 __ Asr(temp, value, kBitsPerWord - 1); | 6726 if (from_representation() == kUnboxedInt32) { |
| 6727 __ Asr(temp, value, kBitsPerWord - 1); |
| 6728 } else { |
| 6729 ASSERT(from_representation() == kUnboxedUint32); |
| 6730 __ eor(temp, temp, Operand(temp)); |
| 6731 } |
6833 __ StoreToOffset(kWord, | 6732 __ StoreToOffset(kWord, |
6834 value, | 6733 value, |
6835 out, | 6734 out, |
6836 Mint::value_offset() - kHeapObjectTag); | 6735 Mint::value_offset() - kHeapObjectTag); |
6837 __ StoreToOffset(kWord, | 6736 __ StoreToOffset(kWord, |
6838 temp, | 6737 temp, |
6839 out, | 6738 out, |
6840 Mint::value_offset() - kHeapObjectTag + kWordSize); | 6739 Mint::value_offset() - kHeapObjectTag + kWordSize); |
6841 __ Bind(&done); | 6740 __ Bind(&done); |
6842 } | 6741 } |
6843 } | 6742 } |
6844 | 6743 |
6845 | 6744 |
6846 | |
6847 LocationSummary* UnboxInt32Instr::MakeLocationSummary(Isolate* isolate, | |
6848 bool opt) const { | |
6849 const intptr_t value_cid = value()->Type()->ToCid(); | |
6850 const intptr_t kNumInputs = 1; | |
6851 const intptr_t kNumTemps = | |
6852 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; | |
6853 LocationSummary* summary = new(isolate) LocationSummary( | |
6854 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
6855 summary->set_in(0, Location::RequiresRegister()); | |
6856 if (kNumTemps > 0) { | |
6857 summary->set_temp(0, Location::RequiresRegister()); | |
6858 } | |
6859 summary->set_out(0, Location::RequiresRegister()); | |
6860 return summary; | |
6861 } | |
6862 | |
6863 | |
6864 static void LoadInt32FromMint(FlowGraphCompiler* compiler, | 6745 static void LoadInt32FromMint(FlowGraphCompiler* compiler, |
6865 Register mint, | 6746 Register mint, |
6866 Register result, | 6747 Register result, |
6867 Register temp, | 6748 Register temp, |
6868 Label* deopt) { | 6749 Label* deopt) { |
6869 __ LoadFromOffset(kWord, | 6750 __ LoadFromOffset(kWord, |
6870 result, | 6751 result, |
6871 mint, | 6752 mint, |
6872 Mint::value_offset() - kHeapObjectTag); | 6753 Mint::value_offset() - kHeapObjectTag); |
6873 if (deopt != NULL) { | 6754 if (deopt != NULL) { |
6874 __ LoadFromOffset(kWord, | 6755 __ LoadFromOffset(kWord, |
6875 temp, | 6756 temp, |
6876 mint, | 6757 mint, |
6877 Mint::value_offset() - kHeapObjectTag + kWordSize); | 6758 Mint::value_offset() - kHeapObjectTag + kWordSize); |
6878 __ cmp(temp, Operand(result, ASR, kBitsPerWord - 1)); | 6759 __ cmp(temp, Operand(result, ASR, kBitsPerWord - 1)); |
6879 __ b(deopt, NE); | 6760 __ b(deopt, NE); |
6880 } | 6761 } |
6881 } | 6762 } |
6882 | 6763 |
6883 | 6764 |
6884 void UnboxInt32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6765 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, |
| 6766 bool opt) const { |
| 6767 ASSERT((representation() == kUnboxedInt32) || |
| 6768 (representation() == kUnboxedUint32)); |
| 6769 ASSERT((representation() != kUnboxedUint32) || is_truncating()); |
| 6770 const intptr_t value_cid = value()->Type()->ToCid(); |
| 6771 const intptr_t kNumInputs = 1; |
| 6772 const intptr_t kNumTemps = |
| 6773 ((value_cid == kSmiCid) || |
| 6774 ((value_cid == kMintCid) && is_truncating())) ? 0 : 1; |
| 6775 LocationSummary* summary = new(isolate) LocationSummary( |
| 6776 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6777 summary->set_in(0, Location::RequiresRegister()); |
| 6778 if (kNumTemps > 0) { |
| 6779 summary->set_temp(0, Location::RequiresRegister()); |
| 6780 } |
| 6781 summary->set_out(0, Location::RequiresRegister()); |
| 6782 return summary; |
| 6783 } |
| 6784 |
| 6785 |
| 6786 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6885 const intptr_t value_cid = value()->Type()->ToCid(); | 6787 const intptr_t value_cid = value()->Type()->ToCid(); |
6886 const Register value = locs()->in(0).reg(); | 6788 const Register value = locs()->in(0).reg(); |
6887 const Register out = locs()->out(0).reg(); | 6789 const Register out = locs()->out(0).reg(); |
| 6790 const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; |
| 6791 Label* deopt = CanDeoptimize() ? |
| 6792 compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL; |
| 6793 Label* out_of_range = !is_truncating() ? deopt : NULL; |
6888 ASSERT(value != out); | 6794 ASSERT(value != out); |
6889 | 6795 |
6890 if (value_cid == kMintCid) { | 6796 if (value_cid == kSmiCid) { |
6891 Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; | |
6892 Label* deopt = CanDeoptimize() ? | |
6893 compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL; | |
6894 LoadInt32FromMint(compiler, | |
6895 value, | |
6896 out, | |
6897 temp, | |
6898 deopt); | |
6899 } else if (value_cid == kSmiCid) { | |
6900 __ SmiUntag(out, value); | 6797 __ SmiUntag(out, value); |
| 6798 } else if (value_cid == kMintCid) { |
| 6799 LoadInt32FromMint(compiler, value, out, temp, out_of_range); |
6901 } else { | 6800 } else { |
6902 Register temp = locs()->temp(0).reg(); | |
6903 Label* deopt = compiler->AddDeoptStub(deopt_id_, | |
6904 ICData::kDeoptUnboxInteger); | |
6905 Label done; | 6801 Label done; |
6906 __ tst(value, Operand(kSmiTagMask)); | 6802 __ SmiUntag(out, value, &done); |
6907 // Smi case. | |
6908 __ mov(out, Operand(value), EQ); | |
6909 __ SmiUntag(out, EQ); | |
6910 __ b(&done, EQ); | |
6911 // Mint case. | |
6912 __ CompareClassId(value, kMintCid, temp); | 6803 __ CompareClassId(value, kMintCid, temp); |
6913 __ b(deopt, NE); | 6804 __ b(deopt, NE); |
6914 LoadInt32FromMint(compiler, | 6805 LoadInt32FromMint(compiler, value, out, temp, out_of_range); |
6915 value, | |
6916 out, | |
6917 temp, | |
6918 deopt); | |
6919 __ Bind(&done); | 6806 __ Bind(&done); |
6920 } | 6807 } |
6921 } | 6808 } |
6922 | 6809 |
6923 | 6810 |
6924 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 6811 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
6925 bool opt) const { | 6812 bool opt) const { |
6926 const intptr_t kNumInputs = 1; | 6813 const intptr_t kNumInputs = 1; |
6927 const intptr_t kNumTemps = 0; | 6814 const intptr_t kNumTemps = 0; |
6928 LocationSummary* summary = new(isolate) LocationSummary( | 6815 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7237 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 7124 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
7238 #if defined(DEBUG) | 7125 #if defined(DEBUG) |
7239 __ LoadImmediate(R4, kInvalidObjectPointer); | 7126 __ LoadImmediate(R4, kInvalidObjectPointer); |
7240 __ LoadImmediate(R5, kInvalidObjectPointer); | 7127 __ LoadImmediate(R5, kInvalidObjectPointer); |
7241 #endif | 7128 #endif |
7242 } | 7129 } |
7243 | 7130 |
7244 } // namespace dart | 7131 } // namespace dart |
7245 | 7132 |
7246 #endif // defined TARGET_ARCH_ARM | 7133 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |