| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 switch (class_id_) { | 972 switch (class_id_) { |
| 973 case kArrayCid: | 973 case kArrayCid: |
| 974 case kImmutableArrayCid: | 974 case kImmutableArrayCid: |
| 975 return CompileType::Dynamic(); | 975 return CompileType::Dynamic(); |
| 976 | 976 |
| 977 case kTypedDataFloat32ArrayCid: | 977 case kTypedDataFloat32ArrayCid: |
| 978 case kTypedDataFloat64ArrayCid: | 978 case kTypedDataFloat64ArrayCid: |
| 979 return CompileType::FromCid(kDoubleCid); | 979 return CompileType::FromCid(kDoubleCid); |
| 980 case kTypedDataFloat32x4ArrayCid: | 980 case kTypedDataFloat32x4ArrayCid: |
| 981 return CompileType::FromCid(kFloat32x4Cid); | 981 return CompileType::FromCid(kFloat32x4Cid); |
| 982 case kTypedDataUint32x4ArrayCid: |
| 983 return CompileType::FromCid(kUint32x4Cid); |
| 982 | 984 |
| 983 case kTypedDataInt8ArrayCid: | 985 case kTypedDataInt8ArrayCid: |
| 984 case kTypedDataUint8ArrayCid: | 986 case kTypedDataUint8ArrayCid: |
| 985 case kTypedDataUint8ClampedArrayCid: | 987 case kTypedDataUint8ClampedArrayCid: |
| 986 case kExternalTypedDataUint8ArrayCid: | 988 case kExternalTypedDataUint8ArrayCid: |
| 987 case kExternalTypedDataUint8ClampedArrayCid: | 989 case kExternalTypedDataUint8ClampedArrayCid: |
| 988 case kTypedDataInt16ArrayCid: | 990 case kTypedDataInt16ArrayCid: |
| 989 case kTypedDataUint16ArrayCid: | 991 case kTypedDataUint16ArrayCid: |
| 990 case kOneByteStringCid: | 992 case kOneByteStringCid: |
| 991 case kTwoByteStringCid: | 993 case kTwoByteStringCid: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1021 case kTwoByteStringCid: | 1023 case kTwoByteStringCid: |
| 1022 return kTagged; | 1024 return kTagged; |
| 1023 case kTypedDataInt32ArrayCid: | 1025 case kTypedDataInt32ArrayCid: |
| 1024 case kTypedDataUint32ArrayCid: | 1026 case kTypedDataUint32ArrayCid: |
| 1025 // Instruction can deoptimize if we optimistically assumed that the result | 1027 // Instruction can deoptimize if we optimistically assumed that the result |
| 1026 // fits into Smi. | 1028 // fits into Smi. |
| 1027 return CanDeoptimize() ? kTagged : kUnboxedMint; | 1029 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 1028 case kTypedDataFloat32ArrayCid: | 1030 case kTypedDataFloat32ArrayCid: |
| 1029 case kTypedDataFloat64ArrayCid: | 1031 case kTypedDataFloat64ArrayCid: |
| 1030 return kUnboxedDouble; | 1032 return kUnboxedDouble; |
| 1033 case kTypedDataUint32x4ArrayCid: |
| 1034 return kUnboxedUint32x4; |
| 1031 case kTypedDataFloat32x4ArrayCid: | 1035 case kTypedDataFloat32x4ArrayCid: |
| 1032 return kUnboxedFloat32x4; | 1036 return kUnboxedFloat32x4; |
| 1033 default: | 1037 default: |
| 1034 UNREACHABLE(); | 1038 UNREACHABLE(); |
| 1035 return kTagged; | 1039 return kTagged; |
| 1036 } | 1040 } |
| 1037 } | 1041 } |
| 1038 | 1042 |
| 1039 | 1043 |
| 1040 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1044 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1041 const intptr_t kNumInputs = 2; | 1045 const intptr_t kNumInputs = 2; |
| 1042 const intptr_t kNumTemps = 0; | 1046 const intptr_t kNumTemps = 0; |
| 1043 LocationSummary* locs = | 1047 LocationSummary* locs = |
| 1044 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1048 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1045 locs->set_in(0, Location::RequiresRegister()); | 1049 locs->set_in(0, Location::RequiresRegister()); |
| 1046 // The smi index is either untagged (element size == 1), or it is left smi | 1050 // The smi index is either untagged (element size == 1), or it is left smi |
| 1047 // tagged (for all element sizes > 1). | 1051 // tagged (for all element sizes > 1). |
| 1048 // TODO(regis): Revisit and see if the index can be immediate. | 1052 // TODO(regis): Revisit and see if the index can be immediate. |
| 1049 locs->set_in(1, Location::WritableRegister()); | 1053 locs->set_in(1, Location::WritableRegister()); |
| 1050 if (representation() == kUnboxedDouble) { | 1054 if ((representation() == kUnboxedDouble) || |
| 1055 (representation() == kUnboxedFloat32x4) || |
| 1056 (representation() == kUnboxedUint32x4)) { |
| 1051 locs->set_out(Location::RequiresFpuRegister()); | 1057 locs->set_out(Location::RequiresFpuRegister()); |
| 1052 } else { | 1058 } else { |
| 1053 locs->set_out(Location::RequiresRegister()); | 1059 locs->set_out(Location::RequiresRegister()); |
| 1054 } | 1060 } |
| 1055 return locs; | 1061 return locs; |
| 1056 } | 1062 } |
| 1057 | 1063 |
| 1058 | 1064 |
| 1059 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1065 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1060 Register array = locs()->in(0).reg(); | 1066 Register array = locs()->in(0).reg(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 | 1098 |
| 1093 if (!IsExternal()) { | 1099 if (!IsExternal()) { |
| 1094 ASSERT(this->array()->definition()->representation() == kTagged); | 1100 ASSERT(this->array()->definition()->representation() == kTagged); |
| 1095 __ AddImmediate(index.reg(), | 1101 __ AddImmediate(index.reg(), |
| 1096 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 1102 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 1097 } | 1103 } |
| 1098 element_address = Address(array, index.reg(), LSL, 0); | 1104 element_address = Address(array, index.reg(), LSL, 0); |
| 1099 | 1105 |
| 1100 if ((representation() == kUnboxedDouble) || | 1106 if ((representation() == kUnboxedDouble) || |
| 1101 (representation() == kUnboxedMint) || | 1107 (representation() == kUnboxedMint) || |
| 1102 (representation() == kUnboxedFloat32x4)) { | 1108 (representation() == kUnboxedFloat32x4) || |
| 1109 (representation() == kUnboxedUint32x4)) { |
| 1103 QRegister result = locs()->out().fpu_reg(); | 1110 QRegister result = locs()->out().fpu_reg(); |
| 1104 DRegister dresult0 = EvenDRegisterOf(result); | 1111 DRegister dresult0 = EvenDRegisterOf(result); |
| 1105 DRegister dresult1 = OddDRegisterOf(result); | 1112 DRegister dresult1 = OddDRegisterOf(result); |
| 1106 switch (class_id()) { | 1113 switch (class_id()) { |
| 1107 case kTypedDataInt32ArrayCid: | 1114 case kTypedDataInt32ArrayCid: |
| 1108 UNIMPLEMENTED(); | 1115 UNIMPLEMENTED(); |
| 1109 break; | 1116 break; |
| 1110 case kTypedDataUint32ArrayCid: | 1117 case kTypedDataUint32ArrayCid: |
| 1111 UNIMPLEMENTED(); | 1118 UNIMPLEMENTED(); |
| 1112 break; | 1119 break; |
| 1113 case kTypedDataFloat32ArrayCid: | 1120 case kTypedDataFloat32ArrayCid: |
| 1114 // Load single precision float and promote to double. | 1121 // Load single precision float and promote to double. |
| 1115 // vldrs does not support indexed addressing. | 1122 // vldrs does not support indexed addressing. |
| 1116 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1123 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1117 element_address = Address(index.reg(), 0); | 1124 element_address = Address(index.reg(), 0); |
| 1118 __ vldrs(STMP, element_address); | 1125 __ vldrs(STMP, element_address); |
| 1119 __ vcvtds(dresult0, STMP); | 1126 __ vcvtds(dresult0, STMP); |
| 1120 break; | 1127 break; |
| 1121 case kTypedDataFloat64ArrayCid: | 1128 case kTypedDataFloat64ArrayCid: |
| 1122 // vldrd does not support indexed addressing. | 1129 // vldrd does not support indexed addressing. |
| 1123 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1130 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1124 element_address = Address(index.reg(), 0); | 1131 element_address = Address(index.reg(), 0); |
| 1125 __ vldrd(dresult0, element_address); | 1132 __ vldrd(dresult0, element_address); |
| 1126 break; | 1133 break; |
| 1134 case kTypedDataUint32x4ArrayCid: |
| 1127 case kTypedDataFloat32x4ArrayCid: | 1135 case kTypedDataFloat32x4ArrayCid: |
| 1128 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1136 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1129 __ LoadDFromOffset(dresult0, index.reg(), 0); | 1137 __ LoadDFromOffset(dresult0, index.reg(), 0); |
| 1130 __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize); | 1138 __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize); |
| 1131 break; | 1139 break; |
| 1132 } | 1140 } |
| 1133 return; | 1141 return; |
| 1134 } | 1142 } |
| 1135 | 1143 |
| 1136 Register result = locs()->out().reg(); | 1144 Register result = locs()->out().reg(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 case kTypedDataUint16ArrayCid: | 1210 case kTypedDataUint16ArrayCid: |
| 1203 return kTagged; | 1211 return kTagged; |
| 1204 case kTypedDataInt32ArrayCid: | 1212 case kTypedDataInt32ArrayCid: |
| 1205 case kTypedDataUint32ArrayCid: | 1213 case kTypedDataUint32ArrayCid: |
| 1206 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1214 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 1207 case kTypedDataFloat32ArrayCid: | 1215 case kTypedDataFloat32ArrayCid: |
| 1208 case kTypedDataFloat64ArrayCid: | 1216 case kTypedDataFloat64ArrayCid: |
| 1209 return kUnboxedDouble; | 1217 return kUnboxedDouble; |
| 1210 case kTypedDataFloat32x4ArrayCid: | 1218 case kTypedDataFloat32x4ArrayCid: |
| 1211 return kUnboxedFloat32x4; | 1219 return kUnboxedFloat32x4; |
| 1220 case kTypedDataUint32x4ArrayCid: |
| 1221 return kUnboxedUint32x4; |
| 1212 default: | 1222 default: |
| 1213 UNREACHABLE(); | 1223 UNREACHABLE(); |
| 1214 return kTagged; | 1224 return kTagged; |
| 1215 } | 1225 } |
| 1216 } | 1226 } |
| 1217 | 1227 |
| 1218 | 1228 |
| 1219 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1229 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1220 const intptr_t kNumInputs = 3; | 1230 const intptr_t kNumInputs = 3; |
| 1221 const intptr_t kNumTemps = 0; | 1231 const intptr_t kNumTemps = 0; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1239 case kTypedDataUint8ClampedArrayCid: | 1249 case kTypedDataUint8ClampedArrayCid: |
| 1240 case kOneByteStringCid: | 1250 case kOneByteStringCid: |
| 1241 case kTypedDataInt16ArrayCid: | 1251 case kTypedDataInt16ArrayCid: |
| 1242 case kTypedDataUint16ArrayCid: | 1252 case kTypedDataUint16ArrayCid: |
| 1243 case kTypedDataInt32ArrayCid: | 1253 case kTypedDataInt32ArrayCid: |
| 1244 case kTypedDataUint32ArrayCid: | 1254 case kTypedDataUint32ArrayCid: |
| 1245 locs->set_in(2, Location::WritableRegister()); | 1255 locs->set_in(2, Location::WritableRegister()); |
| 1246 break; | 1256 break; |
| 1247 case kTypedDataFloat32ArrayCid: | 1257 case kTypedDataFloat32ArrayCid: |
| 1248 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. | 1258 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. |
| 1259 case kTypedDataUint32x4ArrayCid: |
| 1249 case kTypedDataFloat32x4ArrayCid: | 1260 case kTypedDataFloat32x4ArrayCid: |
| 1250 locs->set_in(2, Location::RequiresFpuRegister()); | 1261 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1251 break; | 1262 break; |
| 1252 default: | 1263 default: |
| 1253 UNREACHABLE(); | 1264 UNREACHABLE(); |
| 1254 return NULL; | 1265 return NULL; |
| 1255 } | 1266 } |
| 1256 return locs; | 1267 return locs; |
| 1257 } | 1268 } |
| 1258 | 1269 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1390 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1380 __ StoreSToOffset(STMP, index.reg(), 0); | 1391 __ StoreSToOffset(STMP, index.reg(), 0); |
| 1381 break; | 1392 break; |
| 1382 } | 1393 } |
| 1383 case kTypedDataFloat64ArrayCid: { | 1394 case kTypedDataFloat64ArrayCid: { |
| 1384 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); | 1395 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); |
| 1385 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1396 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1386 __ StoreDToOffset(in2, index.reg(), 0); | 1397 __ StoreDToOffset(in2, index.reg(), 0); |
| 1387 break; | 1398 break; |
| 1388 } | 1399 } |
| 1400 case kTypedDataUint32x4ArrayCid: |
| 1389 case kTypedDataFloat32x4ArrayCid: { | 1401 case kTypedDataFloat32x4ArrayCid: { |
| 1390 QRegister in = locs()->in(2).fpu_reg(); | 1402 QRegister in = locs()->in(2).fpu_reg(); |
| 1391 DRegister din0 = EvenDRegisterOf(in); | 1403 DRegister din0 = EvenDRegisterOf(in); |
| 1392 DRegister din1 = OddDRegisterOf(in); | 1404 DRegister din1 = OddDRegisterOf(in); |
| 1393 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1405 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1394 __ StoreDToOffset(din0, index.reg(), 0); | 1406 __ StoreDToOffset(din0, index.reg(), 0); |
| 1395 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); | 1407 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); |
| 1396 break; | 1408 break; |
| 1397 } | 1409 } |
| 1398 default: | 1410 default: |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 Label check_array, length_compared, no_fixed_length; | 1516 Label check_array, length_compared, no_fixed_length; |
| 1505 // If length is negative the length guard is either disabled or | 1517 // If length is negative the length guard is either disabled or |
| 1506 // has not been initialized, either way it is safe to skip the | 1518 // has not been initialized, either way it is safe to skip the |
| 1507 // length check. | 1519 // length check. |
| 1508 __ ldr(IP, field_length_operand); | 1520 __ ldr(IP, field_length_operand); |
| 1509 __ CompareImmediate(IP, 0); | 1521 __ CompareImmediate(IP, 0); |
| 1510 __ b(&skip_length_check, LT); | 1522 __ b(&skip_length_check, LT); |
| 1511 __ CompareImmediate(value_cid_reg, kNullCid); | 1523 __ CompareImmediate(value_cid_reg, kNullCid); |
| 1512 __ b(&no_fixed_length, EQ); | 1524 __ b(&no_fixed_length, EQ); |
| 1513 // Check for typed data array. | 1525 // Check for typed data array. |
| 1514 __ CompareImmediate(value_cid_reg, kTypedDataFloat32x4ArrayCid); | 1526 __ CompareImmediate(value_cid_reg, kTypedDataUint32x4ArrayCid); |
| 1515 __ b(&no_fixed_length, GT); | 1527 __ b(&no_fixed_length, GT); |
| 1516 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 1528 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); |
| 1517 // Could still be a regular array. | 1529 // Could still be a regular array. |
| 1518 __ b(&check_array, LT); | 1530 __ b(&check_array, LT); |
| 1519 __ ldr(temp_reg, | 1531 __ ldr(temp_reg, |
| 1520 FieldAddress(value_reg, TypedData::length_offset())); | 1532 FieldAddress(value_reg, TypedData::length_offset())); |
| 1521 __ ldr(IP, field_length_operand); | 1533 __ ldr(IP, field_length_operand); |
| 1522 __ cmp(temp_reg, ShifterOperand(IP)); | 1534 __ cmp(temp_reg, ShifterOperand(IP)); |
| 1523 __ b(&length_compared); | 1535 __ b(&length_compared); |
| 1524 // Check for regular array. | 1536 // Check for regular array. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 __ b(fail, NE); | 1596 __ b(fail, NE); |
| 1585 | 1597 |
| 1586 if (value_cid == kDynamicCid) { | 1598 if (value_cid == kDynamicCid) { |
| 1587 __ str(value_cid_reg, field_cid_operand); | 1599 __ str(value_cid_reg, field_cid_operand); |
| 1588 __ str(value_cid_reg, field_nullability_operand); | 1600 __ str(value_cid_reg, field_nullability_operand); |
| 1589 if (field_has_length) { | 1601 if (field_has_length) { |
| 1590 Label check_array, length_set, no_fixed_length; | 1602 Label check_array, length_set, no_fixed_length; |
| 1591 __ CompareImmediate(value_cid_reg, kNullCid); | 1603 __ CompareImmediate(value_cid_reg, kNullCid); |
| 1592 __ b(&no_fixed_length, EQ); | 1604 __ b(&no_fixed_length, EQ); |
| 1593 // Check for typed data array. | 1605 // Check for typed data array. |
| 1594 __ CompareImmediate(value_cid_reg, kTypedDataFloat32x4ArrayCid); | 1606 __ CompareImmediate(value_cid_reg, kTypedDataUint32x4ArrayCid); |
| 1595 __ b(&no_fixed_length, GT); | 1607 __ b(&no_fixed_length, GT); |
| 1596 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 1608 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); |
| 1597 // Could still be a regular array. | 1609 // Could still be a regular array. |
| 1598 __ b(&check_array, LT); | 1610 __ b(&check_array, LT); |
| 1599 // Destroy value_cid_reg (safe because we are finished with it). | 1611 // Destroy value_cid_reg (safe because we are finished with it). |
| 1600 __ ldr(value_cid_reg, | 1612 __ ldr(value_cid_reg, |
| 1601 FieldAddress(value_reg, TypedData::length_offset())); | 1613 FieldAddress(value_reg, TypedData::length_offset())); |
| 1602 __ str(value_cid_reg, field_length_operand); | 1614 __ str(value_cid_reg, field_length_operand); |
| 1603 __ b(&length_set); // Updated field length typed data array. | 1615 __ b(&length_set); // Updated field length typed data array. |
| 1604 // Check for regular array. | 1616 // Check for regular array. |
| (...skipping 3080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4685 compiler->GenerateCall(token_pos(), | 4697 compiler->GenerateCall(token_pos(), |
| 4686 &label, | 4698 &label, |
| 4687 PcDescriptors::kOther, | 4699 PcDescriptors::kOther, |
| 4688 locs()); | 4700 locs()); |
| 4689 __ Drop(2); // Discard type arguments and receiver. | 4701 __ Drop(2); // Discard type arguments and receiver. |
| 4690 } | 4702 } |
| 4691 | 4703 |
| 4692 } // namespace dart | 4704 } // namespace dart |
| 4693 | 4705 |
| 4694 #endif // defined TARGET_ARCH_ARM | 4706 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |