Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 12775009: Optimize TypedData operators [] and []= in the same way as ScalarList. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: ARM/MIPS build, comments, rebased Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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);
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698