| 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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 Label load_pointer; | 2162 Label load_pointer; |
| 2164 Label load_double; | 2163 Label load_double; |
| 2165 | 2164 |
| 2166 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); | 2165 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |
| 2167 | 2166 |
| 2168 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); | 2167 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |
| 2169 FieldAddress field_nullability_operand(result_reg, | 2168 FieldAddress field_nullability_operand(result_reg, |
| 2170 Field::is_nullable_offset()); | 2169 Field::is_nullable_offset()); |
| 2171 | 2170 |
| 2172 __ lw(temp, field_nullability_operand); | 2171 __ lw(temp, field_nullability_operand); |
| 2173 __ BranchEqual(temp, kNullCid, &load_pointer); | 2172 __ BranchEqual(temp, Immediate(kNullCid), &load_pointer); |
| 2174 | 2173 |
| 2175 __ lw(temp, field_cid_operand); | 2174 __ lw(temp, field_cid_operand); |
| 2176 __ BranchEqual(temp, kDoubleCid, &load_double); | 2175 __ BranchEqual(temp, Immediate(kDoubleCid), &load_double); |
| 2177 | 2176 |
| 2178 // Fall through. | 2177 // Fall through. |
| 2179 __ b(&load_pointer); | 2178 __ b(&load_pointer); |
| 2180 | 2179 |
| 2181 if (!compiler->is_optimizing()) { | 2180 if (!compiler->is_optimizing()) { |
| 2182 locs()->live_registers()->Add(locs()->in(0)); | 2181 locs()->live_registers()->Add(locs()->in(0)); |
| 2183 } | 2182 } |
| 2184 | 2183 |
| 2185 { | 2184 { |
| 2186 __ Bind(&load_double); | 2185 __ Bind(&load_double); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2265 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2264 // 'instantiator_reg' is the instantiator TypeArguments object (or null). |
| 2266 ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2265 ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
| 2267 !type_arguments().CanShareInstantiatorTypeArguments( | 2266 !type_arguments().CanShareInstantiatorTypeArguments( |
| 2268 instantiator_class())); | 2267 instantiator_class())); |
| 2269 // If the instantiator is null and if the type argument vector | 2268 // If the instantiator is null and if the type argument vector |
| 2270 // instantiated from null becomes a vector of dynamic, then use null as | 2269 // instantiated from null becomes a vector of dynamic, then use null as |
| 2271 // the type arguments. | 2270 // the type arguments. |
| 2272 Label type_arguments_instantiated; | 2271 Label type_arguments_instantiated; |
| 2273 const intptr_t len = type_arguments().Length(); | 2272 const intptr_t len = type_arguments().Length(); |
| 2274 if (type_arguments().IsRawInstantiatedRaw(len)) { | 2273 if (type_arguments().IsRawInstantiatedRaw(len)) { |
| 2275 __ BranchEqual(instantiator_reg, reinterpret_cast<int32_t>(Object::null()), | 2274 __ BranchEqual(instantiator_reg, Object::null_object(), |
| 2276 &type_arguments_instantiated); | 2275 &type_arguments_instantiated); |
| 2277 } | 2276 } |
| 2278 | 2277 |
| 2279 __ LoadObject(T2, type_arguments()); | 2278 __ LoadObject(T2, type_arguments()); |
| 2280 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); | 2279 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); |
| 2281 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); | 2280 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); |
| 2282 // The instantiations cache is initialized with Object::zero_array() and is | 2281 // The instantiations cache is initialized with Object::zero_array() and is |
| 2283 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2282 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
| 2284 Label loop, found, slow_case; | 2283 Label loop, found, slow_case; |
| 2285 __ Bind(&loop); | 2284 __ Bind(&loop); |
| 2286 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator. | 2285 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator. |
| 2287 __ beq(T1, T0, &found); | 2286 __ beq(T1, T0, &found); |
| 2288 __ BranchNotEqual(T1, Smi::RawValue(StubCode::kNoInstantiator), &loop); | 2287 __ BranchNotEqual( |
| 2288 T1, Immediate(Smi::RawValue(StubCode::kNoInstantiator)), &loop); |
| 2289 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize)); | 2289 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize)); |
| 2290 __ b(&slow_case); | 2290 __ b(&slow_case); |
| 2291 __ Bind(&found); | 2291 __ Bind(&found); |
| 2292 __ lw(T0, Address(T2, 1 * kWordSize)); // Cached instantiated args. | 2292 __ lw(T0, Address(T2, 1 * kWordSize)); // Cached instantiated args. |
| 2293 __ b(&type_arguments_instantiated); | 2293 __ b(&type_arguments_instantiated); |
| 2294 | 2294 |
| 2295 __ Bind(&slow_case); | 2295 __ Bind(&slow_case); |
| 2296 // Instantiate non-null type arguments. | 2296 // Instantiate non-null type arguments. |
| 2297 // A runtime call to instantiate the type arguments is required. | 2297 // A runtime call to instantiate the type arguments is required. |
| 2298 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 2298 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2611 __ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label()); | 2611 __ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label()); |
| 2612 if (compiler->CanOSRFunction() && in_loop()) { | 2612 if (compiler->CanOSRFunction() && in_loop()) { |
| 2613 Register temp = locs()->temp(0).reg(); | 2613 Register temp = locs()->temp(0).reg(); |
| 2614 // In unoptimized code check the usage counter to trigger OSR at loop | 2614 // In unoptimized code check the usage counter to trigger OSR at loop |
| 2615 // stack checks. Use progressively higher thresholds for more deeply | 2615 // stack checks. Use progressively higher thresholds for more deeply |
| 2616 // nested loops to attempt to hit outer loops with OSR when possible. | 2616 // nested loops to attempt to hit outer loops with OSR when possible. |
| 2617 __ LoadObject(temp, compiler->parsed_function().function()); | 2617 __ LoadObject(temp, compiler->parsed_function().function()); |
| 2618 intptr_t threshold = | 2618 intptr_t threshold = |
| 2619 FLAG_optimization_counter_threshold * (loop_depth() + 1); | 2619 FLAG_optimization_counter_threshold * (loop_depth() + 1); |
| 2620 __ lw(temp, FieldAddress(temp, Function::usage_counter_offset())); | 2620 __ lw(temp, FieldAddress(temp, Function::usage_counter_offset())); |
| 2621 __ BranchSignedGreaterEqual(temp, threshold, slow_path->osr_entry_label()); | 2621 __ BranchSignedGreaterEqual( |
| 2622 temp, Immediate(threshold), slow_path->osr_entry_label()); |
| 2622 } | 2623 } |
| 2623 if (compiler->ForceSlowPathForStackOverflow()) { | 2624 if (compiler->ForceSlowPathForStackOverflow()) { |
| 2624 __ b(slow_path->entry_label()); | 2625 __ b(slow_path->entry_label()); |
| 2625 } | 2626 } |
| 2626 __ Bind(slow_path->exit_label()); | 2627 __ Bind(slow_path->exit_label()); |
| 2627 } | 2628 } |
| 2628 | 2629 |
| 2629 | 2630 |
| 2630 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2631 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2631 BinarySmiOpInstr* shift_left) { | 2632 BinarySmiOpInstr* shift_left) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2667 const intptr_t left_int = Smi::Cast(obj).Value(); | 2668 const intptr_t left_int = Smi::Cast(obj).Value(); |
| 2668 if (left_int == 0) { | 2669 if (left_int == 0) { |
| 2669 __ bltz(right, deopt); | 2670 __ bltz(right, deopt); |
| 2670 __ mov(result, ZR); | 2671 __ mov(result, ZR); |
| 2671 return; | 2672 return; |
| 2672 } | 2673 } |
| 2673 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); | 2674 const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); |
| 2674 const bool right_needs_check = | 2675 const bool right_needs_check = |
| 2675 !RangeUtils::IsWithin(right_range, 0, max_right - 1); | 2676 !RangeUtils::IsWithin(right_range, 0, max_right - 1); |
| 2676 if (right_needs_check) { | 2677 if (right_needs_check) { |
| 2677 __ BranchUnsignedGreaterEqual( | 2678 const Immediate& max_right_imm = |
| 2678 right, reinterpret_cast<int32_t>(Smi::New(max_right)), deopt); | 2679 Immediate(reinterpret_cast<int32_t>(Smi::New(max_right))); |
| 2680 __ BranchUnsignedGreaterEqual(right, max_right_imm, deopt); |
| 2679 } | 2681 } |
| 2680 __ SmiUntag(TMP, right); | 2682 __ SmiUntag(TMP, right); |
| 2681 __ sllv(result, left, TMP); | 2683 __ sllv(result, left, TMP); |
| 2682 } | 2684 } |
| 2683 return; | 2685 return; |
| 2684 } | 2686 } |
| 2685 | 2687 |
| 2686 const bool right_needs_check = | 2688 const bool right_needs_check = |
| 2687 !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1)); | 2689 !RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1)); |
| 2688 if (!shift_left->can_overflow()) { | 2690 if (!shift_left->can_overflow()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2701 __ sra(TMP, right, kSmiTagSize); | 2703 __ sra(TMP, right, kSmiTagSize); |
| 2702 __ sllv(TMP, left, TMP); | 2704 __ sllv(TMP, left, TMP); |
| 2703 // result = right < kBits ? left << right : result. | 2705 // result = right < kBits ? left << right : result. |
| 2704 __ movn(result, TMP, CMPRES1); | 2706 __ movn(result, TMP, CMPRES1); |
| 2705 } else { | 2707 } else { |
| 2706 __ sra(TMP, right, kSmiTagSize); | 2708 __ sra(TMP, right, kSmiTagSize); |
| 2707 __ sllv(result, left, TMP); | 2709 __ sllv(result, left, TMP); |
| 2708 } | 2710 } |
| 2709 } else { | 2711 } else { |
| 2710 if (right_needs_check) { | 2712 if (right_needs_check) { |
| 2713 const Immediate& bits_imm = |
| 2714 Immediate(reinterpret_cast<int32_t>(Smi::New(Smi::kBits))); |
| 2711 ASSERT(shift_left->CanDeoptimize()); | 2715 ASSERT(shift_left->CanDeoptimize()); |
| 2712 __ BranchUnsignedGreaterEqual( | 2716 __ BranchUnsignedGreaterEqual(right, bits_imm, deopt); |
| 2713 right, reinterpret_cast<int32_t>(Smi::New(Smi::kBits)), deopt); | |
| 2714 } | 2717 } |
| 2715 // Left is not a constant. | 2718 // Left is not a constant. |
| 2716 Register temp = locs.temp(0).reg(); | 2719 Register temp = locs.temp(0).reg(); |
| 2717 // Check if count too large for handling it inlined. | 2720 // Check if count too large for handling it inlined. |
| 2718 __ SmiUntag(temp, right); | 2721 __ SmiUntag(temp, right); |
| 2719 // Overflow test (preserve left, right, and temp); | 2722 // Overflow test (preserve left, right, and temp); |
| 2720 __ sllv(CMPRES1, left, temp); | 2723 __ sllv(CMPRES1, left, temp); |
| 2721 __ srav(CMPRES1, CMPRES1, temp); | 2724 __ srav(CMPRES1, CMPRES1, temp); |
| 2722 __ bne(CMPRES1, left, deopt); // Overflow. | 2725 __ bne(CMPRES1, left, deopt); // Overflow. |
| 2723 // Shift for result now we know there is no overflow. | 2726 // Shift for result now we know there is no overflow. |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2945 // Handle divide by zero in runtime. | 2948 // Handle divide by zero in runtime. |
| 2946 __ beq(right, ZR, deopt); | 2949 __ beq(right, ZR, deopt); |
| 2947 } | 2950 } |
| 2948 Register temp = locs()->temp(0).reg(); | 2951 Register temp = locs()->temp(0).reg(); |
| 2949 __ SmiUntag(temp, left); | 2952 __ SmiUntag(temp, left); |
| 2950 __ SmiUntag(TMP, right); | 2953 __ SmiUntag(TMP, right); |
| 2951 __ div(temp, TMP); | 2954 __ div(temp, TMP); |
| 2952 __ mflo(result); | 2955 __ mflo(result); |
| 2953 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 2956 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 2954 // case we cannot tag the result. | 2957 // case we cannot tag the result. |
| 2955 __ BranchEqual(result, 0x40000000, deopt); | 2958 __ BranchEqual(result, Immediate(0x40000000), deopt); |
| 2956 __ SmiTag(result); | 2959 __ SmiTag(result); |
| 2957 break; | 2960 break; |
| 2958 } | 2961 } |
| 2959 case Token::kMOD: { | 2962 case Token::kMOD: { |
| 2960 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 2963 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
| 2961 // Handle divide by zero in runtime. | 2964 // Handle divide by zero in runtime. |
| 2962 __ beq(right, ZR, deopt); | 2965 __ beq(right, ZR, deopt); |
| 2963 } | 2966 } |
| 2964 Register temp = locs()->temp(0).reg(); | 2967 Register temp = locs()->temp(0).reg(); |
| 2965 __ SmiUntag(temp, left); | 2968 __ SmiUntag(temp, left); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2998 Register temp = locs()->temp(0).reg(); | 3001 Register temp = locs()->temp(0).reg(); |
| 2999 if (CanDeoptimize()) { | 3002 if (CanDeoptimize()) { |
| 3000 __ bltz(right, deopt); | 3003 __ bltz(right, deopt); |
| 3001 } | 3004 } |
| 3002 __ SmiUntag(temp, right); | 3005 __ SmiUntag(temp, right); |
| 3003 // sra operation masks the count to 5 bits. | 3006 // sra operation masks the count to 5 bits. |
| 3004 const intptr_t kCountLimit = 0x1F; | 3007 const intptr_t kCountLimit = 0x1F; |
| 3005 if ((right_range == NULL) || | 3008 if ((right_range == NULL) || |
| 3006 !right_range->OnlyLessThanOrEqualTo(kCountLimit)) { | 3009 !right_range->OnlyLessThanOrEqualTo(kCountLimit)) { |
| 3007 Label ok; | 3010 Label ok; |
| 3008 __ BranchSignedLessEqual(temp, kCountLimit, &ok); | 3011 __ BranchSignedLessEqual(temp, Immediate(kCountLimit), &ok); |
| 3009 __ LoadImmediate(temp, kCountLimit); | 3012 __ LoadImmediate(temp, kCountLimit); |
| 3010 __ Bind(&ok); | 3013 __ Bind(&ok); |
| 3011 } | 3014 } |
| 3012 | 3015 |
| 3013 __ SmiUntag(CMPRES1, left); | 3016 __ SmiUntag(CMPRES1, left); |
| 3014 __ srav(result, CMPRES1, temp); | 3017 __ srav(result, CMPRES1, temp); |
| 3015 __ SmiTag(result); | 3018 __ SmiTag(result); |
| 3016 break; | 3019 break; |
| 3017 } | 3020 } |
| 3018 case Token::kDIV: { | 3021 case Token::kDIV: { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3118 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); | 3121 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); |
| 3119 } else if (value_cid == kSmiCid) { | 3122 } else if (value_cid == kSmiCid) { |
| 3120 __ SmiUntag(TMP, value); | 3123 __ SmiUntag(TMP, value); |
| 3121 __ mtc1(TMP, STMP1); | 3124 __ mtc1(TMP, STMP1); |
| 3122 __ cvtdw(result, STMP1); | 3125 __ cvtdw(result, STMP1); |
| 3123 } else { | 3126 } else { |
| 3124 Label* deopt = compiler->AddDeoptStub(deopt_id_, | 3127 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 3125 ICData::kDeoptBinaryDoubleOp); | 3128 ICData::kDeoptBinaryDoubleOp); |
| 3126 if (value_type->is_nullable() && | 3129 if (value_type->is_nullable() && |
| 3127 (value_type->ToNullableCid() == kDoubleCid)) { | 3130 (value_type->ToNullableCid() == kDoubleCid)) { |
| 3128 __ BranchEqual(value, reinterpret_cast<int32_t>(Object::null()), deopt); | 3131 __ BranchEqual(value, Object::null_object(), deopt); |
| 3129 // It must be double now. | 3132 // It must be double now. |
| 3130 __ LoadDFromOffset(result, value, | 3133 __ LoadDFromOffset(result, value, |
| 3131 Double::value_offset() - kHeapObjectTag); | 3134 Double::value_offset() - kHeapObjectTag); |
| 3132 } else { | 3135 } else { |
| 3133 Label is_smi, done; | 3136 Label is_smi, done; |
| 3134 | 3137 |
| 3135 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); | 3138 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
| 3136 __ beq(CMPRES1, ZR, &is_smi); | 3139 __ beq(CMPRES1, ZR, &is_smi); |
| 3137 __ LoadClassId(CMPRES1, value); | 3140 __ LoadClassId(CMPRES1, value); |
| 3138 __ BranchNotEqual(CMPRES1, kDoubleCid, deopt); | 3141 __ BranchNotEqual(CMPRES1, Immediate(kDoubleCid), deopt); |
| 3139 __ LoadDFromOffset(result, value, | 3142 __ LoadDFromOffset(result, value, |
| 3140 Double::value_offset() - kHeapObjectTag); | 3143 Double::value_offset() - kHeapObjectTag); |
| 3141 __ b(&done); | 3144 __ b(&done); |
| 3142 __ Bind(&is_smi); | 3145 __ Bind(&is_smi); |
| 3143 __ SmiUntag(TMP, value); | 3146 __ SmiUntag(TMP, value); |
| 3144 __ mtc1(TMP, STMP1); | 3147 __ mtc1(TMP, STMP1); |
| 3145 __ cvtdw(result, STMP1); | 3148 __ cvtdw(result, STMP1); |
| 3146 __ Bind(&done); | 3149 __ Bind(&done); |
| 3147 } | 3150 } |
| 3148 } | 3151 } |
| (...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4198 // Handle divide by zero in runtime. | 4201 // Handle divide by zero in runtime. |
| 4199 __ beq(right, ZR, deopt); | 4202 __ beq(right, ZR, deopt); |
| 4200 } | 4203 } |
| 4201 __ SmiUntag(temp, left); | 4204 __ SmiUntag(temp, left); |
| 4202 __ SmiUntag(TMP, right); | 4205 __ SmiUntag(TMP, right); |
| 4203 __ div(temp, TMP); | 4206 __ div(temp, TMP); |
| 4204 __ mflo(result_div); | 4207 __ mflo(result_div); |
| 4205 __ mfhi(result_mod); | 4208 __ mfhi(result_mod); |
| 4206 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 4209 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 4207 // case we cannot tag the result. | 4210 // case we cannot tag the result. |
| 4208 __ BranchEqual(result_div, 0x40000000, deopt); | 4211 __ BranchEqual(result_div, Immediate(0x40000000), deopt); |
| 4209 // res = left % right; | 4212 // res = left % right; |
| 4210 // if (res < 0) { | 4213 // if (res < 0) { |
| 4211 // if (right < 0) { | 4214 // if (right < 0) { |
| 4212 // res = res - right; | 4215 // res = res - right; |
| 4213 // } else { | 4216 // } else { |
| 4214 // res = res + right; | 4217 // res = res + right; |
| 4215 // } | 4218 // } |
| 4216 // } | 4219 // } |
| 4217 Label done; | 4220 Label done; |
| 4218 __ bgez(result_mod, &done); | 4221 __ bgez(result_mod, &done); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4312 } | 4315 } |
| 4313 return summary; | 4316 return summary; |
| 4314 } | 4317 } |
| 4315 | 4318 |
| 4316 | 4319 |
| 4317 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4320 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4318 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 4321 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 4319 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 4322 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 4320 if (IsNullCheck()) { | 4323 if (IsNullCheck()) { |
| 4321 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 4324 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| 4322 __ BranchEqual(locs()->in(0).reg(), | 4325 __ BranchEqual(locs()->in(0).reg(), Object::null_object(), deopt); |
| 4323 reinterpret_cast<int32_t>(Object::null()), deopt); | |
| 4324 return; | 4326 return; |
| 4325 } | 4327 } |
| 4326 | 4328 |
| 4327 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | 4329 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
| 4328 (unary_checks().NumberOfChecks() > 1)); | 4330 (unary_checks().NumberOfChecks() > 1)); |
| 4329 Register value = locs()->in(0).reg(); | 4331 Register value = locs()->in(0).reg(); |
| 4330 Register temp = locs()->temp(0).reg(); | 4332 Register temp = locs()->temp(0).reg(); |
| 4331 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 4333 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| 4332 Label is_ok; | 4334 Label is_ok; |
| 4333 intptr_t cix = 0; | 4335 intptr_t cix = 0; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4402 LocationSummary* summary = new(isolate) LocationSummary( | 4404 LocationSummary* summary = new(isolate) LocationSummary( |
| 4403 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4405 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4404 summary->set_in(0, Location::RequiresRegister()); | 4406 summary->set_in(0, Location::RequiresRegister()); |
| 4405 return summary; | 4407 return summary; |
| 4406 } | 4408 } |
| 4407 | 4409 |
| 4408 | 4410 |
| 4409 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4411 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4410 Register value = locs()->in(0).reg(); | 4412 Register value = locs()->in(0).reg(); |
| 4411 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | 4413 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); |
| 4412 __ BranchNotEqual(value, Smi::RawValue(cid_), deopt); | 4414 __ BranchNotEqual(value, Immediate(Smi::RawValue(cid_)), deopt); |
| 4413 } | 4415 } |
| 4414 | 4416 |
| 4415 | 4417 |
| 4416 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 4418 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, |
| 4417 bool opt) const { | 4419 bool opt) const { |
| 4418 const intptr_t kNumInputs = 2; | 4420 const intptr_t kNumInputs = 2; |
| 4419 const intptr_t kNumTemps = 0; | 4421 const intptr_t kNumTemps = 0; |
| 4420 LocationSummary* locs = new(isolate) LocationSummary( | 4422 LocationSummary* locs = new(isolate) LocationSummary( |
| 4421 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4423 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4422 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 4424 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4439 // Unconditionally deoptimize for constant bounds checks because they | 4441 // Unconditionally deoptimize for constant bounds checks because they |
| 4440 // only occur only when index is out-of-bounds. | 4442 // only occur only when index is out-of-bounds. |
| 4441 __ b(deopt); | 4443 __ b(deopt); |
| 4442 return; | 4444 return; |
| 4443 } | 4445 } |
| 4444 | 4446 |
| 4445 if (index_loc.IsConstant()) { | 4447 if (index_loc.IsConstant()) { |
| 4446 Register length = length_loc.reg(); | 4448 Register length = length_loc.reg(); |
| 4447 const Smi& index = Smi::Cast(index_loc.constant()); | 4449 const Smi& index = Smi::Cast(index_loc.constant()); |
| 4448 __ BranchUnsignedLessEqual( | 4450 __ BranchUnsignedLessEqual( |
| 4449 length, reinterpret_cast<int32_t>(index.raw()), deopt); | 4451 length, Immediate(reinterpret_cast<int32_t>(index.raw())), deopt); |
| 4450 } else if (length_loc.IsConstant()) { | 4452 } else if (length_loc.IsConstant()) { |
| 4451 const Smi& length = Smi::Cast(length_loc.constant()); | 4453 const Smi& length = Smi::Cast(length_loc.constant()); |
| 4452 Register index = index_loc.reg(); | 4454 Register index = index_loc.reg(); |
| 4453 __ BranchUnsignedGreaterEqual( | 4455 __ BranchUnsignedGreaterEqual( |
| 4454 index, reinterpret_cast<int32_t>(length.raw()), deopt); | 4456 index, Immediate(reinterpret_cast<int32_t>(length.raw())), deopt); |
| 4455 } else { | 4457 } else { |
| 4456 Register length = length_loc.reg(); | 4458 Register length = length_loc.reg(); |
| 4457 Register index = index_loc.reg(); | 4459 Register index = index_loc.reg(); |
| 4458 __ BranchUnsignedGreaterEqual(index, length, deopt); | 4460 __ BranchUnsignedGreaterEqual(index, length, deopt); |
| 4459 } | 4461 } |
| 4460 } | 4462 } |
| 4461 | 4463 |
| 4462 | 4464 |
| 4463 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, | 4465 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, |
| 4464 bool opt) const { | 4466 bool opt) const { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4647 if (value_cid == kSmiCid) { | 4649 if (value_cid == kSmiCid) { |
| 4648 __ SmiUntag(out, value); | 4650 __ SmiUntag(out, value); |
| 4649 } else if (value_cid == kMintCid) { | 4651 } else if (value_cid == kMintCid) { |
| 4650 LoadInt32FromMint(compiler, value, out, out_of_range); | 4652 LoadInt32FromMint(compiler, value, out, out_of_range); |
| 4651 } else { | 4653 } else { |
| 4652 Label done; | 4654 Label done; |
| 4653 __ SmiUntag(out, value); | 4655 __ SmiUntag(out, value); |
| 4654 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); | 4656 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
| 4655 __ beq(CMPRES1, ZR, &done); | 4657 __ beq(CMPRES1, ZR, &done); |
| 4656 __ LoadClassId(CMPRES1, value); | 4658 __ LoadClassId(CMPRES1, value); |
| 4657 __ BranchNotEqual(CMPRES1, kMintCid, deopt); | 4659 __ BranchNotEqual(CMPRES1, Immediate(kMintCid), deopt); |
| 4658 LoadInt32FromMint(compiler, value, out, out_of_range); | 4660 LoadInt32FromMint(compiler, value, out, out_of_range); |
| 4659 __ Bind(&done); | 4661 __ Bind(&done); |
| 4660 } | 4662 } |
| 4661 } | 4663 } |
| 4662 | 4664 |
| 4663 | 4665 |
| 4664 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 4666 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
| 4665 bool opt) const { | 4667 bool opt) const { |
| 4666 const intptr_t kNumInputs = 1; | 4668 const intptr_t kNumInputs = 1; |
| 4667 const intptr_t kNumTemps = 0; | 4669 const intptr_t kNumTemps = 0; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4686 const Register out = locs()->out(0).reg(); | 4688 const Register out = locs()->out(0).reg(); |
| 4687 // Representations are bitwise equivalent. | 4689 // Representations are bitwise equivalent. |
| 4688 ASSERT(out == locs()->in(0).reg()); | 4690 ASSERT(out == locs()->in(0).reg()); |
| 4689 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { | 4691 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { |
| 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 if (CanDeoptimize()) { | 4695 if (CanDeoptimize()) { |
| 4694 Label* deopt = | 4696 Label* deopt = |
| 4695 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 4697 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 4696 __ BranchSignedLess(out, 0, deopt); | 4698 __ BranchSignedLess(out, Immediate(0), deopt); |
| 4697 } | 4699 } |
| 4698 } else if (from() == kUnboxedMint) { | 4700 } else if (from() == kUnboxedMint) { |
| 4699 UNREACHABLE(); | 4701 UNREACHABLE(); |
| 4700 } else if (to() == kUnboxedMint) { | 4702 } else if (to() == kUnboxedMint) { |
| 4701 ASSERT(from() == kUnboxedUint32 || from() == kUnboxedInt32); | 4703 ASSERT(from() == kUnboxedUint32 || from() == kUnboxedInt32); |
| 4702 UNREACHABLE(); | 4704 UNREACHABLE(); |
| 4703 } else { | 4705 } else { |
| 4704 UNREACHABLE(); | 4706 UNREACHABLE(); |
| 4705 } | 4707 } |
| 4706 } | 4708 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4926 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 4928 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 4927 #if defined(DEBUG) | 4929 #if defined(DEBUG) |
| 4928 __ LoadImmediate(S4, kInvalidObjectPointer); | 4930 __ LoadImmediate(S4, kInvalidObjectPointer); |
| 4929 __ LoadImmediate(S5, kInvalidObjectPointer); | 4931 __ LoadImmediate(S5, kInvalidObjectPointer); |
| 4930 #endif | 4932 #endif |
| 4931 } | 4933 } |
| 4932 | 4934 |
| 4933 } // namespace dart | 4935 } // namespace dart |
| 4934 | 4936 |
| 4935 #endif // defined TARGET_ARCH_MIPS | 4937 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |