| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 #if defined(DEBUG) | 98 #if defined(DEBUG) |
| 99 Label stack_ok; | 99 Label stack_ok; |
| 100 __ Comment("Stack Check"); | 100 __ Comment("Stack Check"); |
| 101 __ TraceSimMsg("Stack Check"); | 101 __ TraceSimMsg("Stack Check"); |
| 102 const intptr_t fp_sp_dist = | 102 const intptr_t fp_sp_dist = |
| 103 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; | 103 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; |
| 104 ASSERT(fp_sp_dist <= 0); | 104 ASSERT(fp_sp_dist <= 0); |
| 105 __ subu(CMPRES1, SP, FP); | 105 __ subu(CMPRES1, SP, FP); |
| 106 | 106 |
| 107 __ BranchEqual(CMPRES1, fp_sp_dist, &stack_ok); | 107 __ BranchEqual(CMPRES1, Immediate(fp_sp_dist), &stack_ok); |
| 108 __ break_(0); | 108 __ break_(0); |
| 109 | 109 |
| 110 __ Bind(&stack_ok); | 110 __ Bind(&stack_ok); |
| 111 #endif | 111 #endif |
| 112 __ LeaveDartFrameAndReturn(); | 112 __ LeaveDartFrameAndReturn(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 | 115 |
| 116 static Condition NegateCondition(Condition condition) { | 116 static Condition NegateCondition(Condition condition) { |
| 117 switch (condition) { | 117 switch (condition) { |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 ASSERT(data[0] == kSmiCid); | 751 ASSERT(data[0] == kSmiCid); |
| 752 bool result = data[1] == true_result; | 752 bool result = data[1] == true_result; |
| 753 __ andi(CMPRES1, val_reg, Immediate(kSmiTagMask)); | 753 __ andi(CMPRES1, val_reg, Immediate(kSmiTagMask)); |
| 754 __ beq(CMPRES1, ZR, result ? labels.true_label : labels.false_label); | 754 __ beq(CMPRES1, ZR, result ? labels.true_label : labels.false_label); |
| 755 | 755 |
| 756 __ LoadClassId(cid_reg, val_reg); | 756 __ LoadClassId(cid_reg, val_reg); |
| 757 for (intptr_t i = 2; i < data.length(); i += 2) { | 757 for (intptr_t i = 2; i < data.length(); i += 2) { |
| 758 const intptr_t test_cid = data[i]; | 758 const intptr_t test_cid = data[i]; |
| 759 ASSERT(test_cid != kSmiCid); | 759 ASSERT(test_cid != kSmiCid); |
| 760 result = data[i + 1] == true_result; | 760 result = data[i + 1] == true_result; |
| 761 __ BranchEqual(cid_reg, test_cid, | 761 __ BranchEqual(cid_reg, Immediate(test_cid), |
| 762 result ? labels.true_label : labels.false_label); | 762 result ? labels.true_label : labels.false_label); |
| 763 } | 763 } |
| 764 // No match found, deoptimize or false. | 764 // No match found, deoptimize or false. |
| 765 if (deopt == NULL) { | 765 if (deopt == NULL) { |
| 766 Label* target = result ? labels.false_label : labels.true_label; | 766 Label* target = result ? labels.false_label : labels.true_label; |
| 767 if (target != labels.fall_through) { | 767 if (target != labels.fall_through) { |
| 768 __ b(target); | 768 __ b(target); |
| 769 } | 769 } |
| 770 } else { | 770 } else { |
| 771 __ b(deopt); | 771 __ b(deopt); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 | 978 |
| 979 | 979 |
| 980 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 980 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 981 __ TraceSimMsg("StringToCharCodeInstr"); | 981 __ TraceSimMsg("StringToCharCodeInstr"); |
| 982 | 982 |
| 983 ASSERT(cid_ == kOneByteStringCid); | 983 ASSERT(cid_ == kOneByteStringCid); |
| 984 Register str = locs()->in(0).reg(); | 984 Register str = locs()->in(0).reg(); |
| 985 Register result = locs()->out(0).reg(); | 985 Register result = locs()->out(0).reg(); |
| 986 Label done, is_one; | 986 Label done, is_one; |
| 987 __ lw(result, FieldAddress(str, String::length_offset())); | 987 __ lw(result, FieldAddress(str, String::length_offset())); |
| 988 __ BranchEqual(result, Smi::RawValue(1), &is_one); | 988 __ BranchEqual(result, Immediate(Smi::RawValue(1)), &is_one); |
| 989 __ LoadImmediate(result, Smi::RawValue(-1)); | 989 __ LoadImmediate(result, Smi::RawValue(-1)); |
| 990 __ b(&done); | 990 __ b(&done); |
| 991 __ Bind(&is_one); | 991 __ Bind(&is_one); |
| 992 __ lbu(result, FieldAddress(str, OneByteString::data_offset())); | 992 __ lbu(result, FieldAddress(str, OneByteString::data_offset())); |
| 993 __ SmiTag(result); | 993 __ SmiTag(result); |
| 994 __ Bind(&done); | 994 __ Bind(&done); |
| 995 } | 995 } |
| 996 | 996 |
| 997 | 997 |
| 998 LocationSummary* StringInterpolateInstr::MakeLocationSummary(Isolate* isolate, | 998 LocationSummary* StringInterpolateInstr::MakeLocationSummary(Isolate* isolate, |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 case kTypedDataUint16ArrayCid: | 1230 case kTypedDataUint16ArrayCid: |
| 1231 case kTwoByteStringCid: | 1231 case kTwoByteStringCid: |
| 1232 __ lhu(result, element_address); | 1232 __ lhu(result, element_address); |
| 1233 __ SmiTag(result); | 1233 __ SmiTag(result); |
| 1234 break; | 1234 break; |
| 1235 case kTypedDataInt32ArrayCid: { | 1235 case kTypedDataInt32ArrayCid: { |
| 1236 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 1236 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 1237 ICData::kDeoptInt32Load); | 1237 ICData::kDeoptInt32Load); |
| 1238 __ lw(result, element_address); | 1238 __ lw(result, element_address); |
| 1239 // Verify that the signed value in 'result' can fit inside a Smi. | 1239 // Verify that the signed value in 'result' can fit inside a Smi. |
| 1240 __ BranchSignedLess(result, 0xC0000000, deopt); | 1240 __ BranchSignedLess(result, Immediate(0xC0000000), deopt); |
| 1241 __ SmiTag(result); | 1241 __ SmiTag(result); |
| 1242 } | 1242 } |
| 1243 break; | 1243 break; |
| 1244 case kTypedDataUint32ArrayCid: { | 1244 case kTypedDataUint32ArrayCid: { |
| 1245 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 1245 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 1246 ICData::kDeoptUint32Load); | 1246 ICData::kDeoptUint32Load); |
| 1247 __ lw(result, element_address); | 1247 __ lw(result, element_address); |
| 1248 // Verify that the unsigned value in 'result' can fit inside a Smi. | 1248 // Verify that the unsigned value in 'result' can fit inside a Smi. |
| 1249 __ LoadImmediate(TMP, 0xC0000000); | 1249 __ LoadImmediate(TMP, 0xC0000000); |
| 1250 __ and_(CMPRES1, result, TMP); | 1250 __ and_(CMPRES1, result, TMP); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1391 value = 0xFF; | 1391 value = 0xFF; |
| 1392 } else if (value < 0) { | 1392 } else if (value < 0) { |
| 1393 value = 0; | 1393 value = 0; |
| 1394 } | 1394 } |
| 1395 __ LoadImmediate(TMP, static_cast<int8_t>(value)); | 1395 __ LoadImmediate(TMP, static_cast<int8_t>(value)); |
| 1396 __ sb(TMP, element_address); | 1396 __ sb(TMP, element_address); |
| 1397 } else { | 1397 } else { |
| 1398 Register value = locs()->in(2).reg(); | 1398 Register value = locs()->in(2).reg(); |
| 1399 Label store_value, bigger, smaller; | 1399 Label store_value, bigger, smaller; |
| 1400 __ SmiUntag(TMP, value); | 1400 __ SmiUntag(TMP, value); |
| 1401 __ BranchUnsignedLess(TMP, 0xFF + 1, &store_value); | 1401 __ BranchUnsignedLess(TMP, Immediate(0xFF + 1), &store_value); |
| 1402 __ LoadImmediate(TMP, 0xFF); | 1402 __ LoadImmediate(TMP, 0xFF); |
| 1403 __ slti(CMPRES1, value, Immediate(1)); | 1403 __ slti(CMPRES1, value, Immediate(1)); |
| 1404 __ movn(TMP, ZR, CMPRES1); | 1404 __ movn(TMP, ZR, CMPRES1); |
| 1405 __ Bind(&store_value); | 1405 __ Bind(&store_value); |
| 1406 __ sb(TMP, element_address); | 1406 __ sb(TMP, element_address); |
| 1407 } | 1407 } |
| 1408 break; | 1408 break; |
| 1409 } | 1409 } |
| 1410 case kTypedDataInt16ArrayCid: | 1410 case kTypedDataInt16ArrayCid: |
| 1411 case kTypedDataUint16ArrayCid: { | 1411 case kTypedDataUint16ArrayCid: { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1533 // Check if the tracked state of the guarded field can be initialized | 1533 // Check if the tracked state of the guarded field can be initialized |
| 1534 // inline. If the field needs length check we fall through to runtime | 1534 // inline. If the field needs length check we fall through to runtime |
| 1535 // which is responsible for computing offset of the length field | 1535 // which is responsible for computing offset of the length field |
| 1536 // based on the class id. | 1536 // based on the class id. |
| 1537 // Length guard will be emitted separately when needed via GuardFieldLength | 1537 // Length guard will be emitted separately when needed via GuardFieldLength |
| 1538 // instruction after GuardFieldClass. | 1538 // instruction after GuardFieldClass. |
| 1539 if (!field().needs_length_check()) { | 1539 if (!field().needs_length_check()) { |
| 1540 // Uninitialized field can be handled inline. Check if the | 1540 // Uninitialized field can be handled inline. Check if the |
| 1541 // field is still unitialized. | 1541 // field is still unitialized. |
| 1542 __ lw(CMPRES1, field_cid_operand); | 1542 __ lw(CMPRES1, field_cid_operand); |
| 1543 __ BranchNotEqual(CMPRES1, kIllegalCid, fail); | 1543 __ BranchNotEqual(CMPRES1, Immediate(kIllegalCid), fail); |
| 1544 | 1544 |
| 1545 if (value_cid == kDynamicCid) { | 1545 if (value_cid == kDynamicCid) { |
| 1546 __ sw(value_cid_reg, field_cid_operand); | 1546 __ sw(value_cid_reg, field_cid_operand); |
| 1547 __ sw(value_cid_reg, field_nullability_operand); | 1547 __ sw(value_cid_reg, field_nullability_operand); |
| 1548 } else { | 1548 } else { |
| 1549 __ LoadImmediate(TMP, value_cid); | 1549 __ LoadImmediate(TMP, value_cid); |
| 1550 __ sw(TMP, field_cid_operand); | 1550 __ sw(TMP, field_cid_operand); |
| 1551 __ sw(TMP, field_nullability_operand); | 1551 __ sw(TMP, field_nullability_operand); |
| 1552 } | 1552 } |
| 1553 | 1553 |
| 1554 if (deopt == NULL) { | 1554 if (deopt == NULL) { |
| 1555 ASSERT(!compiler->is_optimizing()); | 1555 ASSERT(!compiler->is_optimizing()); |
| 1556 __ b(&ok); | 1556 __ b(&ok); |
| 1557 } | 1557 } |
| 1558 } | 1558 } |
| 1559 | 1559 |
| 1560 if (deopt == NULL) { | 1560 if (deopt == NULL) { |
| 1561 ASSERT(!compiler->is_optimizing()); | 1561 ASSERT(!compiler->is_optimizing()); |
| 1562 __ Bind(fail); | 1562 __ Bind(fail); |
| 1563 | 1563 |
| 1564 __ lw(CMPRES1, FieldAddress(field_reg, Field::guarded_cid_offset())); | 1564 __ lw(CMPRES1, FieldAddress(field_reg, Field::guarded_cid_offset())); |
| 1565 __ BranchEqual(CMPRES1, kDynamicCid, &ok); | 1565 __ BranchEqual(CMPRES1, Immediate(kDynamicCid), &ok); |
| 1566 | 1566 |
| 1567 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1567 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 1568 __ sw(field_reg, Address(SP, 1 * kWordSize)); | 1568 __ sw(field_reg, Address(SP, 1 * kWordSize)); |
| 1569 __ sw(value_reg, Address(SP, 0 * kWordSize)); | 1569 __ sw(value_reg, Address(SP, 0 * kWordSize)); |
| 1570 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); | 1570 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); |
| 1571 __ Drop(2); // Drop the field and the value. | 1571 __ Drop(2); // Drop the field and the value. |
| 1572 } | 1572 } |
| 1573 } else { | 1573 } else { |
| 1574 ASSERT(compiler->is_optimizing()); | 1574 ASSERT(compiler->is_optimizing()); |
| 1575 ASSERT(deopt != NULL); | 1575 ASSERT(deopt != NULL); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1796 | 1796 |
| 1797 static void EnsureMutableBox(FlowGraphCompiler* compiler, | 1797 static void EnsureMutableBox(FlowGraphCompiler* compiler, |
| 1798 StoreInstanceFieldInstr* instruction, | 1798 StoreInstanceFieldInstr* instruction, |
| 1799 Register box_reg, | 1799 Register box_reg, |
| 1800 const Class& cls, | 1800 const Class& cls, |
| 1801 Register instance_reg, | 1801 Register instance_reg, |
| 1802 intptr_t offset, | 1802 intptr_t offset, |
| 1803 Register temp) { | 1803 Register temp) { |
| 1804 Label done; | 1804 Label done; |
| 1805 __ lw(box_reg, FieldAddress(instance_reg, offset)); | 1805 __ lw(box_reg, FieldAddress(instance_reg, offset)); |
| 1806 __ BranchNotEqual(box_reg, reinterpret_cast<int32_t>(Object::null()), | 1806 __ BranchNotEqual(box_reg, Object::null_object(), &done); |
| 1807 &done); | |
| 1808 BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp); | 1807 BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp); |
| 1809 __ mov(temp, box_reg); | 1808 __ mov(temp, box_reg); |
| 1810 __ StoreIntoObjectOffset(instance_reg, offset, temp); | 1809 __ StoreIntoObjectOffset(instance_reg, offset, temp); |
| 1811 __ Bind(&done); | 1810 __ Bind(&done); |
| 1812 } | 1811 } |
| 1813 | 1812 |
| 1814 | 1813 |
| 1815 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1814 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1816 Label skip_store; | 1815 Label skip_store; |
| 1817 | 1816 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 // across allocation slow-path. | 1859 // across allocation slow-path. |
| 1861 locs()->live_registers()->Add(locs()->in(1), kTagged); | 1860 locs()->live_registers()->Add(locs()->in(1), kTagged); |
| 1862 } | 1861 } |
| 1863 | 1862 |
| 1864 Label store_pointer; | 1863 Label store_pointer; |
| 1865 Label store_double; | 1864 Label store_double; |
| 1866 | 1865 |
| 1867 __ LoadObject(temp, Field::ZoneHandle(field().raw())); | 1866 __ LoadObject(temp, Field::ZoneHandle(field().raw())); |
| 1868 | 1867 |
| 1869 __ lw(temp2, FieldAddress(temp, Field::is_nullable_offset())); | 1868 __ lw(temp2, FieldAddress(temp, Field::is_nullable_offset())); |
| 1870 __ BranchEqual(temp2, kNullCid, &store_pointer); | 1869 __ BranchEqual(temp2, Immediate(kNullCid), &store_pointer); |
| 1871 | 1870 |
| 1872 __ lbu(temp2, FieldAddress(temp, Field::kind_bits_offset())); | 1871 __ lbu(temp2, FieldAddress(temp, Field::kind_bits_offset())); |
| 1873 __ andi(CMPRES1, temp2, Immediate(1 << Field::kUnboxingCandidateBit)); | 1872 __ andi(CMPRES1, temp2, Immediate(1 << Field::kUnboxingCandidateBit)); |
| 1874 __ beq(CMPRES1, ZR, &store_pointer); | 1873 __ beq(CMPRES1, ZR, &store_pointer); |
| 1875 | 1874 |
| 1876 __ lw(temp2, FieldAddress(temp, Field::guarded_cid_offset())); | 1875 __ lw(temp2, FieldAddress(temp, Field::guarded_cid_offset())); |
| 1877 __ BranchEqual(temp2, kDoubleCid, &store_double); | 1876 __ BranchEqual(temp2, Immediate(kDoubleCid), &store_double); |
| 1878 | 1877 |
| 1879 // Fall through. | 1878 // Fall through. |
| 1880 __ b(&store_pointer); | 1879 __ b(&store_pointer); |
| 1881 | 1880 |
| 1882 if (!compiler->is_optimizing()) { | 1881 if (!compiler->is_optimizing()) { |
| 1883 locs()->live_registers()->Add(locs()->in(0)); | 1882 locs()->live_registers()->Add(locs()->in(0)); |
| 1884 locs()->live_registers()->Add(locs()->in(1)); | 1883 locs()->live_registers()->Add(locs()->in(1)); |
| 1885 } | 1884 } |
| 1886 | 1885 |
| 1887 { | 1886 { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2167 Label load_pointer; | 2166 Label load_pointer; |
| 2168 Label load_double; | 2167 Label load_double; |
| 2169 | 2168 |
| 2170 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); | 2169 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |
| 2171 | 2170 |
| 2172 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); | 2171 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |
| 2173 FieldAddress field_nullability_operand(result_reg, | 2172 FieldAddress field_nullability_operand(result_reg, |
| 2174 Field::is_nullable_offset()); | 2173 Field::is_nullable_offset()); |
| 2175 | 2174 |
| 2176 __ lw(temp, field_nullability_operand); | 2175 __ lw(temp, field_nullability_operand); |
| 2177 __ BranchEqual(temp, kNullCid, &load_pointer); | 2176 __ BranchEqual(temp, Immediate(kNullCid), &load_pointer); |
| 2178 | 2177 |
| 2179 __ lw(temp, field_cid_operand); | 2178 __ lw(temp, field_cid_operand); |
| 2180 __ BranchEqual(temp, kDoubleCid, &load_double); | 2179 __ BranchEqual(temp, Immediate(kDoubleCid), &load_double); |
| 2181 | 2180 |
| 2182 // Fall through. | 2181 // Fall through. |
| 2183 __ b(&load_pointer); | 2182 __ b(&load_pointer); |
| 2184 | 2183 |
| 2185 if (!compiler->is_optimizing()) { | 2184 if (!compiler->is_optimizing()) { |
| 2186 locs()->live_registers()->Add(locs()->in(0)); | 2185 locs()->live_registers()->Add(locs()->in(0)); |
| 2187 } | 2186 } |
| 2188 | 2187 |
| 2189 { | 2188 { |
| 2190 __ Bind(&load_double); | 2189 __ Bind(&load_double); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2269 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2268 // 'instantiator_reg' is the instantiator TypeArguments object (or null). |
| 2270 ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2269 ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
| 2271 !type_arguments().CanShareInstantiatorTypeArguments( | 2270 !type_arguments().CanShareInstantiatorTypeArguments( |
| 2272 instantiator_class())); | 2271 instantiator_class())); |
| 2273 // If the instantiator is null and if the type argument vector | 2272 // If the instantiator is null and if the type argument vector |
| 2274 // instantiated from null becomes a vector of dynamic, then use null as | 2273 // instantiated from null becomes a vector of dynamic, then use null as |
| 2275 // the type arguments. | 2274 // the type arguments. |
| 2276 Label type_arguments_instantiated; | 2275 Label type_arguments_instantiated; |
| 2277 const intptr_t len = type_arguments().Length(); | 2276 const intptr_t len = type_arguments().Length(); |
| 2278 if (type_arguments().IsRawInstantiatedRaw(len)) { | 2277 if (type_arguments().IsRawInstantiatedRaw(len)) { |
| 2279 __ BranchEqual(instantiator_reg, reinterpret_cast<int32_t>(Object::null()), | 2278 __ BranchEqual(instantiator_reg, Object::null_object(), |
| 2280 &type_arguments_instantiated); | 2279 &type_arguments_instantiated); |
| 2281 } | 2280 } |
| 2282 | 2281 |
| 2283 __ LoadObject(T2, type_arguments()); | 2282 __ LoadObject(T2, type_arguments()); |
| 2284 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); | 2283 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); |
| 2285 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); | 2284 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); |
| 2286 // The instantiations cache is initialized with Object::zero_array() and is | 2285 // The instantiations cache is initialized with Object::zero_array() and is |
| 2287 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2286 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
| 2288 Label loop, found, slow_case; | 2287 Label loop, found, slow_case; |
| 2289 __ Bind(&loop); | 2288 __ Bind(&loop); |
| 2290 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator. | 2289 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator. |
| 2291 __ beq(T1, T0, &found); | 2290 __ beq(T1, T0, &found); |
| 2292 __ BranchNotEqual(T1, Smi::RawValue(StubCode::kNoInstantiator), &loop); | 2291 __ BranchNotEqual( |
| 2292 T1, Immediate(Smi::RawValue(StubCode::kNoInstantiator)), &loop); |
| 2293 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize)); | 2293 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize)); |
| 2294 __ b(&slow_case); | 2294 __ b(&slow_case); |
| 2295 __ Bind(&found); | 2295 __ Bind(&found); |
| 2296 __ lw(T0, Address(T2, 1 * kWordSize)); // Cached instantiated args. | 2296 __ lw(T0, Address(T2, 1 * kWordSize)); // Cached instantiated args. |
| 2297 __ b(&type_arguments_instantiated); | 2297 __ b(&type_arguments_instantiated); |
| 2298 | 2298 |
| 2299 __ Bind(&slow_case); | 2299 __ Bind(&slow_case); |
| 2300 // Instantiate non-null type arguments. | 2300 // Instantiate non-null type arguments. |
| 2301 // A runtime call to instantiate the type arguments is required. | 2301 // A runtime call to instantiate the type arguments is required. |
| 2302 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 2302 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2615 __ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label()); | 2615 __ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label()); |
| 2616 if (compiler->CanOSRFunction() && in_loop()) { | 2616 if (compiler->CanOSRFunction() && in_loop()) { |
| 2617 Register temp = locs()->temp(0).reg(); | 2617 Register temp = locs()->temp(0).reg(); |
| 2618 // In unoptimized code check the usage counter to trigger OSR at loop | 2618 // In unoptimized code check the usage counter to trigger OSR at loop |
| 2619 // stack checks. Use progressively higher thresholds for more deeply | 2619 // stack checks. Use progressively higher thresholds for more deeply |
| 2620 // nested loops to attempt to hit outer loops with OSR when possible. | 2620 // nested loops to attempt to hit outer loops with OSR when possible. |
| 2621 __ LoadObject(temp, compiler->parsed_function().function()); | 2621 __ LoadObject(temp, compiler->parsed_function().function()); |
| 2622 intptr_t threshold = | 2622 intptr_t threshold = |
| 2623 FLAG_optimization_counter_threshold * (loop_depth() + 1); | 2623 FLAG_optimization_counter_threshold * (loop_depth() + 1); |
| 2624 __ lw(temp, FieldAddress(temp, Function::usage_counter_offset())); | 2624 __ lw(temp, FieldAddress(temp, Function::usage_counter_offset())); |
| 2625 __ BranchSignedGreaterEqual(temp, threshold, slow_path->osr_entry_label()); | 2625 __ BranchSignedGreaterEqual( |
| 2626 temp, Immediate(threshold), slow_path->osr_entry_label()); |
| 2626 } | 2627 } |
| 2627 if (compiler->ForceSlowPathForStackOverflow()) { | 2628 if (compiler->ForceSlowPathForStackOverflow()) { |
| 2628 __ b(slow_path->entry_label()); | 2629 __ b(slow_path->entry_label()); |
| 2629 } | 2630 } |
| 2630 __ Bind(slow_path->exit_label()); | 2631 __ Bind(slow_path->exit_label()); |
| 2631 } | 2632 } |
| 2632 | 2633 |
| 2633 | 2634 |
| 2634 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2635 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2635 BinarySmiOpInstr* shift_left) { | 2636 BinarySmiOpInstr* shift_left) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2671 const intptr_t left_int = Smi::Cast(obj).Value(); | 2672 const intptr_t left_int = Smi::Cast(obj).Value(); |
| 2672 if (left_int == 0) { | 2673 if (left_int == 0) { |
| 2673 __ bltz(right, deopt); | 2674 __ bltz(right, deopt); |
| 2674 __ mov(result, ZR); | 2675 __ mov(result, ZR); |
| 2675 return; | 2676 return; |
| 2676 } | 2677 } |
| 2677 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); | 2678 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); |
| 2678 const bool right_needs_check = | 2679 const bool right_needs_check = |
| 2679 !RangeUtils::IsWithin(right_range, 0, max_right - 1); | 2680 !RangeUtils::IsWithin(right_range, 0, max_right - 1); |
| 2680 if (right_needs_check) { | 2681 if (right_needs_check) { |
| 2681 __ BranchUnsignedGreaterEqual( | 2682 const Immediate& max_right_imm = |
| 2682 right, reinterpret_cast<int32_t>(Smi::New(max_right)), deopt); | 2683 Immediate(reinterpret_cast<int32_t>(Smi::New(max_right))); |
| 2684 __ BranchUnsignedGreaterEqual(right, max_right_imm, deopt); |
| 2683 } | 2685 } |
| 2684 __ SmiUntag(TMP, right); | 2686 __ SmiUntag(TMP, right); |
| 2685 __ sllv(result, left, TMP); | 2687 __ sllv(result, left, TMP); |
| 2686 } | 2688 } |
| 2687 return; | 2689 return; |
| 2688 } | 2690 } |
| 2689 | 2691 |
| 2690 const bool right_needs_check = | 2692 const bool right_needs_check = |
| 2691 !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1)); | 2693 !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1)); |
| 2692 if (!shift_left->can_overflow()) { | 2694 if (!shift_left->can_overflow()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2705 __ sra(TMP, right, kSmiTagSize); | 2707 __ sra(TMP, right, kSmiTagSize); |
| 2706 __ sllv(TMP, left, TMP); | 2708 __ sllv(TMP, left, TMP); |
| 2707 // result = right < kBits ? left << right : result. | 2709 // result = right < kBits ? left << right : result. |
| 2708 __ movn(result, TMP, CMPRES1); | 2710 __ movn(result, TMP, CMPRES1); |
| 2709 } else { | 2711 } else { |
| 2710 __ sra(TMP, right, kSmiTagSize); | 2712 __ sra(TMP, right, kSmiTagSize); |
| 2711 __ sllv(result, left, TMP); | 2713 __ sllv(result, left, TMP); |
| 2712 } | 2714 } |
| 2713 } else { | 2715 } else { |
| 2714 if (right_needs_check) { | 2716 if (right_needs_check) { |
| 2717 const Immediate& bits_imm = |
| 2718 Immediate(reinterpret_cast<int32_t>(Smi::New(Smi::kBits))); |
| 2715 ASSERT(shift_left->CanDeoptimize()); | 2719 ASSERT(shift_left->CanDeoptimize()); |
| 2716 __ BranchUnsignedGreaterEqual( | 2720 __ BranchUnsignedGreaterEqual(right, bits_imm, deopt); |
| 2717 right, reinterpret_cast<int32_t>(Smi::New(Smi::kBits)), deopt); | |
| 2718 } | 2721 } |
| 2719 // Left is not a constant. | 2722 // Left is not a constant. |
| 2720 Register temp = locs.temp(0).reg(); | 2723 Register temp = locs.temp(0).reg(); |
| 2721 // Check if count too large for handling it inlined. | 2724 // Check if count too large for handling it inlined. |
| 2722 __ SmiUntag(temp, right); | 2725 __ SmiUntag(temp, right); |
| 2723 // Overflow test (preserve left, right, and temp); | 2726 // Overflow test (preserve left, right, and temp); |
| 2724 __ sllv(CMPRES1, left, temp); | 2727 __ sllv(CMPRES1, left, temp); |
| 2725 __ srav(CMPRES1, CMPRES1, temp); | 2728 __ srav(CMPRES1, CMPRES1, temp); |
| 2726 __ bne(CMPRES1, left, deopt); // Overflow. | 2729 __ bne(CMPRES1, left, deopt); // Overflow. |
| 2727 // Shift for result now we know there is no overflow. | 2730 // Shift for result now we know there is no overflow. |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2949 // Handle divide by zero in runtime. | 2952 // Handle divide by zero in runtime. |
| 2950 __ beq(right, ZR, deopt); | 2953 __ beq(right, ZR, deopt); |
| 2951 } | 2954 } |
| 2952 Register temp = locs()->temp(0).reg(); | 2955 Register temp = locs()->temp(0).reg(); |
| 2953 __ SmiUntag(temp, left); | 2956 __ SmiUntag(temp, left); |
| 2954 __ SmiUntag(TMP, right); | 2957 __ SmiUntag(TMP, right); |
| 2955 __ div(temp, TMP); | 2958 __ div(temp, TMP); |
| 2956 __ mflo(result); | 2959 __ mflo(result); |
| 2957 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 2960 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 2958 // case we cannot tag the result. | 2961 // case we cannot tag the result. |
| 2959 __ BranchEqual(result, 0x40000000, deopt); | 2962 __ BranchEqual(result, Immediate(0x40000000), deopt); |
| 2960 __ SmiTag(result); | 2963 __ SmiTag(result); |
| 2961 break; | 2964 break; |
| 2962 } | 2965 } |
| 2963 case Token::kMOD: { | 2966 case Token::kMOD: { |
| 2964 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 2967 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
| 2965 // Handle divide by zero in runtime. | 2968 // Handle divide by zero in runtime. |
| 2966 __ beq(right, ZR, deopt); | 2969 __ beq(right, ZR, deopt); |
| 2967 } | 2970 } |
| 2968 Register temp = locs()->temp(0).reg(); | 2971 Register temp = locs()->temp(0).reg(); |
| 2969 __ SmiUntag(temp, left); | 2972 __ SmiUntag(temp, left); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3002 Register temp = locs()->temp(0).reg(); | 3005 Register temp = locs()->temp(0).reg(); |
| 3003 if (CanDeoptimize()) { | 3006 if (CanDeoptimize()) { |
| 3004 __ bltz(right, deopt); | 3007 __ bltz(right, deopt); |
| 3005 } | 3008 } |
| 3006 __ SmiUntag(temp, right); | 3009 __ SmiUntag(temp, right); |
| 3007 // sra operation masks the count to 5 bits. | 3010 // sra operation masks the count to 5 bits. |
| 3008 const intptr_t kCountLimit = 0x1F; | 3011 const intptr_t kCountLimit = 0x1F; |
| 3009 if ((right_range == NULL) || | 3012 if ((right_range == NULL) || |
| 3010 !right_range->OnlyLessThanOrEqualTo(kCountLimit)) { | 3013 !right_range->OnlyLessThanOrEqualTo(kCountLimit)) { |
| 3011 Label ok; | 3014 Label ok; |
| 3012 __ BranchSignedLessEqual(temp, kCountLimit, &ok); | 3015 __ BranchSignedLessEqual(temp, Immediate(kCountLimit), &ok); |
| 3013 __ LoadImmediate(temp, kCountLimit); | 3016 __ LoadImmediate(temp, kCountLimit); |
| 3014 __ Bind(&ok); | 3017 __ Bind(&ok); |
| 3015 } | 3018 } |
| 3016 | 3019 |
| 3017 __ SmiUntag(CMPRES1, left); | 3020 __ SmiUntag(CMPRES1, left); |
| 3018 __ srav(result, CMPRES1, temp); | 3021 __ srav(result, CMPRES1, temp); |
| 3019 __ SmiTag(result); | 3022 __ SmiTag(result); |
| 3020 break; | 3023 break; |
| 3021 } | 3024 } |
| 3022 case Token::kDIV: { | 3025 case Token::kDIV: { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3122 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); | 3125 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); |
| 3123 } else if (value_cid == kSmiCid) { | 3126 } else if (value_cid == kSmiCid) { |
| 3124 __ SmiUntag(TMP, value); | 3127 __ SmiUntag(TMP, value); |
| 3125 __ mtc1(TMP, STMP1); | 3128 __ mtc1(TMP, STMP1); |
| 3126 __ cvtdw(result, STMP1); | 3129 __ cvtdw(result, STMP1); |
| 3127 } else { | 3130 } else { |
| 3128 Label* deopt = compiler->AddDeoptStub(deopt_id_, | 3131 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 3129 ICData::kDeoptBinaryDoubleOp); | 3132 ICData::kDeoptBinaryDoubleOp); |
| 3130 if (value_type->is_nullable() && | 3133 if (value_type->is_nullable() && |
| 3131 (value_type->ToNullableCid() == kDoubleCid)) { | 3134 (value_type->ToNullableCid() == kDoubleCid)) { |
| 3132 __ BranchEqual(value, reinterpret_cast<int32_t>(Object::null()), deopt); | 3135 __ BranchEqual(value, Object::null_object(), deopt); |
| 3133 // It must be double now. | 3136 // It must be double now. |
| 3134 __ LoadDFromOffset(result, value, | 3137 __ LoadDFromOffset(result, value, |
| 3135 Double::value_offset() - kHeapObjectTag); | 3138 Double::value_offset() - kHeapObjectTag); |
| 3136 } else { | 3139 } else { |
| 3137 Label is_smi, done; | 3140 Label is_smi, done; |
| 3138 | 3141 |
| 3139 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); | 3142 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
| 3140 __ beq(CMPRES1, ZR, &is_smi); | 3143 __ beq(CMPRES1, ZR, &is_smi); |
| 3141 __ LoadClassId(CMPRES1, value); | 3144 __ LoadClassId(CMPRES1, value); |
| 3142 __ BranchNotEqual(CMPRES1, kDoubleCid, deopt); | 3145 __ BranchNotEqual(CMPRES1, Immediate(kDoubleCid), deopt); |
| 3143 __ LoadDFromOffset(result, value, | 3146 __ LoadDFromOffset(result, value, |
| 3144 Double::value_offset() - kHeapObjectTag); | 3147 Double::value_offset() - kHeapObjectTag); |
| 3145 __ b(&done); | 3148 __ b(&done); |
| 3146 __ Bind(&is_smi); | 3149 __ Bind(&is_smi); |
| 3147 __ SmiUntag(TMP, value); | 3150 __ SmiUntag(TMP, value); |
| 3148 __ mtc1(TMP, STMP1); | 3151 __ mtc1(TMP, STMP1); |
| 3149 __ cvtdw(result, STMP1); | 3152 __ cvtdw(result, STMP1); |
| 3150 __ Bind(&done); | 3153 __ Bind(&done); |
| 3151 } | 3154 } |
| 3152 } | 3155 } |
| (...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4202 // Handle divide by zero in runtime. | 4205 // Handle divide by zero in runtime. |
| 4203 __ beq(right, ZR, deopt); | 4206 __ beq(right, ZR, deopt); |
| 4204 } | 4207 } |
| 4205 __ SmiUntag(temp, left); | 4208 __ SmiUntag(temp, left); |
| 4206 __ SmiUntag(TMP, right); | 4209 __ SmiUntag(TMP, right); |
| 4207 __ div(temp, TMP); | 4210 __ div(temp, TMP); |
| 4208 __ mflo(result_div); | 4211 __ mflo(result_div); |
| 4209 __ mfhi(result_mod); | 4212 __ mfhi(result_mod); |
| 4210 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 4213 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 4211 // case we cannot tag the result. | 4214 // case we cannot tag the result. |
| 4212 __ BranchEqual(result_div, 0x40000000, deopt); | 4215 __ BranchEqual(result_div, Immediate(0x40000000), deopt); |
| 4213 // res = left % right; | 4216 // res = left % right; |
| 4214 // if (res < 0) { | 4217 // if (res < 0) { |
| 4215 // if (right < 0) { | 4218 // if (right < 0) { |
| 4216 // res = res - right; | 4219 // res = res - right; |
| 4217 // } else { | 4220 // } else { |
| 4218 // res = res + right; | 4221 // res = res + right; |
| 4219 // } | 4222 // } |
| 4220 // } | 4223 // } |
| 4221 Label done; | 4224 Label done; |
| 4222 __ bgez(result_mod, &done); | 4225 __ bgez(result_mod, &done); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4316 } | 4319 } |
| 4317 return summary; | 4320 return summary; |
| 4318 } | 4321 } |
| 4319 | 4322 |
| 4320 | 4323 |
| 4321 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4324 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4322 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 4325 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 4323 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 4326 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 4324 if (IsNullCheck()) { | 4327 if (IsNullCheck()) { |
| 4325 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 4328 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| 4326 __ BranchEqual(locs()->in(0).reg(), | 4329 __ BranchEqual(locs()->in(0).reg(), Object::null_object(), deopt); |
| 4327 reinterpret_cast<int32_t>(Object::null()), deopt); | |
| 4328 return; | 4330 return; |
| 4329 } | 4331 } |
| 4330 | 4332 |
| 4331 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | 4333 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
| 4332 (unary_checks().NumberOfChecks() > 1)); | 4334 (unary_checks().NumberOfChecks() > 1)); |
| 4333 Register value = locs()->in(0).reg(); | 4335 Register value = locs()->in(0).reg(); |
| 4334 Register temp = locs()->temp(0).reg(); | 4336 Register temp = locs()->temp(0).reg(); |
| 4335 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 4337 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| 4336 Label is_ok; | 4338 Label is_ok; |
| 4337 intptr_t cix = 0; | 4339 intptr_t cix = 0; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4406 LocationSummary* summary = new(isolate) LocationSummary( | 4408 LocationSummary* summary = new(isolate) LocationSummary( |
| 4407 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4409 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4408 summary->set_in(0, Location::RequiresRegister()); | 4410 summary->set_in(0, Location::RequiresRegister()); |
| 4409 return summary; | 4411 return summary; |
| 4410 } | 4412 } |
| 4411 | 4413 |
| 4412 | 4414 |
| 4413 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4415 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4414 Register value = locs()->in(0).reg(); | 4416 Register value = locs()->in(0).reg(); |
| 4415 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | 4417 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); |
| 4416 __ BranchNotEqual(value, Smi::RawValue(cid_), deopt); | 4418 __ BranchNotEqual(value, Immediate(Smi::RawValue(cid_)), deopt); |
| 4417 } | 4419 } |
| 4418 | 4420 |
| 4419 | 4421 |
| 4420 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 4422 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, |
| 4421 bool opt) const { | 4423 bool opt) const { |
| 4422 const intptr_t kNumInputs = 2; | 4424 const intptr_t kNumInputs = 2; |
| 4423 const intptr_t kNumTemps = 0; | 4425 const intptr_t kNumTemps = 0; |
| 4424 LocationSummary* locs = new(isolate) LocationSummary( | 4426 LocationSummary* locs = new(isolate) LocationSummary( |
| 4425 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4427 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4426 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 4428 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4443 // Unconditionally deoptimize for constant bounds checks because they | 4445 // Unconditionally deoptimize for constant bounds checks because they |
| 4444 // only occur only when index is out-of-bounds. | 4446 // only occur only when index is out-of-bounds. |
| 4445 __ b(deopt); | 4447 __ b(deopt); |
| 4446 return; | 4448 return; |
| 4447 } | 4449 } |
| 4448 | 4450 |
| 4449 if (index_loc.IsConstant()) { | 4451 if (index_loc.IsConstant()) { |
| 4450 Register length = length_loc.reg(); | 4452 Register length = length_loc.reg(); |
| 4451 const Smi& index = Smi::Cast(index_loc.constant()); | 4453 const Smi& index = Smi::Cast(index_loc.constant()); |
| 4452 __ BranchUnsignedLessEqual( | 4454 __ BranchUnsignedLessEqual( |
| 4453 length, reinterpret_cast<int32_t>(index.raw()), deopt); | 4455 length, Immediate(reinterpret_cast<int32_t>(index.raw())), deopt); |
| 4454 } else if (length_loc.IsConstant()) { | 4456 } else if (length_loc.IsConstant()) { |
| 4455 const Smi& length = Smi::Cast(length_loc.constant()); | 4457 const Smi& length = Smi::Cast(length_loc.constant()); |
| 4456 Register index = index_loc.reg(); | 4458 Register index = index_loc.reg(); |
| 4457 __ BranchUnsignedGreaterEqual( | 4459 __ BranchUnsignedGreaterEqual( |
| 4458 index, reinterpret_cast<int32_t>(length.raw()), deopt); | 4460 index, Immediate(reinterpret_cast<int32_t>(length.raw())), deopt); |
| 4459 } else { | 4461 } else { |
| 4460 Register length = length_loc.reg(); | 4462 Register length = length_loc.reg(); |
| 4461 Register index = index_loc.reg(); | 4463 Register index = index_loc.reg(); |
| 4462 __ BranchUnsignedGreaterEqual(index, length, deopt); | 4464 __ BranchUnsignedGreaterEqual(index, length, deopt); |
| 4463 } | 4465 } |
| 4464 } | 4466 } |
| 4465 | 4467 |
| 4466 | 4468 |
| 4467 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, | 4469 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, |
| 4468 bool opt) const { | 4470 bool opt) const { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4651 if (value_cid == kSmiCid) { | 4653 if (value_cid == kSmiCid) { |
| 4652 __ SmiUntag(out, value); | 4654 __ SmiUntag(out, value); |
| 4653 } else if (value_cid == kMintCid) { | 4655 } else if (value_cid == kMintCid) { |
| 4654 LoadInt32FromMint(compiler, value, out, out_of_range); | 4656 LoadInt32FromMint(compiler, value, out, out_of_range); |
| 4655 } else { | 4657 } else { |
| 4656 Label done; | 4658 Label done; |
| 4657 __ SmiUntag(out, value); | 4659 __ SmiUntag(out, value); |
| 4658 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); | 4660 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
| 4659 __ beq(CMPRES1, ZR, &done); | 4661 __ beq(CMPRES1, ZR, &done); |
| 4660 __ LoadClassId(CMPRES1, value); | 4662 __ LoadClassId(CMPRES1, value); |
| 4661 __ BranchNotEqual(CMPRES1, kMintCid, deopt); | 4663 __ BranchNotEqual(CMPRES1, Immediate(kMintCid), deopt); |
| 4662 LoadInt32FromMint(compiler, value, out, out_of_range); | 4664 LoadInt32FromMint(compiler, value, out, out_of_range); |
| 4663 __ Bind(&done); | 4665 __ Bind(&done); |
| 4664 } | 4666 } |
| 4665 } | 4667 } |
| 4666 | 4668 |
| 4667 | 4669 |
| 4668 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 4670 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
| 4669 bool opt) const { | 4671 bool opt) const { |
| 4670 const intptr_t kNumInputs = 1; | 4672 const intptr_t kNumInputs = 1; |
| 4671 const intptr_t kNumTemps = 0; | 4673 const intptr_t kNumTemps = 0; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4690 const Register out = locs()->out(0).reg(); | 4692 const Register out = locs()->out(0).reg(); |
| 4691 // Representations are bitwise equivalent. | 4693 // Representations are bitwise equivalent. |
| 4692 ASSERT(out == locs()->in(0).reg()); | 4694 ASSERT(out == locs()->in(0).reg()); |
| 4693 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { | 4695 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { |
| 4694 const Register out = locs()->out(0).reg(); | 4696 const Register out = locs()->out(0).reg(); |
| 4695 // Representations are bitwise equivalent. | 4697 // Representations are bitwise equivalent. |
| 4696 ASSERT(out == locs()->in(0).reg()); | 4698 ASSERT(out == locs()->in(0).reg()); |
| 4697 if (CanDeoptimize()) { | 4699 if (CanDeoptimize()) { |
| 4698 Label* deopt = | 4700 Label* deopt = |
| 4699 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 4701 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 4700 __ BranchSignedLess(out, 0, deopt); | 4702 __ BranchSignedLess(out, Immediate(0), deopt); |
| 4701 } | 4703 } |
| 4702 } else if (from() == kUnboxedMint) { | 4704 } else if (from() == kUnboxedMint) { |
| 4703 UNREACHABLE(); | 4705 UNREACHABLE(); |
| 4704 } else if (to() == kUnboxedMint) { | 4706 } else if (to() == kUnboxedMint) { |
| 4705 ASSERT(from() == kUnboxedUint32 || from() == kUnboxedInt32); | 4707 ASSERT(from() == kUnboxedUint32 || from() == kUnboxedInt32); |
| 4706 UNREACHABLE(); | 4708 UNREACHABLE(); |
| 4707 } else { | 4709 } else { |
| 4708 UNREACHABLE(); | 4710 UNREACHABLE(); |
| 4709 } | 4711 } |
| 4710 } | 4712 } |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4917 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 4919 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 4918 #if defined(DEBUG) | 4920 #if defined(DEBUG) |
| 4919 __ LoadImmediate(S4, kInvalidObjectPointer); | 4921 __ LoadImmediate(S4, kInvalidObjectPointer); |
| 4920 __ LoadImmediate(S5, kInvalidObjectPointer); | 4922 __ LoadImmediate(S5, kInvalidObjectPointer); |
| 4921 #endif | 4923 #endif |
| 4922 } | 4924 } |
| 4923 | 4925 |
| 4924 } // namespace dart | 4926 } // namespace dart |
| 4925 | 4927 |
| 4926 #endif // defined TARGET_ARCH_MIPS | 4928 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |