| 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 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 switch (class_id_) { | 1032 switch (class_id_) { |
| 1033 case kArrayCid: | 1033 case kArrayCid: |
| 1034 case kImmutableArrayCid: | 1034 case kImmutableArrayCid: |
| 1035 return CompileType::Dynamic(); | 1035 return CompileType::Dynamic(); |
| 1036 | 1036 |
| 1037 case kTypedDataFloat32ArrayCid: | 1037 case kTypedDataFloat32ArrayCid: |
| 1038 case kTypedDataFloat64ArrayCid: | 1038 case kTypedDataFloat64ArrayCid: |
| 1039 return CompileType::FromCid(kDoubleCid); | 1039 return CompileType::FromCid(kDoubleCid); |
| 1040 case kTypedDataFloat32x4ArrayCid: | 1040 case kTypedDataFloat32x4ArrayCid: |
| 1041 return CompileType::FromCid(kFloat32x4Cid); | 1041 return CompileType::FromCid(kFloat32x4Cid); |
| 1042 case kTypedDataUint32x4ArrayCid: |
| 1043 return CompileType::FromCid(kUint32x4Cid); |
| 1042 | 1044 |
| 1043 case kTypedDataInt8ArrayCid: | 1045 case kTypedDataInt8ArrayCid: |
| 1044 case kTypedDataUint8ArrayCid: | 1046 case kTypedDataUint8ArrayCid: |
| 1045 case kTypedDataUint8ClampedArrayCid: | 1047 case kTypedDataUint8ClampedArrayCid: |
| 1046 case kExternalTypedDataUint8ArrayCid: | 1048 case kExternalTypedDataUint8ArrayCid: |
| 1047 case kExternalTypedDataUint8ClampedArrayCid: | 1049 case kExternalTypedDataUint8ClampedArrayCid: |
| 1048 case kTypedDataInt16ArrayCid: | 1050 case kTypedDataInt16ArrayCid: |
| 1049 case kTypedDataUint16ArrayCid: | 1051 case kTypedDataUint16ArrayCid: |
| 1050 case kOneByteStringCid: | 1052 case kOneByteStringCid: |
| 1051 case kTwoByteStringCid: | 1053 case kTwoByteStringCid: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1081 case kTwoByteStringCid: | 1083 case kTwoByteStringCid: |
| 1082 return kTagged; | 1084 return kTagged; |
| 1083 case kTypedDataInt32ArrayCid: | 1085 case kTypedDataInt32ArrayCid: |
| 1084 case kTypedDataUint32ArrayCid: | 1086 case kTypedDataUint32ArrayCid: |
| 1085 // Instruction can deoptimize if we optimistically assumed that the result | 1087 // Instruction can deoptimize if we optimistically assumed that the result |
| 1086 // fits into Smi. | 1088 // fits into Smi. |
| 1087 return CanDeoptimize() ? kTagged : kUnboxedMint; | 1089 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 1088 case kTypedDataFloat32ArrayCid: | 1090 case kTypedDataFloat32ArrayCid: |
| 1089 case kTypedDataFloat64ArrayCid: | 1091 case kTypedDataFloat64ArrayCid: |
| 1090 return kUnboxedDouble; | 1092 return kUnboxedDouble; |
| 1093 case kTypedDataUint32x4ArrayCid: |
| 1094 return kUnboxedUint32x4; |
| 1091 case kTypedDataFloat32x4ArrayCid: | 1095 case kTypedDataFloat32x4ArrayCid: |
| 1092 return kUnboxedFloat32x4; | 1096 return kUnboxedFloat32x4; |
| 1093 default: | 1097 default: |
| 1094 UNIMPLEMENTED(); | 1098 UNIMPLEMENTED(); |
| 1095 return kTagged; | 1099 return kTagged; |
| 1096 } | 1100 } |
| 1097 } | 1101 } |
| 1098 | 1102 |
| 1099 | 1103 |
| 1100 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1104 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1101 const intptr_t kNumInputs = 2; | 1105 const intptr_t kNumInputs = 2; |
| 1102 const intptr_t kNumTemps = 0; | 1106 const intptr_t kNumTemps = 0; |
| 1103 LocationSummary* locs = | 1107 LocationSummary* locs = |
| 1104 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1108 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1105 locs->set_in(0, Location::RequiresRegister()); | 1109 locs->set_in(0, Location::RequiresRegister()); |
| 1106 // The smi index is either untagged (element size == 1), or it is left smi | 1110 // The smi index is either untagged (element size == 1), or it is left smi |
| 1107 // tagged (for all element sizes > 1). | 1111 // tagged (for all element sizes > 1). |
| 1108 // TODO(regis): Revisit and see if the index can be immediate. | 1112 // TODO(regis): Revisit and see if the index can be immediate. |
| 1109 locs->set_in(1, Location::WritableRegister()); | 1113 locs->set_in(1, Location::WritableRegister()); |
| 1110 if (representation() == kUnboxedDouble) { | 1114 if ((representation() == kUnboxedDouble) || |
| 1115 (representation() == kUnboxedFloat32x4) || |
| 1116 (representation() == kUnboxedUint32x4)) { |
| 1111 locs->set_out(Location::RequiresFpuRegister()); | 1117 locs->set_out(Location::RequiresFpuRegister()); |
| 1112 } else { | 1118 } else { |
| 1113 locs->set_out(Location::RequiresRegister()); | 1119 locs->set_out(Location::RequiresRegister()); |
| 1114 } | 1120 } |
| 1115 return locs; | 1121 return locs; |
| 1116 } | 1122 } |
| 1117 | 1123 |
| 1118 | 1124 |
| 1119 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1125 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1120 __ TraceSimMsg("LoadIndexedInstr"); | 1126 __ TraceSimMsg("LoadIndexedInstr"); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 ASSERT(this->array()->definition()->representation() == kTagged); | 1165 ASSERT(this->array()->definition()->representation() == kTagged); |
| 1160 // If the data offset doesn't fit into the 18 bits we get for the addressing | 1166 // If the data offset doesn't fit into the 18 bits we get for the addressing |
| 1161 // mode, then we must load the offset into a register and add it to the | 1167 // mode, then we must load the offset into a register and add it to the |
| 1162 // index. | 1168 // index. |
| 1163 element_address = Address(index.reg(), | 1169 element_address = Address(index.reg(), |
| 1164 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 1170 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 1165 } | 1171 } |
| 1166 | 1172 |
| 1167 if ((representation() == kUnboxedDouble) || | 1173 if ((representation() == kUnboxedDouble) || |
| 1168 (representation() == kUnboxedMint) || | 1174 (representation() == kUnboxedMint) || |
| 1169 (representation() == kUnboxedFloat32x4)) { | 1175 (representation() == kUnboxedFloat32x4) || |
| 1176 (representation() == kUnboxedUint32x4)) { |
| 1170 DRegister result = locs()->out().fpu_reg(); | 1177 DRegister result = locs()->out().fpu_reg(); |
| 1171 switch (class_id()) { | 1178 switch (class_id()) { |
| 1172 case kTypedDataInt32ArrayCid: | 1179 case kTypedDataInt32ArrayCid: |
| 1173 UNIMPLEMENTED(); | 1180 UNIMPLEMENTED(); |
| 1174 break; | 1181 break; |
| 1175 case kTypedDataUint32ArrayCid: | 1182 case kTypedDataUint32ArrayCid: |
| 1176 UNIMPLEMENTED(); | 1183 UNIMPLEMENTED(); |
| 1177 break; | 1184 break; |
| 1178 case kTypedDataFloat32ArrayCid: | 1185 case kTypedDataFloat32ArrayCid: |
| 1179 // Load single precision float and promote to double. | 1186 // Load single precision float and promote to double. |
| 1180 __ lwc1(STMP1, element_address); | 1187 __ lwc1(STMP1, element_address); |
| 1181 __ cvtds(result, STMP1); | 1188 __ cvtds(result, STMP1); |
| 1182 break; | 1189 break; |
| 1183 case kTypedDataFloat64ArrayCid: | 1190 case kTypedDataFloat64ArrayCid: |
| 1184 __ LoadDFromOffset(result, index.reg(), | 1191 __ LoadDFromOffset(result, index.reg(), |
| 1185 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 1192 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 1186 break; | 1193 break; |
| 1194 case kTypedDataUint32x4ArrayCid: |
| 1187 case kTypedDataFloat32x4ArrayCid: | 1195 case kTypedDataFloat32x4ArrayCid: |
| 1188 UNIMPLEMENTED(); | 1196 UNIMPLEMENTED(); |
| 1189 break; | 1197 break; |
| 1190 } | 1198 } |
| 1191 return; | 1199 return; |
| 1192 } | 1200 } |
| 1193 | 1201 |
| 1194 Register result = locs()->out().reg(); | 1202 Register result = locs()->out().reg(); |
| 1195 switch (class_id()) { | 1203 switch (class_id()) { |
| 1196 case kTypedDataInt8ArrayCid: | 1204 case kTypedDataInt8ArrayCid: |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 case kTypedDataUint16ArrayCid: | 1268 case kTypedDataUint16ArrayCid: |
| 1261 return kTagged; | 1269 return kTagged; |
| 1262 case kTypedDataInt32ArrayCid: | 1270 case kTypedDataInt32ArrayCid: |
| 1263 case kTypedDataUint32ArrayCid: | 1271 case kTypedDataUint32ArrayCid: |
| 1264 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1272 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 1265 case kTypedDataFloat32ArrayCid: | 1273 case kTypedDataFloat32ArrayCid: |
| 1266 case kTypedDataFloat64ArrayCid: | 1274 case kTypedDataFloat64ArrayCid: |
| 1267 return kUnboxedDouble; | 1275 return kUnboxedDouble; |
| 1268 case kTypedDataFloat32x4ArrayCid: | 1276 case kTypedDataFloat32x4ArrayCid: |
| 1269 return kUnboxedFloat32x4; | 1277 return kUnboxedFloat32x4; |
| 1278 case kTypedDataUint32x4ArrayCid: |
| 1279 return kUnboxedUint32x4; |
| 1270 default: | 1280 default: |
| 1271 UNIMPLEMENTED(); | 1281 UNIMPLEMENTED(); |
| 1272 return kTagged; | 1282 return kTagged; |
| 1273 } | 1283 } |
| 1274 } | 1284 } |
| 1275 | 1285 |
| 1276 | 1286 |
| 1277 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1287 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1278 const intptr_t kNumInputs = 3; | 1288 const intptr_t kNumInputs = 3; |
| 1279 const intptr_t kNumTemps = 0; | 1289 const intptr_t kNumTemps = 0; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1301 case kTypedDataInt32ArrayCid: | 1311 case kTypedDataInt32ArrayCid: |
| 1302 case kTypedDataUint32ArrayCid: | 1312 case kTypedDataUint32ArrayCid: |
| 1303 locs->set_in(2, Location::WritableRegister()); | 1313 locs->set_in(2, Location::WritableRegister()); |
| 1304 break; | 1314 break; |
| 1305 case kTypedDataFloat32ArrayCid: | 1315 case kTypedDataFloat32ArrayCid: |
| 1306 // TODO(regis): Verify. | 1316 // TODO(regis): Verify. |
| 1307 // Need temp register for float-to-double conversion. | 1317 // Need temp register for float-to-double conversion. |
| 1308 locs->AddTemp(Location::RequiresFpuRegister()); | 1318 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1309 // Fall through. | 1319 // Fall through. |
| 1310 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. | 1320 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. |
| 1321 case kTypedDataUint32x4ArrayCid: |
| 1311 case kTypedDataFloat32x4ArrayCid: | 1322 case kTypedDataFloat32x4ArrayCid: |
| 1312 locs->set_in(2, Location::RequiresFpuRegister()); | 1323 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1313 break; | 1324 break; |
| 1314 default: | 1325 default: |
| 1315 UNREACHABLE(); | 1326 UNREACHABLE(); |
| 1316 return NULL; | 1327 return NULL; |
| 1317 } | 1328 } |
| 1318 return locs; | 1329 return locs; |
| 1319 } | 1330 } |
| 1320 | 1331 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1440 case kTypedDataFloat32ArrayCid: | 1451 case kTypedDataFloat32ArrayCid: |
| 1441 // Convert to single precision. | 1452 // Convert to single precision. |
| 1442 __ cvtsd(STMP1, locs()->in(2).fpu_reg()); | 1453 __ cvtsd(STMP1, locs()->in(2).fpu_reg()); |
| 1443 // Store. | 1454 // Store. |
| 1444 __ swc1(STMP1, element_address); | 1455 __ swc1(STMP1, element_address); |
| 1445 break; | 1456 break; |
| 1446 case kTypedDataFloat64ArrayCid: | 1457 case kTypedDataFloat64ArrayCid: |
| 1447 __ StoreDToOffset(locs()->in(2).fpu_reg(), index.reg(), | 1458 __ StoreDToOffset(locs()->in(2).fpu_reg(), index.reg(), |
| 1448 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 1459 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 1449 break; | 1460 break; |
| 1461 case kTypedDataUint32x4ArrayCid: |
| 1450 case kTypedDataFloat32x4ArrayCid: | 1462 case kTypedDataFloat32x4ArrayCid: |
| 1451 UNIMPLEMENTED(); | 1463 UNIMPLEMENTED(); |
| 1452 break; | 1464 break; |
| 1453 default: | 1465 default: |
| 1454 UNREACHABLE(); | 1466 UNREACHABLE(); |
| 1455 } | 1467 } |
| 1456 } | 1468 } |
| 1457 | 1469 |
| 1458 | 1470 |
| 1459 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1471 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1567 // list length here, without this check the list length could change | 1579 // list length here, without this check the list length could change |
| 1568 // without triggering a deoptimization. | 1580 // without triggering a deoptimization. |
| 1569 Label check_array, length_compared, no_fixed_length; | 1581 Label check_array, length_compared, no_fixed_length; |
| 1570 // If length is negative the length guard is either disabled or | 1582 // If length is negative the length guard is either disabled or |
| 1571 // has not been initialized, either way it is safe to skip the | 1583 // has not been initialized, either way it is safe to skip the |
| 1572 // length check. | 1584 // length check. |
| 1573 __ lw(CMPRES1, field_length_operand); | 1585 __ lw(CMPRES1, field_length_operand); |
| 1574 __ BranchSignedLess(CMPRES1, 0, &skip_length_check); | 1586 __ BranchSignedLess(CMPRES1, 0, &skip_length_check); |
| 1575 __ BranchEqual(value_cid_reg, kNullCid, &no_fixed_length); | 1587 __ BranchEqual(value_cid_reg, kNullCid, &no_fixed_length); |
| 1576 // Check for typed data array. | 1588 // Check for typed data array. |
| 1577 __ BranchSignedGreater(value_cid_reg, kTypedDataFloat32x4ArrayCid, | 1589 __ BranchSignedGreater(value_cid_reg, kTypedDataUint32x4ArrayCid, |
| 1578 &no_fixed_length); | 1590 &no_fixed_length); |
| 1579 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid, | 1591 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid, |
| 1580 &check_array); | 1592 &check_array); |
| 1581 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); | 1593 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); |
| 1582 __ lw(CMPRES1, field_length_operand); | 1594 __ lw(CMPRES1, field_length_operand); |
| 1583 __ subu(CMPRES1, TMP, CMPRES1); | 1595 __ subu(CMPRES1, TMP, CMPRES1); |
| 1584 __ b(&length_compared); | 1596 __ b(&length_compared); |
| 1585 // Check for regular array. | 1597 // Check for regular array. |
| 1586 __ Bind(&check_array); | 1598 __ Bind(&check_array); |
| 1587 __ BranchSignedGreater(value_cid_reg, kImmutableArrayCid, | 1599 __ BranchSignedGreater(value_cid_reg, kImmutableArrayCid, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1643 __ lw(CMPRES1, field_cid_operand); | 1655 __ lw(CMPRES1, field_cid_operand); |
| 1644 __ BranchNotEqual(CMPRES1, kIllegalCid, fail); | 1656 __ BranchNotEqual(CMPRES1, kIllegalCid, fail); |
| 1645 | 1657 |
| 1646 if (value_cid == kDynamicCid) { | 1658 if (value_cid == kDynamicCid) { |
| 1647 __ sw(value_cid_reg, field_cid_operand); | 1659 __ sw(value_cid_reg, field_cid_operand); |
| 1648 __ sw(value_cid_reg, field_nullability_operand); | 1660 __ sw(value_cid_reg, field_nullability_operand); |
| 1649 if (field_has_length) { | 1661 if (field_has_length) { |
| 1650 Label check_array, length_set, no_fixed_length; | 1662 Label check_array, length_set, no_fixed_length; |
| 1651 __ BranchEqual(value_cid_reg, kNullCid, &no_fixed_length); | 1663 __ BranchEqual(value_cid_reg, kNullCid, &no_fixed_length); |
| 1652 // Check for typed data array. | 1664 // Check for typed data array. |
| 1653 __ BranchSignedGreater(value_cid_reg, kTypedDataFloat32x4ArrayCid, | 1665 __ BranchSignedGreater(value_cid_reg, kTypedDataUint32x4ArrayCid, |
| 1654 &no_fixed_length); | 1666 &no_fixed_length); |
| 1655 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid, | 1667 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid, |
| 1656 &check_array); | 1668 &check_array); |
| 1657 // Destroy value_cid_reg (safe because we are finished with it). | 1669 // Destroy value_cid_reg (safe because we are finished with it). |
| 1658 __ lw(value_cid_reg, | 1670 __ lw(value_cid_reg, |
| 1659 FieldAddress(value_reg, TypedData::length_offset())); | 1671 FieldAddress(value_reg, TypedData::length_offset())); |
| 1660 __ sw(value_cid_reg, field_length_operand); | 1672 __ sw(value_cid_reg, field_length_operand); |
| 1661 // Updated field length typed data array. | 1673 // Updated field length typed data array. |
| 1662 __ b(&length_set); | 1674 __ b(&length_set); |
| 1663 // Check for regular array. | 1675 // Check for regular array. |
| (...skipping 2413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4077 compiler->GenerateCall(token_pos(), | 4089 compiler->GenerateCall(token_pos(), |
| 4078 &label, | 4090 &label, |
| 4079 PcDescriptors::kOther, | 4091 PcDescriptors::kOther, |
| 4080 locs()); | 4092 locs()); |
| 4081 __ Drop(2); // Discard type arguments and receiver. | 4093 __ Drop(2); // Discard type arguments and receiver. |
| 4082 } | 4094 } |
| 4083 | 4095 |
| 4084 } // namespace dart | 4096 } // namespace dart |
| 4085 | 4097 |
| 4086 #endif // defined TARGET_ARCH_MIPS | 4098 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |