| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 switch (class_id_) { | 1028 switch (class_id_) { |
| 1029 case kArrayCid: | 1029 case kArrayCid: |
| 1030 case kImmutableArrayCid: | 1030 case kImmutableArrayCid: |
| 1031 return CompileType::Dynamic(); | 1031 return CompileType::Dynamic(); |
| 1032 | 1032 |
| 1033 case kTypedDataFloat32ArrayCid: | 1033 case kTypedDataFloat32ArrayCid: |
| 1034 case kTypedDataFloat64ArrayCid: | 1034 case kTypedDataFloat64ArrayCid: |
| 1035 return CompileType::FromCid(kDoubleCid); | 1035 return CompileType::FromCid(kDoubleCid); |
| 1036 case kTypedDataFloat32x4ArrayCid: | 1036 case kTypedDataFloat32x4ArrayCid: |
| 1037 return CompileType::FromCid(kFloat32x4Cid); | 1037 return CompileType::FromCid(kFloat32x4Cid); |
| 1038 case kTypedDataUint32x4ArrayCid: |
| 1039 return CompileType::FromCid(kUint32x4Cid); |
| 1038 | 1040 |
| 1039 case kTypedDataInt8ArrayCid: | 1041 case kTypedDataInt8ArrayCid: |
| 1040 case kTypedDataUint8ArrayCid: | 1042 case kTypedDataUint8ArrayCid: |
| 1041 case kTypedDataUint8ClampedArrayCid: | 1043 case kTypedDataUint8ClampedArrayCid: |
| 1042 case kExternalTypedDataUint8ArrayCid: | 1044 case kExternalTypedDataUint8ArrayCid: |
| 1043 case kExternalTypedDataUint8ClampedArrayCid: | 1045 case kExternalTypedDataUint8ClampedArrayCid: |
| 1044 case kTypedDataInt16ArrayCid: | 1046 case kTypedDataInt16ArrayCid: |
| 1045 case kTypedDataUint16ArrayCid: | 1047 case kTypedDataUint16ArrayCid: |
| 1046 case kOneByteStringCid: | 1048 case kOneByteStringCid: |
| 1047 case kTwoByteStringCid: | 1049 case kTwoByteStringCid: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1068 case kTypedDataInt16ArrayCid: | 1070 case kTypedDataInt16ArrayCid: |
| 1069 case kTypedDataUint16ArrayCid: | 1071 case kTypedDataUint16ArrayCid: |
| 1070 case kOneByteStringCid: | 1072 case kOneByteStringCid: |
| 1071 case kTwoByteStringCid: | 1073 case kTwoByteStringCid: |
| 1072 case kTypedDataInt32ArrayCid: | 1074 case kTypedDataInt32ArrayCid: |
| 1073 case kTypedDataUint32ArrayCid: | 1075 case kTypedDataUint32ArrayCid: |
| 1074 return kTagged; | 1076 return kTagged; |
| 1075 case kTypedDataFloat32ArrayCid: | 1077 case kTypedDataFloat32ArrayCid: |
| 1076 case kTypedDataFloat64ArrayCid: | 1078 case kTypedDataFloat64ArrayCid: |
| 1077 return kUnboxedDouble; | 1079 return kUnboxedDouble; |
| 1080 case kTypedDataUint32x4ArrayCid: |
| 1081 return kUnboxedUint32x4; |
| 1078 case kTypedDataFloat32x4ArrayCid: | 1082 case kTypedDataFloat32x4ArrayCid: |
| 1079 return kUnboxedFloat32x4; | 1083 return kUnboxedFloat32x4; |
| 1080 default: | 1084 default: |
| 1081 UNIMPLEMENTED(); | 1085 UNIMPLEMENTED(); |
| 1082 return kTagged; | 1086 return kTagged; |
| 1083 } | 1087 } |
| 1084 } | 1088 } |
| 1085 | 1089 |
| 1086 | 1090 |
| 1087 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1091 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1088 const intptr_t kNumInputs = 2; | 1092 const intptr_t kNumInputs = 2; |
| 1089 const intptr_t kNumTemps = 0; | 1093 const intptr_t kNumTemps = 0; |
| 1090 LocationSummary* locs = | 1094 LocationSummary* locs = |
| 1091 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1095 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1092 locs->set_in(0, Location::RequiresRegister()); | 1096 locs->set_in(0, Location::RequiresRegister()); |
| 1093 // The smi index is either untagged (element size == 1), or it is left smi | 1097 // The smi index is either untagged (element size == 1), or it is left smi |
| 1094 // tagged (for all element sizes > 1). | 1098 // tagged (for all element sizes > 1). |
| 1095 if (index_scale() == 1) { | 1099 if (index_scale() == 1) { |
| 1096 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1100 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 1097 ? Location::Constant( | 1101 ? Location::Constant( |
| 1098 index()->definition()->AsConstant()->value()) | 1102 index()->definition()->AsConstant()->value()) |
| 1099 : Location::WritableRegister()); | 1103 : Location::WritableRegister()); |
| 1100 } else { | 1104 } else { |
| 1101 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1105 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 1102 ? Location::Constant( | 1106 ? Location::Constant( |
| 1103 index()->definition()->AsConstant()->value()) | 1107 index()->definition()->AsConstant()->value()) |
| 1104 : Location::RequiresRegister()); | 1108 : Location::RequiresRegister()); |
| 1105 } | 1109 } |
| 1106 if (representation() == kUnboxedDouble) { | 1110 if ((representation() == kUnboxedDouble) || |
| 1111 (representation() == kUnboxedFloat32x4) || |
| 1112 (representation() == kUnboxedUint32x4)) { |
| 1107 locs->set_out(Location::RequiresFpuRegister()); | 1113 locs->set_out(Location::RequiresFpuRegister()); |
| 1108 } else { | 1114 } else { |
| 1109 locs->set_out(Location::RequiresRegister()); | 1115 locs->set_out(Location::RequiresRegister()); |
| 1110 } | 1116 } |
| 1111 return locs; | 1117 return locs; |
| 1112 } | 1118 } |
| 1113 | 1119 |
| 1114 | 1120 |
| 1115 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1121 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1116 Register array = locs()->in(0).reg(); | 1122 Register array = locs()->in(0).reg(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1130 ASSERT(this->array()->definition()->representation() == kTagged); | 1136 ASSERT(this->array()->definition()->representation() == kTagged); |
| 1131 element_address = index.IsRegister() | 1137 element_address = index.IsRegister() |
| 1132 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1138 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1133 class_id(), index_scale(), array, index.reg()) | 1139 class_id(), index_scale(), array, index.reg()) |
| 1134 : FlowGraphCompiler::ElementAddressForIntIndex( | 1140 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1135 class_id(), index_scale(), array, | 1141 class_id(), index_scale(), array, |
| 1136 Smi::Cast(index.constant()).Value()); | 1142 Smi::Cast(index.constant()).Value()); |
| 1137 } | 1143 } |
| 1138 | 1144 |
| 1139 if ((representation() == kUnboxedDouble) || | 1145 if ((representation() == kUnboxedDouble) || |
| 1140 (representation() == kUnboxedFloat32x4)) { | 1146 (representation() == kUnboxedFloat32x4) || |
| 1147 (representation() == kUnboxedUint32x4)) { |
| 1141 if ((index_scale() == 1) && index.IsRegister()) { | 1148 if ((index_scale() == 1) && index.IsRegister()) { |
| 1142 __ SmiUntag(index.reg()); | 1149 __ SmiUntag(index.reg()); |
| 1143 } | 1150 } |
| 1144 | 1151 |
| 1145 XmmRegister result = locs()->out().fpu_reg(); | 1152 XmmRegister result = locs()->out().fpu_reg(); |
| 1146 if (class_id() == kTypedDataFloat32ArrayCid) { | 1153 if (class_id() == kTypedDataFloat32ArrayCid) { |
| 1147 // Load single precision float. | 1154 // Load single precision float. |
| 1148 __ movss(result, element_address); | 1155 __ movss(result, element_address); |
| 1149 // Promote to double. | 1156 // Promote to double. |
| 1150 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1157 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1151 } else if (class_id() == kTypedDataFloat64ArrayCid) { | 1158 } else if (class_id() == kTypedDataFloat64ArrayCid) { |
| 1152 __ movsd(result, element_address); | 1159 __ movsd(result, element_address); |
| 1153 } else { | 1160 } else { |
| 1154 ASSERT(class_id() == kTypedDataFloat32x4ArrayCid); | 1161 ASSERT((class_id() == kTypedDataUint32x4ArrayCid) || |
| 1162 (class_id() == kTypedDataFloat32x4ArrayCid)); |
| 1155 __ movups(result, element_address); | 1163 __ movups(result, element_address); |
| 1156 } | 1164 } |
| 1157 return; | 1165 return; |
| 1158 } | 1166 } |
| 1159 | 1167 |
| 1160 if ((index_scale() == 1) && index.IsRegister()) { | 1168 if ((index_scale() == 1) && index.IsRegister()) { |
| 1161 __ SmiUntag(index.reg()); | 1169 __ SmiUntag(index.reg()); |
| 1162 } | 1170 } |
| 1163 Register result = locs()->out().reg(); | 1171 Register result = locs()->out().reg(); |
| 1164 switch (class_id()) { | 1172 switch (class_id()) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 case kTypedDataInt16ArrayCid: | 1223 case kTypedDataInt16ArrayCid: |
| 1216 case kTypedDataUint16ArrayCid: | 1224 case kTypedDataUint16ArrayCid: |
| 1217 case kTypedDataInt32ArrayCid: | 1225 case kTypedDataInt32ArrayCid: |
| 1218 case kTypedDataUint32ArrayCid: | 1226 case kTypedDataUint32ArrayCid: |
| 1219 return kTagged; | 1227 return kTagged; |
| 1220 case kTypedDataFloat32ArrayCid: | 1228 case kTypedDataFloat32ArrayCid: |
| 1221 case kTypedDataFloat64ArrayCid: | 1229 case kTypedDataFloat64ArrayCid: |
| 1222 return kUnboxedDouble; | 1230 return kUnboxedDouble; |
| 1223 case kTypedDataFloat32x4ArrayCid: | 1231 case kTypedDataFloat32x4ArrayCid: |
| 1224 return kUnboxedFloat32x4; | 1232 return kUnboxedFloat32x4; |
| 1233 case kTypedDataUint32x4ArrayCid: |
| 1234 return kUnboxedUint32x4; |
| 1225 default: | 1235 default: |
| 1226 UNIMPLEMENTED(); | 1236 UNIMPLEMENTED(); |
| 1227 return kTagged; | 1237 return kTagged; |
| 1228 } | 1238 } |
| 1229 } | 1239 } |
| 1230 | 1240 |
| 1231 | 1241 |
| 1232 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1242 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1233 const intptr_t kNumInputs = 3; | 1243 const intptr_t kNumInputs = 3; |
| 1234 const intptr_t kNumTemps = 0; | 1244 const intptr_t kNumTemps = 0; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 locs->set_in(2, Location::WritableRegister()); | 1282 locs->set_in(2, Location::WritableRegister()); |
| 1273 break; | 1283 break; |
| 1274 case kTypedDataFloat32ArrayCid: | 1284 case kTypedDataFloat32ArrayCid: |
| 1275 // Need temp register for float-to-double conversion. | 1285 // Need temp register for float-to-double conversion. |
| 1276 locs->AddTemp(Location::RequiresFpuRegister()); | 1286 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1277 // Fall through. | 1287 // Fall through. |
| 1278 case kTypedDataFloat64ArrayCid: | 1288 case kTypedDataFloat64ArrayCid: |
| 1279 // TODO(srdjan): Support Float64 constants. | 1289 // TODO(srdjan): Support Float64 constants. |
| 1280 locs->set_in(2, Location::RequiresFpuRegister()); | 1290 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1281 break; | 1291 break; |
| 1292 case kTypedDataUint32x4ArrayCid: |
| 1282 case kTypedDataFloat32x4ArrayCid: | 1293 case kTypedDataFloat32x4ArrayCid: |
| 1283 locs->set_in(2, Location::RequiresFpuRegister()); | 1294 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1284 break; | 1295 break; |
| 1285 default: | 1296 default: |
| 1286 UNREACHABLE(); | 1297 UNREACHABLE(); |
| 1287 return NULL; | 1298 return NULL; |
| 1288 } | 1299 } |
| 1289 return locs; | 1300 return locs; |
| 1290 } | 1301 } |
| 1291 | 1302 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 } | 1400 } |
| 1390 case kTypedDataFloat32ArrayCid: | 1401 case kTypedDataFloat32ArrayCid: |
| 1391 // Convert to single precision. | 1402 // Convert to single precision. |
| 1392 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1403 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1393 // Store. | 1404 // Store. |
| 1394 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1405 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1395 break; | 1406 break; |
| 1396 case kTypedDataFloat64ArrayCid: | 1407 case kTypedDataFloat64ArrayCid: |
| 1397 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1408 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1398 break; | 1409 break; |
| 1410 case kTypedDataUint32x4ArrayCid: |
| 1399 case kTypedDataFloat32x4ArrayCid: | 1411 case kTypedDataFloat32x4ArrayCid: |
| 1400 __ movups(element_address, locs()->in(2).fpu_reg()); | 1412 __ movups(element_address, locs()->in(2).fpu_reg()); |
| 1401 break; | 1413 break; |
| 1402 default: | 1414 default: |
| 1403 UNREACHABLE(); | 1415 UNREACHABLE(); |
| 1404 } | 1416 } |
| 1405 } | 1417 } |
| 1406 | 1418 |
| 1407 | 1419 |
| 1408 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1420 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 // If length is negative the length guard is either disabled or | 1535 // If length is negative the length guard is either disabled or |
| 1524 // has not been initialized, either way it is safe to skip the | 1536 // has not been initialized, either way it is safe to skip the |
| 1525 // length check. | 1537 // length check. |
| 1526 __ CompareImmediate( | 1538 __ CompareImmediate( |
| 1527 field_length_operand, Immediate(Smi::RawValue(0)), PP); | 1539 field_length_operand, Immediate(Smi::RawValue(0)), PP); |
| 1528 __ j(LESS, &skip_length_check); | 1540 __ j(LESS, &skip_length_check); |
| 1529 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); | 1541 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); |
| 1530 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1542 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1531 // Check for typed data array. | 1543 // Check for typed data array. |
| 1532 __ CompareImmediate( | 1544 __ CompareImmediate( |
| 1533 value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid), PP); | 1545 value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid), PP); |
| 1534 // Not a typed array or a regular array. | 1546 // Not a typed array or a regular array. |
| 1535 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1547 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
| 1536 __ CompareImmediate( | 1548 __ CompareImmediate( |
| 1537 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); | 1549 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); |
| 1538 // Could still be a regular array. | 1550 // Could still be a regular array. |
| 1539 __ j(LESS, &check_array, Assembler::kNearJump); | 1551 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1540 __ pushq(value_cid_reg); | 1552 __ pushq(value_cid_reg); |
| 1541 __ movq(value_cid_reg, | 1553 __ movq(value_cid_reg, |
| 1542 FieldAddress(value_reg, TypedData::length_offset())); | 1554 FieldAddress(value_reg, TypedData::length_offset())); |
| 1543 __ cmpq(field_length_operand, value_cid_reg); | 1555 __ cmpq(field_length_operand, value_cid_reg); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1603 | 1615 |
| 1604 if (value_cid == kDynamicCid) { | 1616 if (value_cid == kDynamicCid) { |
| 1605 __ movq(field_cid_operand, value_cid_reg); | 1617 __ movq(field_cid_operand, value_cid_reg); |
| 1606 __ movq(field_nullability_operand, value_cid_reg); | 1618 __ movq(field_nullability_operand, value_cid_reg); |
| 1607 if (field_has_length) { | 1619 if (field_has_length) { |
| 1608 Label check_array, length_set, no_fixed_length; | 1620 Label check_array, length_set, no_fixed_length; |
| 1609 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); | 1621 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); |
| 1610 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1622 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1611 // Check for typed data array. | 1623 // Check for typed data array. |
| 1612 __ CompareImmediate(value_cid_reg, | 1624 __ CompareImmediate(value_cid_reg, |
| 1613 Immediate(kTypedDataFloat32x4ArrayCid), PP); | 1625 Immediate(kTypedDataUint32x4ArrayCid), PP); |
| 1614 // Not a typed array or a regular array. | 1626 // Not a typed array or a regular array. |
| 1615 __ j(GREATER, &no_fixed_length); | 1627 __ j(GREATER, &no_fixed_length); |
| 1616 __ CompareImmediate( | 1628 __ CompareImmediate( |
| 1617 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); | 1629 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); |
| 1618 // Could still be a regular array. | 1630 // Could still be a regular array. |
| 1619 __ j(LESS, &check_array, Assembler::kNearJump); | 1631 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1620 // Destroy value_cid_reg (safe because we are finished with it). | 1632 // Destroy value_cid_reg (safe because we are finished with it). |
| 1621 __ movq(value_cid_reg, | 1633 __ movq(value_cid_reg, |
| 1622 FieldAddress(value_reg, TypedData::length_offset())); | 1634 FieldAddress(value_reg, TypedData::length_offset())); |
| 1623 __ movq(field_length_operand, value_cid_reg); | 1635 __ movq(field_length_operand, value_cid_reg); |
| (...skipping 3182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4806 PcDescriptors::kOther, | 4818 PcDescriptors::kOther, |
| 4807 locs()); | 4819 locs()); |
| 4808 __ Drop(2); // Discard type arguments and receiver. | 4820 __ Drop(2); // Discard type arguments and receiver. |
| 4809 } | 4821 } |
| 4810 | 4822 |
| 4811 } // namespace dart | 4823 } // namespace dart |
| 4812 | 4824 |
| 4813 #undef __ | 4825 #undef __ |
| 4814 | 4826 |
| 4815 #endif // defined TARGET_ARCH_X64 | 4827 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |