| 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 |