Chromium Code Reviews| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1095 | 1095 |
| 1096 | 1096 |
| 1097 CompileType LoadIndexedInstr::ComputeType() const { | 1097 CompileType LoadIndexedInstr::ComputeType() const { |
| 1098 switch (class_id_) { | 1098 switch (class_id_) { |
| 1099 case kArrayCid: | 1099 case kArrayCid: |
| 1100 case kImmutableArrayCid: | 1100 case kImmutableArrayCid: |
| 1101 return CompileType::Dynamic(); | 1101 return CompileType::Dynamic(); |
| 1102 | 1102 |
| 1103 case kFloat32ArrayCid : | 1103 case kFloat32ArrayCid : |
| 1104 case kFloat64ArrayCid : | 1104 case kFloat64ArrayCid : |
| 1105 case kTypedDataFloat32ArrayCid: | |
| 1106 case kTypedDataFloat64ArrayCid: | |
| 1105 return CompileType::FromCid(kDoubleCid); | 1107 return CompileType::FromCid(kDoubleCid); |
| 1106 | 1108 |
| 1107 case kInt8ArrayCid: | 1109 case kInt8ArrayCid: |
| 1108 case kUint8ArrayCid: | 1110 case kUint8ArrayCid: |
| 1109 case kUint8ClampedArrayCid: | 1111 case kUint8ClampedArrayCid: |
| 1110 case kExternalUint8ArrayCid: | 1112 case kExternalUint8ArrayCid: |
| 1111 case kExternalUint8ClampedArrayCid: | 1113 case kExternalUint8ClampedArrayCid: |
| 1112 case kInt16ArrayCid: | 1114 case kInt16ArrayCid: |
| 1113 case kUint16ArrayCid: | 1115 case kUint16ArrayCid: |
| 1116 case kTypedDataInt8ArrayCid: | |
| 1117 case kTypedDataUint8ArrayCid: | |
| 1118 case kTypedDataUint8ClampedArrayCid: | |
| 1119 case kExternalTypedDataUint8ArrayCid: | |
| 1120 case kExternalTypedDataUint8ClampedArrayCid: | |
| 1121 case kTypedDataInt16ArrayCid: | |
| 1122 case kTypedDataUint16ArrayCid: | |
| 1114 case kOneByteStringCid: | 1123 case kOneByteStringCid: |
| 1115 case kTwoByteStringCid: | 1124 case kTwoByteStringCid: |
| 1116 return CompileType::FromCid(kSmiCid); | 1125 return CompileType::FromCid(kSmiCid); |
| 1117 | 1126 |
| 1118 case kInt32ArrayCid: | 1127 case kInt32ArrayCid: |
| 1119 case kUint32ArrayCid: | 1128 case kUint32ArrayCid: |
| 1129 case kTypedDataInt32ArrayCid: | |
| 1130 case kTypedDataUint32ArrayCid: | |
| 1120 // Result can be Smi or Mint when boxed. | 1131 // Result can be Smi or Mint when boxed. |
| 1121 // Instruction can deoptimize if we optimistically assumed that the result | 1132 // Instruction can deoptimize if we optimistically assumed that the result |
| 1122 // fits into Smi. | 1133 // fits into Smi. |
| 1123 return CanDeoptimize() ? CompileType::FromCid(kSmiCid) | 1134 return CanDeoptimize() ? CompileType::FromCid(kSmiCid) |
| 1124 : CompileType::Int(); | 1135 : CompileType::Int(); |
| 1125 | 1136 |
| 1126 default: | 1137 default: |
| 1127 UNIMPLEMENTED(); | 1138 UNIMPLEMENTED(); |
| 1128 return CompileType::Dynamic(); | 1139 return CompileType::Dynamic(); |
| 1129 } | 1140 } |
| 1130 } | 1141 } |
| 1131 | 1142 |
| 1132 | 1143 |
| 1133 Representation LoadIndexedInstr::representation() const { | 1144 Representation LoadIndexedInstr::representation() const { |
| 1134 switch (class_id_) { | 1145 switch (class_id_) { |
| 1135 case kArrayCid: | 1146 case kArrayCid: |
| 1136 case kImmutableArrayCid: | 1147 case kImmutableArrayCid: |
| 1137 case kInt8ArrayCid: | 1148 case kInt8ArrayCid: |
| 1138 case kUint8ArrayCid: | 1149 case kUint8ArrayCid: |
| 1139 case kUint8ClampedArrayCid: | 1150 case kUint8ClampedArrayCid: |
| 1140 case kExternalUint8ArrayCid: | 1151 case kExternalUint8ArrayCid: |
| 1141 case kExternalUint8ClampedArrayCid: | 1152 case kExternalUint8ClampedArrayCid: |
| 1142 case kInt16ArrayCid: | 1153 case kInt16ArrayCid: |
| 1143 case kUint16ArrayCid: | 1154 case kUint16ArrayCid: |
| 1155 case kTypedDataInt8ArrayCid: | |
| 1156 case kTypedDataUint8ArrayCid: | |
| 1157 case kTypedDataUint8ClampedArrayCid: | |
| 1158 case kExternalTypedDataUint8ArrayCid: | |
| 1159 case kExternalTypedDataUint8ClampedArrayCid: | |
| 1160 case kTypedDataInt16ArrayCid: | |
| 1161 case kTypedDataUint16ArrayCid: | |
| 1144 case kOneByteStringCid: | 1162 case kOneByteStringCid: |
| 1145 case kTwoByteStringCid: | 1163 case kTwoByteStringCid: |
| 1146 return kTagged; | 1164 return kTagged; |
| 1147 case kInt32ArrayCid: | 1165 case kInt32ArrayCid: |
| 1148 case kUint32ArrayCid: | 1166 case kUint32ArrayCid: |
| 1167 case kTypedDataInt32ArrayCid: | |
| 1168 case kTypedDataUint32ArrayCid: | |
| 1149 // Instruction can deoptimize if we optimistically assumed that the result | 1169 // Instruction can deoptimize if we optimistically assumed that the result |
| 1150 // fits into Smi. | 1170 // fits into Smi. |
| 1151 return CanDeoptimize() ? kTagged : kUnboxedMint; | 1171 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 1152 case kFloat32ArrayCid : | 1172 case kFloat32ArrayCid : |
| 1153 case kFloat64ArrayCid : | 1173 case kFloat64ArrayCid : |
| 1174 case kTypedDataFloat32ArrayCid: | |
| 1175 case kTypedDataFloat64ArrayCid: | |
| 1154 return kUnboxedDouble; | 1176 return kUnboxedDouble; |
| 1155 default: | 1177 default: |
| 1156 UNIMPLEMENTED(); | 1178 UNIMPLEMENTED(); |
| 1157 return kTagged; | 1179 return kTagged; |
| 1158 } | 1180 } |
| 1159 } | 1181 } |
| 1160 | 1182 |
| 1161 | 1183 |
| 1162 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1184 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1163 const intptr_t kNumInputs = 2; | 1185 const intptr_t kNumInputs = 2; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1185 } | 1207 } |
| 1186 return locs; | 1208 return locs; |
| 1187 } | 1209 } |
| 1188 | 1210 |
| 1189 | 1211 |
| 1190 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1212 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1191 Register array = locs()->in(0).reg(); | 1213 Register array = locs()->in(0).reg(); |
| 1192 Location index = locs()->in(1); | 1214 Location index = locs()->in(1); |
| 1193 | 1215 |
| 1194 if ((class_id() == kExternalUint8ArrayCid) || | 1216 if ((class_id() == kExternalUint8ArrayCid) || |
| 1195 (class_id() == kExternalUint8ClampedArrayCid)) { | 1217 (class_id() == kExternalUint8ClampedArrayCid) || |
| 1218 (class_id() == kExternalTypedDataUint8ArrayCid) || | |
| 1219 (class_id() == kExternalTypedDataUint8ClampedArrayCid)) { | |
| 1196 Register result = locs()->out().reg(); | 1220 Register result = locs()->out().reg(); |
| 1197 const Address& element_address = index.IsRegister() | 1221 const Address& element_address = index.IsRegister() |
| 1198 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( | 1222 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| 1199 class_id(), index_scale(), result, index.reg()) | 1223 index_scale(), result, index.reg()) |
| 1200 : FlowGraphCompiler::ExternalElementAddressForIntIndex( | 1224 : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| 1201 class_id(), index_scale(), result, | 1225 index_scale(), result, Smi::Cast(index.constant()).Value()); |
| 1202 Smi::Cast(index.constant()).Value()); | |
| 1203 ASSERT(index_scale() == 1); | 1226 ASSERT(index_scale() == 1); |
| 1204 if (index.IsRegister()) { | 1227 if (index.IsRegister()) { |
| 1205 __ SmiUntag(index.reg()); | 1228 __ SmiUntag(index.reg()); |
| 1206 } | 1229 } |
| 1207 __ movl(result, | 1230 __ movl(result, |
| 1208 FieldAddress(array, ExternalUint8Array::data_offset())); | 1231 FieldAddress(array, ExternalUint8Array::data_offset())); |
| 1209 __ movzxb(result, element_address); | 1232 __ movzxb(result, element_address); |
| 1210 __ SmiTag(result); | 1233 __ SmiTag(result); |
| 1211 return; | 1234 return; |
| 1212 } | 1235 } |
| 1213 | 1236 |
| 1214 FieldAddress element_address = index.IsRegister() | 1237 FieldAddress element_address = index.IsRegister() |
| 1215 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1238 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1216 class_id(), index_scale(), array, index.reg()) | 1239 class_id(), index_scale(), array, index.reg()) |
| 1217 : FlowGraphCompiler::ElementAddressForIntIndex( | 1240 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1218 class_id(), index_scale(), array, | 1241 class_id(), index_scale(), array, |
| 1219 Smi::Cast(index.constant()).Value()); | 1242 Smi::Cast(index.constant()).Value()); |
| 1220 | 1243 |
| 1221 if ((representation() == kUnboxedDouble) || | 1244 if ((representation() == kUnboxedDouble) || |
| 1222 (representation() == kUnboxedMint)) { | 1245 (representation() == kUnboxedMint)) { |
| 1223 XmmRegister result = locs()->out().fpu_reg(); | 1246 XmmRegister result = locs()->out().fpu_reg(); |
| 1224 if ((index_scale() == 1) && index.IsRegister()) { | 1247 if ((index_scale() == 1) && index.IsRegister()) { |
| 1225 __ SmiUntag(index.reg()); | 1248 __ SmiUntag(index.reg()); |
| 1226 } | 1249 } |
| 1227 switch (class_id()) { | 1250 switch (class_id()) { |
| 1228 case kInt32ArrayCid: | 1251 case kInt32ArrayCid: |
| 1252 case kTypedDataInt32ArrayCid: | |
| 1229 __ movss(result, element_address); | 1253 __ movss(result, element_address); |
| 1230 __ pmovsxdq(result, result); | 1254 __ pmovsxdq(result, result); |
| 1231 break; | 1255 break; |
| 1232 case kUint32ArrayCid: | 1256 case kUint32ArrayCid: |
| 1257 case kTypedDataUint32ArrayCid: | |
| 1233 __ xorpd(result, result); | 1258 __ xorpd(result, result); |
| 1234 __ movss(result, element_address); | 1259 __ movss(result, element_address); |
| 1235 break; | 1260 break; |
| 1236 case kFloat32ArrayCid: | 1261 case kFloat32ArrayCid: |
| 1262 case kTypedDataFloat32ArrayCid: | |
| 1237 // Load single precision float and promote to double. | 1263 // Load single precision float and promote to double. |
| 1238 __ movss(result, element_address); | 1264 __ movss(result, element_address); |
| 1239 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1265 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1240 break; | 1266 break; |
| 1241 case kFloat64ArrayCid: | 1267 case kFloat64ArrayCid: |
| 1268 case kTypedDataFloat64ArrayCid: | |
| 1242 __ movsd(result, element_address); | 1269 __ movsd(result, element_address); |
| 1243 break; | 1270 break; |
| 1244 } | 1271 } |
| 1245 return; | 1272 return; |
| 1246 } | 1273 } |
| 1247 | 1274 |
| 1248 Register result = locs()->out().reg(); | 1275 Register result = locs()->out().reg(); |
| 1249 if ((index_scale() == 1) && index.IsRegister()) { | 1276 if ((index_scale() == 1) && index.IsRegister()) { |
| 1250 __ SmiUntag(index.reg()); | 1277 __ SmiUntag(index.reg()); |
| 1251 } | 1278 } |
| 1252 switch (class_id()) { | 1279 switch (class_id()) { |
| 1253 case kInt8ArrayCid: | 1280 case kInt8ArrayCid: |
| 1281 case kTypedDataInt8ArrayCid: | |
| 1282 ASSERT(index_scale() == 1); | |
| 1283 __ movsxb(result, element_address); | |
|
Kevin Millikin (Google)
2013/03/14 10:09:12
Something's wrong with the indentation there. Ext
Florian Schneider
2013/03/14 14:03:09
Done.
| |
| 1284 __ SmiTag(result); | |
| 1285 break; | |
| 1254 case kUint8ArrayCid: | 1286 case kUint8ArrayCid: |
| 1255 case kUint8ClampedArrayCid: | 1287 case kUint8ClampedArrayCid: |
| 1288 case kTypedDataUint8ArrayCid: | |
| 1289 case kTypedDataUint8ClampedArrayCid: | |
| 1256 case kOneByteStringCid: | 1290 case kOneByteStringCid: |
| 1257 ASSERT(index_scale() == 1); | 1291 ASSERT(index_scale() == 1); |
| 1258 if (class_id() == kInt8ArrayCid) { | 1292 __ movzxb(result, element_address); |
| 1259 __ movsxb(result, element_address); | |
| 1260 } else { | |
| 1261 __ movzxb(result, element_address); | |
| 1262 } | |
| 1263 __ SmiTag(result); | 1293 __ SmiTag(result); |
| 1264 break; | 1294 break; |
| 1265 case kInt16ArrayCid: | 1295 case kInt16ArrayCid: |
| 1296 case kTypedDataInt16ArrayCid: | |
| 1266 __ movsxw(result, element_address); | 1297 __ movsxw(result, element_address); |
| 1267 __ SmiTag(result); | 1298 __ SmiTag(result); |
| 1268 break; | 1299 break; |
| 1269 case kUint16ArrayCid: | 1300 case kUint16ArrayCid: |
| 1301 case kTypedDataUint16ArrayCid: | |
| 1270 case kTwoByteStringCid: | 1302 case kTwoByteStringCid: |
| 1271 __ movzxw(result, element_address); | 1303 __ movzxw(result, element_address); |
| 1272 __ SmiTag(result); | 1304 __ SmiTag(result); |
| 1273 break; | 1305 break; |
| 1274 case kInt32ArrayCid: { | 1306 case kInt32ArrayCid: |
| 1307 case kTypedDataInt32ArrayCid: { | |
| 1275 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load); | 1308 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load); |
| 1276 __ movl(result, element_address); | 1309 __ movl(result, element_address); |
| 1277 // Verify that the signed value in 'result' can fit inside a Smi. | 1310 // Verify that the signed value in 'result' can fit inside a Smi. |
| 1278 __ cmpl(result, Immediate(0xC0000000)); | 1311 __ cmpl(result, Immediate(0xC0000000)); |
| 1279 __ j(NEGATIVE, deopt); | 1312 __ j(NEGATIVE, deopt); |
| 1280 __ SmiTag(result); | 1313 __ SmiTag(result); |
| 1281 } | 1314 } |
| 1282 break; | 1315 break; |
| 1283 case kUint32ArrayCid: { | 1316 case kUint32ArrayCid: |
| 1317 case kTypedDataUint32ArrayCid: { | |
| 1284 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load); | 1318 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load); |
| 1285 __ movl(result, element_address); | 1319 __ movl(result, element_address); |
| 1286 // Verify that the unsigned value in 'result' can fit inside a Smi. | 1320 // Verify that the unsigned value in 'result' can fit inside a Smi. |
| 1287 __ testl(result, Immediate(0xC0000000)); | 1321 __ testl(result, Immediate(0xC0000000)); |
| 1288 __ j(NOT_ZERO, deopt); | 1322 __ j(NOT_ZERO, deopt); |
| 1289 __ SmiTag(result); | 1323 __ SmiTag(result); |
| 1290 } | 1324 } |
| 1291 break; | 1325 break; |
| 1292 default: | 1326 default: |
| 1293 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1327 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1294 __ movl(result, element_address); | 1328 __ movl(result, element_address); |
| 1295 break; | 1329 break; |
| 1296 } | 1330 } |
| 1297 } | 1331 } |
| 1298 | 1332 |
| 1299 | 1333 |
| 1300 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1334 Representation StoreIndexedInstr::RequiredInputRepresentation( |
| 1301 intptr_t idx) const { | 1335 intptr_t idx) const { |
| 1302 if ((idx == 0) || (idx == 1)) return kTagged; | 1336 if ((idx == 0) || (idx == 1)) return kTagged; |
| 1303 ASSERT(idx == 2); | 1337 ASSERT(idx == 2); |
| 1304 switch (class_id_) { | 1338 switch (class_id_) { |
| 1305 case kArrayCid: | 1339 case kArrayCid: |
| 1306 case kInt8ArrayCid: | 1340 case kInt8ArrayCid: |
| 1307 case kUint8ArrayCid: | 1341 case kUint8ArrayCid: |
| 1308 case kExternalUint8ArrayCid: | 1342 case kExternalUint8ArrayCid: |
| 1309 case kUint8ClampedArrayCid: | 1343 case kUint8ClampedArrayCid: |
| 1310 case kExternalUint8ClampedArrayCid: | 1344 case kExternalUint8ClampedArrayCid: |
| 1311 case kInt16ArrayCid: | 1345 case kInt16ArrayCid: |
| 1312 case kUint16ArrayCid: | 1346 case kUint16ArrayCid: |
| 1347 case kTypedDataInt8ArrayCid: | |
| 1348 case kTypedDataUint8ArrayCid: | |
| 1349 case kExternalTypedDataUint8ArrayCid: | |
| 1350 case kTypedDataUint8ClampedArrayCid: | |
| 1351 case kExternalTypedDataUint8ClampedArrayCid: | |
| 1352 case kTypedDataInt16ArrayCid: | |
| 1353 case kTypedDataUint16ArrayCid: | |
| 1313 return kTagged; | 1354 return kTagged; |
| 1314 case kInt32ArrayCid: | 1355 case kInt32ArrayCid: |
| 1315 case kUint32ArrayCid: | 1356 case kUint32ArrayCid: |
| 1357 case kTypedDataInt32ArrayCid: | |
| 1358 case kTypedDataUint32ArrayCid: | |
| 1316 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1359 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 1317 case kFloat32ArrayCid : | 1360 case kFloat32ArrayCid : |
| 1318 case kFloat64ArrayCid : | 1361 case kFloat64ArrayCid : |
| 1362 case kTypedDataFloat32ArrayCid : | |
| 1363 case kTypedDataFloat64ArrayCid : | |
| 1319 return kUnboxedDouble; | 1364 return kUnboxedDouble; |
| 1320 default: | 1365 default: |
| 1321 UNIMPLEMENTED(); | 1366 UNIMPLEMENTED(); |
| 1322 return kTagged; | 1367 return kTagged; |
| 1323 } | 1368 } |
| 1324 } | 1369 } |
| 1325 | 1370 |
| 1326 | 1371 |
| 1327 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1372 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1328 const intptr_t kNumInputs = 3; | 1373 const intptr_t kNumInputs = 3; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1344 : Location::RequiresRegister()); | 1389 : Location::RequiresRegister()); |
| 1345 } | 1390 } |
| 1346 switch (class_id()) { | 1391 switch (class_id()) { |
| 1347 case kArrayCid: | 1392 case kArrayCid: |
| 1348 locs->set_in(2, ShouldEmitStoreBarrier() | 1393 locs->set_in(2, ShouldEmitStoreBarrier() |
| 1349 ? Location::WritableRegister() | 1394 ? Location::WritableRegister() |
| 1350 : Location::RegisterOrConstant(value())); | 1395 : Location::RegisterOrConstant(value())); |
| 1351 break; | 1396 break; |
| 1352 case kExternalUint8ArrayCid: | 1397 case kExternalUint8ArrayCid: |
| 1353 case kExternalUint8ClampedArrayCid: | 1398 case kExternalUint8ClampedArrayCid: |
| 1399 case kExternalTypedDataUint8ArrayCid: | |
| 1400 case kExternalTypedDataUint8ClampedArrayCid: | |
| 1354 // Need temp register to load the external array's data array. | 1401 // Need temp register to load the external array's data array. |
| 1355 locs->AddTemp(Location::RequiresRegister()); | 1402 locs->AddTemp(Location::RequiresRegister()); |
| 1356 // Fall through. | 1403 // Fall through. |
| 1357 case kInt8ArrayCid: | 1404 case kInt8ArrayCid: |
| 1358 case kUint8ArrayCid: | 1405 case kUint8ArrayCid: |
| 1359 case kUint8ClampedArrayCid: | 1406 case kUint8ClampedArrayCid: |
| 1407 case kTypedDataInt8ArrayCid: | |
| 1408 case kTypedDataUint8ArrayCid: | |
| 1409 case kTypedDataUint8ClampedArrayCid: | |
| 1360 // TODO(fschneider): Add location constraint for byte registers (EAX, | 1410 // TODO(fschneider): Add location constraint for byte registers (EAX, |
| 1361 // EBX, ECX, EDX) instead of using a fixed register. | 1411 // EBX, ECX, EDX) instead of using a fixed register. |
| 1362 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); | 1412 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); |
| 1363 break; | 1413 break; |
| 1364 case kInt16ArrayCid: | 1414 case kInt16ArrayCid: |
| 1365 case kUint16ArrayCid: | 1415 case kUint16ArrayCid: |
| 1416 case kTypedDataInt16ArrayCid: | |
| 1417 case kTypedDataUint16ArrayCid: | |
| 1366 // Writable register because the value must be untagged before storing. | 1418 // Writable register because the value must be untagged before storing. |
| 1367 locs->set_in(2, Location::WritableRegister()); | 1419 locs->set_in(2, Location::WritableRegister()); |
| 1368 break; | 1420 break; |
| 1369 case kInt32ArrayCid: | 1421 case kInt32ArrayCid: |
| 1370 case kUint32ArrayCid: | 1422 case kUint32ArrayCid: |
| 1423 case kTypedDataInt32ArrayCid: | |
| 1424 case kTypedDataUint32ArrayCid: | |
| 1371 // Mints are stored in XMM registers. For smis, use a writable register | 1425 // Mints are stored in XMM registers. For smis, use a writable register |
| 1372 // because the value must be untagged before storing. | 1426 // because the value must be untagged before storing. |
| 1373 locs->set_in(2, value()->IsSmiValue() | 1427 locs->set_in(2, value()->IsSmiValue() |
| 1374 ? Location::WritableRegister() | 1428 ? Location::WritableRegister() |
| 1375 : Location::RequiresFpuRegister()); | 1429 : Location::RequiresFpuRegister()); |
| 1376 break; | 1430 break; |
| 1377 case kFloat32ArrayCid: | 1431 case kFloat32ArrayCid: |
| 1432 case kTypedDataFloat32ArrayCid: | |
| 1378 // Need temp register for float-to-double conversion. | 1433 // Need temp register for float-to-double conversion. |
| 1379 locs->AddTemp(Location::RequiresFpuRegister()); | 1434 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1380 // Fall through. | 1435 // Fall through. |
| 1381 case kFloat64ArrayCid: | 1436 case kFloat64ArrayCid: |
| 1437 case kTypedDataFloat64ArrayCid: | |
| 1382 // TODO(srdjan): Support Float64 constants. | 1438 // TODO(srdjan): Support Float64 constants. |
| 1383 locs->set_in(2, Location::RequiresFpuRegister()); | 1439 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1384 break; | 1440 break; |
| 1385 default: | 1441 default: |
| 1386 UNREACHABLE(); | 1442 UNREACHABLE(); |
| 1387 return NULL; | 1443 return NULL; |
| 1388 } | 1444 } |
| 1389 return locs; | 1445 return locs; |
| 1390 } | 1446 } |
| 1391 | 1447 |
| 1392 | 1448 |
| 1393 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1449 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1394 Register array = locs()->in(0).reg(); | 1450 Register array = locs()->in(0).reg(); |
| 1395 Location index = locs()->in(1); | 1451 Location index = locs()->in(1); |
| 1396 | 1452 |
| 1397 Address element_address(kNoRegister, 0); | 1453 Address element_address(kNoRegister, 0); |
| 1398 if ((class_id() == kExternalUint8ArrayCid) || | 1454 if ((class_id() == kExternalUint8ArrayCid) || |
| 1399 (class_id() == kExternalUint8ClampedArrayCid)) { | 1455 (class_id() == kExternalUint8ClampedArrayCid) || |
| 1456 (class_id() == kExternalTypedDataUint8ArrayCid) || | |
| 1457 (class_id() == kExternalTypedDataUint8ClampedArrayCid)) { | |
| 1400 Register temp = locs()->temp(0).reg(); | 1458 Register temp = locs()->temp(0).reg(); |
| 1401 element_address = index.IsRegister() | 1459 element_address = index.IsRegister() |
| 1402 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( | 1460 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| 1403 class_id(), index_scale(), temp, index.reg()) | 1461 index_scale(), temp, index.reg()) |
| 1404 : FlowGraphCompiler::ExternalElementAddressForIntIndex( | 1462 : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| 1405 class_id(), index_scale(), temp, | 1463 index_scale(), temp, Smi::Cast(index.constant()).Value()); |
| 1406 Smi::Cast(index.constant()).Value()); | |
| 1407 __ movl(temp, | 1464 __ movl(temp, |
| 1408 FieldAddress(array, ExternalUint8Array::data_offset())); | 1465 FieldAddress(array, ExternalUint8Array::data_offset())); |
| 1409 } else { | 1466 } else { |
| 1410 element_address = index.IsRegister() | 1467 element_address = index.IsRegister() |
| 1411 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1468 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1412 class_id(), index_scale(), array, index.reg()) | 1469 class_id(), index_scale(), array, index.reg()) |
| 1413 : FlowGraphCompiler::ElementAddressForIntIndex( | 1470 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1414 class_id(), index_scale(), array, | 1471 class_id(), index_scale(), array, |
| 1415 Smi::Cast(index.constant()).Value()); | 1472 Smi::Cast(index.constant()).Value()); |
| 1416 } | 1473 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1427 const Object& constant = locs()->in(2).constant(); | 1484 const Object& constant = locs()->in(2).constant(); |
| 1428 __ StoreIntoObjectNoBarrier(array, element_address, constant); | 1485 __ StoreIntoObjectNoBarrier(array, element_address, constant); |
| 1429 } else { | 1486 } else { |
| 1430 Register value = locs()->in(2).reg(); | 1487 Register value = locs()->in(2).reg(); |
| 1431 __ StoreIntoObjectNoBarrier(array, element_address, value); | 1488 __ StoreIntoObjectNoBarrier(array, element_address, value); |
| 1432 } | 1489 } |
| 1433 break; | 1490 break; |
| 1434 case kInt8ArrayCid: | 1491 case kInt8ArrayCid: |
| 1435 case kUint8ArrayCid: | 1492 case kUint8ArrayCid: |
| 1436 case kExternalUint8ArrayCid: | 1493 case kExternalUint8ArrayCid: |
| 1494 case kTypedDataInt8ArrayCid: | |
| 1495 case kTypedDataUint8ArrayCid: | |
| 1496 case kExternalTypedDataUint8ArrayCid: | |
| 1437 if (locs()->in(2).IsConstant()) { | 1497 if (locs()->in(2).IsConstant()) { |
| 1438 const Smi& constant = Smi::Cast(locs()->in(2).constant()); | 1498 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| 1439 __ movb(element_address, | 1499 __ movb(element_address, |
| 1440 Immediate(static_cast<int8_t>(constant.Value()))); | 1500 Immediate(static_cast<int8_t>(constant.Value()))); |
| 1441 } else { | 1501 } else { |
| 1442 ASSERT(locs()->in(2).reg() == EAX); | 1502 ASSERT(locs()->in(2).reg() == EAX); |
| 1443 __ SmiUntag(EAX); | 1503 __ SmiUntag(EAX); |
| 1444 __ movb(element_address, AL); | 1504 __ movb(element_address, AL); |
| 1445 } | 1505 } |
| 1446 break; | 1506 break; |
| 1447 case kUint8ClampedArrayCid: | 1507 case kUint8ClampedArrayCid: |
| 1448 case kExternalUint8ClampedArrayCid: { | 1508 case kExternalUint8ClampedArrayCid: |
| 1509 case kTypedDataUint8ClampedArrayCid: | |
| 1510 case kExternalTypedDataUint8ClampedArrayCid: { | |
| 1449 if (locs()->in(2).IsConstant()) { | 1511 if (locs()->in(2).IsConstant()) { |
| 1450 const Smi& constant = Smi::Cast(locs()->in(2).constant()); | 1512 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| 1451 intptr_t value = constant.Value(); | 1513 intptr_t value = constant.Value(); |
| 1452 // Clamp to 0x0 or 0xFF respectively. | 1514 // Clamp to 0x0 or 0xFF respectively. |
| 1453 if (value > 0xFF) { | 1515 if (value > 0xFF) { |
| 1454 value = 0xFF; | 1516 value = 0xFF; |
| 1455 } else if (value < 0) { | 1517 } else if (value < 0) { |
| 1456 value = 0; | 1518 value = 0; |
| 1457 } | 1519 } |
| 1458 __ movb(element_address, | 1520 __ movb(element_address, |
| 1459 Immediate(static_cast<int8_t>(value))); | 1521 Immediate(static_cast<int8_t>(value))); |
| 1460 } else { | 1522 } else { |
| 1461 ASSERT(locs()->in(2).reg() == EAX); | 1523 ASSERT(locs()->in(2).reg() == EAX); |
| 1462 Label store_value, store_0xff; | 1524 Label store_value, store_0xff; |
| 1463 __ SmiUntag(EAX); | 1525 __ SmiUntag(EAX); |
| 1464 __ cmpl(EAX, Immediate(0xFF)); | 1526 __ cmpl(EAX, Immediate(0xFF)); |
| 1465 __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump); | 1527 __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump); |
| 1466 // Clamp to 0x0 or 0xFF respectively. | 1528 // Clamp to 0x0 or 0xFF respectively. |
| 1467 __ j(GREATER, &store_0xff); | 1529 __ j(GREATER, &store_0xff); |
| 1468 __ xorl(EAX, EAX); | 1530 __ xorl(EAX, EAX); |
| 1469 __ jmp(&store_value, Assembler::kNearJump); | 1531 __ jmp(&store_value, Assembler::kNearJump); |
| 1470 __ Bind(&store_0xff); | 1532 __ Bind(&store_0xff); |
| 1471 __ movl(EAX, Immediate(0xFF)); | 1533 __ movl(EAX, Immediate(0xFF)); |
| 1472 __ Bind(&store_value); | 1534 __ Bind(&store_value); |
| 1473 __ movb(element_address, AL); | 1535 __ movb(element_address, AL); |
| 1474 } | 1536 } |
| 1475 break; | 1537 break; |
| 1476 } | 1538 } |
| 1477 case kInt16ArrayCid: | 1539 case kInt16ArrayCid: |
| 1478 case kUint16ArrayCid: { | 1540 case kUint16ArrayCid: |
| 1541 case kTypedDataInt16ArrayCid: | |
| 1542 case kTypedDataUint16ArrayCid: { | |
| 1479 Register value = locs()->in(2).reg(); | 1543 Register value = locs()->in(2).reg(); |
| 1480 __ SmiUntag(value); | 1544 __ SmiUntag(value); |
| 1481 __ movw(element_address, value); | 1545 __ movw(element_address, value); |
| 1482 break; | 1546 break; |
| 1483 } | 1547 } |
| 1484 case kInt32ArrayCid: | 1548 case kInt32ArrayCid: |
| 1485 case kUint32ArrayCid: | 1549 case kUint32ArrayCid: |
| 1550 case kTypedDataInt32ArrayCid: | |
| 1551 case kTypedDataUint32ArrayCid: | |
| 1486 if (value()->IsSmiValue()) { | 1552 if (value()->IsSmiValue()) { |
| 1487 ASSERT(RequiredInputRepresentation(2) == kTagged); | 1553 ASSERT(RequiredInputRepresentation(2) == kTagged); |
| 1488 Register value = locs()->in(2).reg(); | 1554 Register value = locs()->in(2).reg(); |
| 1489 __ SmiUntag(value); | 1555 __ SmiUntag(value); |
| 1490 __ movl(element_address, value); | 1556 __ movl(element_address, value); |
| 1491 } else { | 1557 } else { |
| 1492 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); | 1558 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); |
| 1493 __ movss(element_address, locs()->in(2).fpu_reg()); | 1559 __ movss(element_address, locs()->in(2).fpu_reg()); |
| 1494 } | 1560 } |
| 1495 break; | 1561 break; |
| 1496 case kFloat32ArrayCid: | 1562 case kFloat32ArrayCid: |
| 1563 case kTypedDataFloat32ArrayCid: | |
| 1497 // Convert to single precision. | 1564 // Convert to single precision. |
| 1498 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1565 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1499 // Store. | 1566 // Store. |
| 1500 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1567 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1501 break; | 1568 break; |
| 1502 case kFloat64ArrayCid: | 1569 case kFloat64ArrayCid: |
| 1570 case kTypedDataFloat64ArrayCid: | |
| 1503 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1571 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1504 break; | 1572 break; |
| 1505 default: | 1573 default: |
| 1506 UNREACHABLE(); | 1574 UNREACHABLE(); |
| 1507 } | 1575 } |
| 1508 } | 1576 } |
| 1509 | 1577 |
| 1510 | 1578 |
| 1511 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1579 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { |
| 1512 const intptr_t kNumInputs = 2; | 1580 const intptr_t kNumInputs = 2; |
| (...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3554 PcDescriptors::kOther, | 3622 PcDescriptors::kOther, |
| 3555 locs()); | 3623 locs()); |
| 3556 __ Drop(2); // Discard type arguments and receiver. | 3624 __ Drop(2); // Discard type arguments and receiver. |
| 3557 } | 3625 } |
| 3558 | 3626 |
| 3559 } // namespace dart | 3627 } // namespace dart |
| 3560 | 3628 |
| 3561 #undef __ | 3629 #undef __ |
| 3562 | 3630 |
| 3563 #endif // defined TARGET_ARCH_IA32 | 3631 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |