| 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 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1298 | 1298 |
| 1299 | 1299 |
| 1300 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1300 Representation StoreIndexedInstr::RequiredInputRepresentation( |
| 1301 intptr_t idx) const { | 1301 intptr_t idx) const { |
| 1302 if ((idx == 0) || (idx == 1)) return kTagged; | 1302 if ((idx == 0) || (idx == 1)) return kTagged; |
| 1303 ASSERT(idx == 2); | 1303 ASSERT(idx == 2); |
| 1304 switch (class_id_) { | 1304 switch (class_id_) { |
| 1305 case kArrayCid: | 1305 case kArrayCid: |
| 1306 case kInt8ArrayCid: | 1306 case kInt8ArrayCid: |
| 1307 case kUint8ArrayCid: | 1307 case kUint8ArrayCid: |
| 1308 case kExternalUint8ArrayCid: |
| 1308 case kUint8ClampedArrayCid: | 1309 case kUint8ClampedArrayCid: |
| 1310 case kExternalUint8ClampedArrayCid: |
| 1309 case kInt16ArrayCid: | 1311 case kInt16ArrayCid: |
| 1310 case kUint16ArrayCid: | 1312 case kUint16ArrayCid: |
| 1311 return kTagged; | 1313 return kTagged; |
| 1312 case kInt32ArrayCid: | 1314 case kInt32ArrayCid: |
| 1313 case kUint32ArrayCid: | 1315 case kUint32ArrayCid: |
| 1314 return kUnboxedMint; | 1316 return kUnboxedMint; |
| 1315 case kFloat32ArrayCid : | 1317 case kFloat32ArrayCid : |
| 1316 case kFloat64ArrayCid : | 1318 case kFloat64ArrayCid : |
| 1317 return kUnboxedDouble; | 1319 return kUnboxedDouble; |
| 1318 default: | 1320 default: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1333 // sizes > 1). | 1335 // sizes > 1). |
| 1334 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1336 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 1335 ? Location::RegisterOrSmiConstant(index()) | 1337 ? Location::RegisterOrSmiConstant(index()) |
| 1336 : Location::RequiresRegister()); | 1338 : Location::RequiresRegister()); |
| 1337 switch (class_id()) { | 1339 switch (class_id()) { |
| 1338 case kArrayCid: | 1340 case kArrayCid: |
| 1339 locs->set_in(2, ShouldEmitStoreBarrier() | 1341 locs->set_in(2, ShouldEmitStoreBarrier() |
| 1340 ? Location::WritableRegister() | 1342 ? Location::WritableRegister() |
| 1341 : Location::RegisterOrConstant(value())); | 1343 : Location::RegisterOrConstant(value())); |
| 1342 break; | 1344 break; |
| 1345 case kExternalUint8ArrayCid: |
| 1346 case kExternalUint8ClampedArrayCid: |
| 1347 // Need temp register to load the external array's data array. |
| 1348 locs->AddTemp(Location::RequiresRegister()); |
| 1349 // Fall through. |
| 1343 case kInt8ArrayCid: | 1350 case kInt8ArrayCid: |
| 1344 case kUint8ArrayCid: | 1351 case kUint8ArrayCid: |
| 1345 case kUint8ClampedArrayCid: | 1352 case kUint8ClampedArrayCid: |
| 1346 // TODO(fschneider): Add location constraint for byte registers (EAX, | 1353 // TODO(fschneider): Add location constraint for byte registers (EAX, |
| 1347 // EBX, ECX, EDX) instead of using a fixed register. | 1354 // EBX, ECX, EDX) instead of using a fixed register. |
| 1348 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); | 1355 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); |
| 1349 break; | 1356 break; |
| 1350 case kInt16ArrayCid: | 1357 case kInt16ArrayCid: |
| 1351 case kUint16ArrayCid: | 1358 case kUint16ArrayCid: |
| 1352 // Writable register because the value must be untagged before storing. | 1359 // Writable register because the value must be untagged before storing. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1369 return locs; | 1376 return locs; |
| 1370 } | 1377 } |
| 1371 | 1378 |
| 1372 | 1379 |
| 1373 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1380 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1374 Register array = locs()->in(0).reg(); | 1381 Register array = locs()->in(0).reg(); |
| 1375 Location index = locs()->in(1); | 1382 Location index = locs()->in(1); |
| 1376 | 1383 |
| 1377 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id()); | 1384 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id()); |
| 1378 | 1385 |
| 1379 FieldAddress element_address = index.IsRegister() ? | 1386 Address element_address(kNoRegister, 0); |
| 1380 FlowGraphCompiler::ElementAddressForRegIndex( | 1387 if ((class_id() == kExternalUint8ArrayCid) || |
| 1381 class_id(), index_scale, array, index.reg()) : | 1388 (class_id() == kExternalUint8ClampedArrayCid)) { |
| 1382 FlowGraphCompiler::ElementAddressForIntIndex( | 1389 Register temp = locs()->temp(0).reg(); |
| 1390 element_address = index.IsRegister() |
| 1391 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| 1392 class_id(), index_scale, temp, index.reg()) |
| 1393 : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| 1394 class_id(), index_scale, temp, |
| 1395 Smi::Cast(index.constant()).Value()); |
| 1396 __ movl(temp, |
| 1397 FieldAddress(array, ExternalUint8Array::data_offset())); |
| 1398 } else { |
| 1399 element_address = index.IsRegister() |
| 1400 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1401 class_id(), index_scale, array, index.reg()) |
| 1402 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1383 class_id(), index_scale, array, Smi::Cast(index.constant()).Value()); | 1403 class_id(), index_scale, array, Smi::Cast(index.constant()).Value()); |
| 1404 } |
| 1384 | 1405 |
| 1385 switch (class_id()) { | 1406 switch (class_id()) { |
| 1386 case kArrayCid: | 1407 case kArrayCid: |
| 1387 if (ShouldEmitStoreBarrier()) { | 1408 if (ShouldEmitStoreBarrier()) { |
| 1388 Register value = locs()->in(2).reg(); | 1409 Register value = locs()->in(2).reg(); |
| 1389 __ StoreIntoObject(array, element_address, value); | 1410 __ StoreIntoObject(array, element_address, value); |
| 1390 } else if (locs()->in(2).IsConstant()) { | 1411 } else if (locs()->in(2).IsConstant()) { |
| 1391 const Object& constant = locs()->in(2).constant(); | 1412 const Object& constant = locs()->in(2).constant(); |
| 1392 __ StoreIntoObjectNoBarrier(array, element_address, constant); | 1413 __ StoreIntoObjectNoBarrier(array, element_address, constant); |
| 1393 } else { | 1414 } else { |
| 1394 Register value = locs()->in(2).reg(); | 1415 Register value = locs()->in(2).reg(); |
| 1395 __ StoreIntoObjectNoBarrier(array, element_address, value); | 1416 __ StoreIntoObjectNoBarrier(array, element_address, value); |
| 1396 } | 1417 } |
| 1397 break; | 1418 break; |
| 1398 case kInt8ArrayCid: | 1419 case kInt8ArrayCid: |
| 1399 case kUint8ArrayCid: | 1420 case kUint8ArrayCid: |
| 1421 case kExternalUint8ArrayCid: |
| 1400 if (index.IsRegister()) { | 1422 if (index.IsRegister()) { |
| 1401 __ SmiUntag(index.reg()); | 1423 __ SmiUntag(index.reg()); |
| 1402 } | 1424 } |
| 1403 if (locs()->in(2).IsConstant()) { | 1425 if (locs()->in(2).IsConstant()) { |
| 1404 const Smi& constant = Smi::Cast(locs()->in(2).constant()); | 1426 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| 1405 __ movb(element_address, | 1427 __ movb(element_address, |
| 1406 Immediate(static_cast<int8_t>(constant.Value()))); | 1428 Immediate(static_cast<int8_t>(constant.Value()))); |
| 1407 } else { | 1429 } else { |
| 1408 ASSERT(locs()->in(2).reg() == EAX); | 1430 ASSERT(locs()->in(2).reg() == EAX); |
| 1409 __ SmiUntag(EAX); | 1431 __ SmiUntag(EAX); |
| 1410 __ movb(element_address, AL); | 1432 __ movb(element_address, AL); |
| 1411 } | 1433 } |
| 1412 if (index.IsRegister()) { | 1434 if (index.IsRegister()) { |
| 1413 __ SmiTag(index.reg()); // Re-tag. | 1435 __ SmiTag(index.reg()); // Re-tag. |
| 1414 } | 1436 } |
| 1415 break; | 1437 break; |
| 1416 case kUint8ClampedArrayCid: { | 1438 case kUint8ClampedArrayCid: |
| 1439 case kExternalUint8ClampedArrayCid: { |
| 1417 if (index.IsRegister()) { | 1440 if (index.IsRegister()) { |
| 1418 __ SmiUntag(index.reg()); | 1441 __ SmiUntag(index.reg()); |
| 1419 } | 1442 } |
| 1420 if (locs()->in(2).IsConstant()) { | 1443 if (locs()->in(2).IsConstant()) { |
| 1421 const Smi& constant = Smi::Cast(locs()->in(2).constant()); | 1444 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| 1422 intptr_t value = constant.Value(); | 1445 intptr_t value = constant.Value(); |
| 1423 // Clamp to 0x0 or 0xFF respectively. | 1446 // Clamp to 0x0 or 0xFF respectively. |
| 1424 if (value > 0xFF) { | 1447 if (value > 0xFF) { |
| 1425 value = 0xFF; | 1448 value = 0xFF; |
| 1426 } else if (value < 0) { | 1449 } else if (value < 0) { |
| (...skipping 1990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3417 PcDescriptors::kOther, | 3440 PcDescriptors::kOther, |
| 3418 locs()); | 3441 locs()); |
| 3419 __ Drop(2); // Discard type arguments and receiver. | 3442 __ Drop(2); // Discard type arguments and receiver. |
| 3420 } | 3443 } |
| 3421 | 3444 |
| 3422 } // namespace dart | 3445 } // namespace dart |
| 3423 | 3446 |
| 3424 #undef __ | 3447 #undef __ |
| 3425 | 3448 |
| 3426 #endif // defined TARGET_ARCH_IA32 | 3449 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |