| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 switch (class_id_) { | 1043 switch (class_id_) { |
| 1044 case kArrayCid: | 1044 case kArrayCid: |
| 1045 case kImmutableArrayCid: | 1045 case kImmutableArrayCid: |
| 1046 return CompileType::Dynamic(); | 1046 return CompileType::Dynamic(); |
| 1047 | 1047 |
| 1048 case kTypedDataFloat32ArrayCid: | 1048 case kTypedDataFloat32ArrayCid: |
| 1049 case kTypedDataFloat64ArrayCid: | 1049 case kTypedDataFloat64ArrayCid: |
| 1050 return CompileType::FromCid(kDoubleCid); | 1050 return CompileType::FromCid(kDoubleCid); |
| 1051 case kTypedDataFloat32x4ArrayCid: | 1051 case kTypedDataFloat32x4ArrayCid: |
| 1052 return CompileType::FromCid(kFloat32x4Cid); | 1052 return CompileType::FromCid(kFloat32x4Cid); |
| 1053 case kTypedDataUint32x4ArrayCid: |
| 1054 return CompileType::FromCid(kUint32x4Cid); |
| 1053 | 1055 |
| 1054 case kTypedDataInt8ArrayCid: | 1056 case kTypedDataInt8ArrayCid: |
| 1055 case kTypedDataUint8ArrayCid: | 1057 case kTypedDataUint8ArrayCid: |
| 1056 case kTypedDataUint8ClampedArrayCid: | 1058 case kTypedDataUint8ClampedArrayCid: |
| 1057 case kExternalTypedDataUint8ArrayCid: | 1059 case kExternalTypedDataUint8ArrayCid: |
| 1058 case kExternalTypedDataUint8ClampedArrayCid: | 1060 case kExternalTypedDataUint8ClampedArrayCid: |
| 1059 case kTypedDataInt16ArrayCid: | 1061 case kTypedDataInt16ArrayCid: |
| 1060 case kTypedDataUint16ArrayCid: | 1062 case kTypedDataUint16ArrayCid: |
| 1061 case kOneByteStringCid: | 1063 case kOneByteStringCid: |
| 1062 case kTwoByteStringCid: | 1064 case kTwoByteStringCid: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 case kTypedDataInt32ArrayCid: | 1096 case kTypedDataInt32ArrayCid: |
| 1095 case kTypedDataUint32ArrayCid: | 1097 case kTypedDataUint32ArrayCid: |
| 1096 // Instruction can deoptimize if we optimistically assumed that the result | 1098 // Instruction can deoptimize if we optimistically assumed that the result |
| 1097 // fits into Smi. | 1099 // fits into Smi. |
| 1098 return CanDeoptimize() ? kTagged : kUnboxedMint; | 1100 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 1099 case kTypedDataFloat32ArrayCid: | 1101 case kTypedDataFloat32ArrayCid: |
| 1100 case kTypedDataFloat64ArrayCid: | 1102 case kTypedDataFloat64ArrayCid: |
| 1101 return kUnboxedDouble; | 1103 return kUnboxedDouble; |
| 1102 case kTypedDataFloat32x4ArrayCid: | 1104 case kTypedDataFloat32x4ArrayCid: |
| 1103 return kUnboxedFloat32x4; | 1105 return kUnboxedFloat32x4; |
| 1106 case kTypedDataUint32x4ArrayCid: |
| 1107 return kUnboxedUint32x4; |
| 1104 default: | 1108 default: |
| 1105 UNIMPLEMENTED(); | 1109 UNIMPLEMENTED(); |
| 1106 return kTagged; | 1110 return kTagged; |
| 1107 } | 1111 } |
| 1108 } | 1112 } |
| 1109 | 1113 |
| 1110 | 1114 |
| 1111 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1115 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1112 const intptr_t kNumInputs = 2; | 1116 const intptr_t kNumInputs = 2; |
| 1113 const intptr_t kNumTemps = 0; | 1117 const intptr_t kNumTemps = 0; |
| 1114 LocationSummary* locs = | 1118 LocationSummary* locs = |
| 1115 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1119 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1116 locs->set_in(0, Location::RequiresRegister()); | 1120 locs->set_in(0, Location::RequiresRegister()); |
| 1117 if (CanBeImmediateIndex(index(), class_id())) { | 1121 if (CanBeImmediateIndex(index(), class_id())) { |
| 1118 // CanBeImmediateIndex must return false for unsafe smis. | 1122 // CanBeImmediateIndex must return false for unsafe smis. |
| 1119 locs->set_in(1, Location::Constant(index()->BoundConstant())); | 1123 locs->set_in(1, Location::Constant(index()->BoundConstant())); |
| 1120 } else { | 1124 } else { |
| 1121 // The index is either untagged (element size == 1) or a smi (for all | 1125 // The index is either untagged (element size == 1) or a smi (for all |
| 1122 // element sizes > 1). | 1126 // element sizes > 1). |
| 1123 locs->set_in(1, (index_scale() == 1) | 1127 locs->set_in(1, (index_scale() == 1) |
| 1124 ? Location::WritableRegister() | 1128 ? Location::WritableRegister() |
| 1125 : Location::RequiresRegister()); | 1129 : Location::RequiresRegister()); |
| 1126 } | 1130 } |
| 1127 if (representation() == kUnboxedDouble) { | 1131 if ((representation() == kUnboxedDouble) || |
| 1132 (representation() == kUnboxedFloat32x4) || |
| 1133 (representation() == kUnboxedUint32x4)) { |
| 1128 locs->set_out(Location::RequiresFpuRegister()); | 1134 locs->set_out(Location::RequiresFpuRegister()); |
| 1129 } else { | 1135 } else { |
| 1130 locs->set_out(Location::RequiresRegister()); | 1136 locs->set_out(Location::RequiresRegister()); |
| 1131 } | 1137 } |
| 1132 return locs; | 1138 return locs; |
| 1133 } | 1139 } |
| 1134 | 1140 |
| 1135 | 1141 |
| 1136 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1142 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1137 Register array = locs()->in(0).reg(); | 1143 Register array = locs()->in(0).reg(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1149 element_address = index.IsRegister() | 1155 element_address = index.IsRegister() |
| 1150 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1156 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1151 class_id(), index_scale(), array, index.reg()) | 1157 class_id(), index_scale(), array, index.reg()) |
| 1152 : FlowGraphCompiler::ElementAddressForIntIndex( | 1158 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1153 class_id(), index_scale(), array, | 1159 class_id(), index_scale(), array, |
| 1154 Smi::Cast(index.constant()).Value()); | 1160 Smi::Cast(index.constant()).Value()); |
| 1155 } | 1161 } |
| 1156 | 1162 |
| 1157 if ((representation() == kUnboxedDouble) || | 1163 if ((representation() == kUnboxedDouble) || |
| 1158 (representation() == kUnboxedMint) || | 1164 (representation() == kUnboxedMint) || |
| 1159 (representation() == kUnboxedFloat32x4)) { | 1165 (representation() == kUnboxedFloat32x4) || |
| 1166 (representation() == kUnboxedUint32x4)) { |
| 1160 XmmRegister result = locs()->out().fpu_reg(); | 1167 XmmRegister result = locs()->out().fpu_reg(); |
| 1161 if ((index_scale() == 1) && index.IsRegister()) { | 1168 if ((index_scale() == 1) && index.IsRegister()) { |
| 1162 __ SmiUntag(index.reg()); | 1169 __ SmiUntag(index.reg()); |
| 1163 } | 1170 } |
| 1164 switch (class_id()) { | 1171 switch (class_id()) { |
| 1165 case kTypedDataInt32ArrayCid: | 1172 case kTypedDataInt32ArrayCid: |
| 1166 __ movss(result, element_address); | 1173 __ movss(result, element_address); |
| 1167 __ pmovsxdq(result, result); | 1174 __ pmovsxdq(result, result); |
| 1168 break; | 1175 break; |
| 1169 case kTypedDataUint32ArrayCid: | 1176 case kTypedDataUint32ArrayCid: |
| 1170 __ xorpd(result, result); | 1177 __ xorpd(result, result); |
| 1171 __ movss(result, element_address); | 1178 __ movss(result, element_address); |
| 1172 break; | 1179 break; |
| 1173 case kTypedDataFloat32ArrayCid: | 1180 case kTypedDataFloat32ArrayCid: |
| 1174 // Load single precision float and promote to double. | 1181 // Load single precision float and promote to double. |
| 1175 __ movss(result, element_address); | 1182 __ movss(result, element_address); |
| 1176 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1183 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1177 break; | 1184 break; |
| 1178 case kTypedDataFloat64ArrayCid: | 1185 case kTypedDataFloat64ArrayCid: |
| 1179 __ movsd(result, element_address); | 1186 __ movsd(result, element_address); |
| 1180 break; | 1187 break; |
| 1188 case kTypedDataUint32x4ArrayCid: |
| 1181 case kTypedDataFloat32x4ArrayCid: | 1189 case kTypedDataFloat32x4ArrayCid: |
| 1182 __ movups(result, element_address); | 1190 __ movups(result, element_address); |
| 1183 break; | 1191 break; |
| 1184 } | 1192 } |
| 1185 return; | 1193 return; |
| 1186 } | 1194 } |
| 1187 | 1195 |
| 1188 Register result = locs()->out().reg(); | 1196 Register result = locs()->out().reg(); |
| 1189 if ((index_scale() == 1) && index.IsRegister()) { | 1197 if ((index_scale() == 1) && index.IsRegister()) { |
| 1190 __ SmiUntag(index.reg()); | 1198 __ SmiUntag(index.reg()); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 case kTypedDataUint16ArrayCid: | 1265 case kTypedDataUint16ArrayCid: |
| 1258 return kTagged; | 1266 return kTagged; |
| 1259 case kTypedDataInt32ArrayCid: | 1267 case kTypedDataInt32ArrayCid: |
| 1260 case kTypedDataUint32ArrayCid: | 1268 case kTypedDataUint32ArrayCid: |
| 1261 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1269 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 1262 case kTypedDataFloat32ArrayCid: | 1270 case kTypedDataFloat32ArrayCid: |
| 1263 case kTypedDataFloat64ArrayCid: | 1271 case kTypedDataFloat64ArrayCid: |
| 1264 return kUnboxedDouble; | 1272 return kUnboxedDouble; |
| 1265 case kTypedDataFloat32x4ArrayCid: | 1273 case kTypedDataFloat32x4ArrayCid: |
| 1266 return kUnboxedFloat32x4; | 1274 return kUnboxedFloat32x4; |
| 1275 case kTypedDataUint32x4ArrayCid: |
| 1276 return kUnboxedUint32x4; |
| 1267 default: | 1277 default: |
| 1268 UNIMPLEMENTED(); | 1278 UNIMPLEMENTED(); |
| 1269 return kTagged; | 1279 return kTagged; |
| 1270 } | 1280 } |
| 1271 } | 1281 } |
| 1272 | 1282 |
| 1273 | 1283 |
| 1274 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1284 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1275 const intptr_t kNumInputs = 3; | 1285 const intptr_t kNumInputs = 3; |
| 1276 const intptr_t kNumTemps = 0; | 1286 const intptr_t kNumTemps = 0; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 : Location::RequiresFpuRegister()); | 1327 : Location::RequiresFpuRegister()); |
| 1318 break; | 1328 break; |
| 1319 case kTypedDataFloat32ArrayCid: | 1329 case kTypedDataFloat32ArrayCid: |
| 1320 // Need temp register for float-to-double conversion. | 1330 // Need temp register for float-to-double conversion. |
| 1321 locs->AddTemp(Location::RequiresFpuRegister()); | 1331 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1322 // Fall through. | 1332 // Fall through. |
| 1323 case kTypedDataFloat64ArrayCid: | 1333 case kTypedDataFloat64ArrayCid: |
| 1324 // TODO(srdjan): Support Float64 constants. | 1334 // TODO(srdjan): Support Float64 constants. |
| 1325 locs->set_in(2, Location::RequiresFpuRegister()); | 1335 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1326 break; | 1336 break; |
| 1337 case kTypedDataUint32x4ArrayCid: |
| 1327 case kTypedDataFloat32x4ArrayCid: | 1338 case kTypedDataFloat32x4ArrayCid: |
| 1328 locs->set_in(2, Location::RequiresFpuRegister()); | 1339 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1329 break; | 1340 break; |
| 1330 default: | 1341 default: |
| 1331 UNREACHABLE(); | 1342 UNREACHABLE(); |
| 1332 return NULL; | 1343 return NULL; |
| 1333 } | 1344 } |
| 1334 return locs; | 1345 return locs; |
| 1335 } | 1346 } |
| 1336 | 1347 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1437 break; | 1448 break; |
| 1438 case kTypedDataFloat32ArrayCid: | 1449 case kTypedDataFloat32ArrayCid: |
| 1439 // Convert to single precision. | 1450 // Convert to single precision. |
| 1440 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1451 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1441 // Store. | 1452 // Store. |
| 1442 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1453 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1443 break; | 1454 break; |
| 1444 case kTypedDataFloat64ArrayCid: | 1455 case kTypedDataFloat64ArrayCid: |
| 1445 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1456 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1446 break; | 1457 break; |
| 1458 case kTypedDataUint32x4ArrayCid: |
| 1447 case kTypedDataFloat32x4ArrayCid: | 1459 case kTypedDataFloat32x4ArrayCid: |
| 1448 __ movups(element_address, locs()->in(2).fpu_reg()); | 1460 __ movups(element_address, locs()->in(2).fpu_reg()); |
| 1449 break; | 1461 break; |
| 1450 default: | 1462 default: |
| 1451 UNREACHABLE(); | 1463 UNREACHABLE(); |
| 1452 } | 1464 } |
| 1453 } | 1465 } |
| 1454 | 1466 |
| 1455 | 1467 |
| 1456 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1468 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1566 // without triggering a deoptimization. | 1578 // without triggering a deoptimization. |
| 1567 Label check_array, length_compared, no_fixed_length; | 1579 Label check_array, length_compared, no_fixed_length; |
| 1568 // If length is negative the length guard is either disabled or | 1580 // If length is negative the length guard is either disabled or |
| 1569 // has not been initialized, either way it is safe to skip the | 1581 // has not been initialized, either way it is safe to skip the |
| 1570 // length check. | 1582 // length check. |
| 1571 __ cmpl(field_length_operand, Immediate(Smi::RawValue(0))); | 1583 __ cmpl(field_length_operand, Immediate(Smi::RawValue(0))); |
| 1572 __ j(LESS, &skip_length_check); | 1584 __ j(LESS, &skip_length_check); |
| 1573 __ cmpl(value_cid_reg, Immediate(kNullCid)); | 1585 __ cmpl(value_cid_reg, Immediate(kNullCid)); |
| 1574 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1586 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1575 // Check for typed data array. | 1587 // Check for typed data array. |
| 1576 __ cmpl(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid)); | 1588 __ cmpl(value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid)); |
| 1577 // Not a typed array or a regular array. | 1589 // Not a typed array or a regular array. |
| 1578 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1590 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
| 1579 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); | 1591 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); |
| 1580 // Could still be a regular array. | 1592 // Could still be a regular array. |
| 1581 __ j(LESS, &check_array, Assembler::kNearJump); | 1593 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1582 __ pushl(value_cid_reg); | 1594 __ pushl(value_cid_reg); |
| 1583 __ movl(value_cid_reg, | 1595 __ movl(value_cid_reg, |
| 1584 FieldAddress(value_reg, TypedData::length_offset())); | 1596 FieldAddress(value_reg, TypedData::length_offset())); |
| 1585 __ cmpl(field_length_operand, value_cid_reg); | 1597 __ cmpl(field_length_operand, value_cid_reg); |
| 1586 __ popl(value_cid_reg); | 1598 __ popl(value_cid_reg); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1653 // At this point the field guard is being initialized for the first time. | 1665 // At this point the field guard is being initialized for the first time. |
| 1654 if (value_cid == kDynamicCid) { | 1666 if (value_cid == kDynamicCid) { |
| 1655 // Do not know value's class id. | 1667 // Do not know value's class id. |
| 1656 __ movl(field_cid_operand, value_cid_reg); | 1668 __ movl(field_cid_operand, value_cid_reg); |
| 1657 __ movl(field_nullability_operand, value_cid_reg); | 1669 __ movl(field_nullability_operand, value_cid_reg); |
| 1658 if (field_has_length) { | 1670 if (field_has_length) { |
| 1659 Label check_array, length_set, no_fixed_length; | 1671 Label check_array, length_set, no_fixed_length; |
| 1660 __ cmpl(value_cid_reg, Immediate(kNullCid)); | 1672 __ cmpl(value_cid_reg, Immediate(kNullCid)); |
| 1661 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1673 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1662 // Check for typed data array. | 1674 // Check for typed data array. |
| 1663 __ cmpl(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid)); | 1675 __ cmpl(value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid)); |
| 1664 // Not a typed array or a regular array. | 1676 // Not a typed array or a regular array. |
| 1665 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1677 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
| 1666 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); | 1678 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); |
| 1667 // Could still be a regular array. | 1679 // Could still be a regular array. |
| 1668 __ j(LESS, &check_array, Assembler::kNearJump); | 1680 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1669 // Destroy value_cid_reg (safe because we are finished with it). | 1681 // Destroy value_cid_reg (safe because we are finished with it). |
| 1670 __ movl(value_cid_reg, | 1682 __ movl(value_cid_reg, |
| 1671 FieldAddress(value_reg, TypedData::length_offset())); | 1683 FieldAddress(value_reg, TypedData::length_offset())); |
| 1672 __ movl(field_length_operand, value_cid_reg); | 1684 __ movl(field_length_operand, value_cid_reg); |
| 1673 // Updated field length typed data array. | 1685 // Updated field length typed data array. |
| (...skipping 3499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5173 PcDescriptors::kOther, | 5185 PcDescriptors::kOther, |
| 5174 locs()); | 5186 locs()); |
| 5175 __ Drop(2); // Discard type arguments and receiver. | 5187 __ Drop(2); // Discard type arguments and receiver. |
| 5176 } | 5188 } |
| 5177 | 5189 |
| 5178 } // namespace dart | 5190 } // namespace dart |
| 5179 | 5191 |
| 5180 #undef __ | 5192 #undef __ |
| 5181 | 5193 |
| 5182 #endif // defined TARGET_ARCH_IA32 | 5194 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |