| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 ASSERT(offset == (xmm_regs_count * kDoubleSize)); | 1333 ASSERT(offset == (xmm_regs_count * kDoubleSize)); |
| 1334 __ addq(RSP, Immediate(offset)); | 1334 __ addq(RSP, Immediate(offset)); |
| 1335 } | 1335 } |
| 1336 } | 1336 } |
| 1337 | 1337 |
| 1338 | 1338 |
| 1339 #undef __ | 1339 #undef __ |
| 1340 #define __ compiler_->assembler()-> | 1340 #define __ compiler_->assembler()-> |
| 1341 | 1341 |
| 1342 | 1342 |
| 1343 static Address ToStackSlotAddress(Location loc) { | |
| 1344 const intptr_t index = loc.stack_index(); | |
| 1345 if (index < 0) { | |
| 1346 const intptr_t offset = (1 - index) * kWordSize; | |
| 1347 return Address(RBP, offset); | |
| 1348 } else { | |
| 1349 const intptr_t offset = | |
| 1350 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize; | |
| 1351 return Address(RBP, offset); | |
| 1352 } | |
| 1353 } | |
| 1354 | |
| 1355 | |
| 1356 void ParallelMoveResolver::EmitMove(int index) { | 1343 void ParallelMoveResolver::EmitMove(int index) { |
| 1357 MoveOperands* move = moves_[index]; | 1344 MoveOperands* move = moves_[index]; |
| 1358 const Location source = move->src(); | 1345 const Location source = move->src(); |
| 1359 const Location destination = move->dest(); | 1346 const Location destination = move->dest(); |
| 1360 | 1347 |
| 1361 if (source.IsRegister()) { | 1348 if (source.IsRegister()) { |
| 1362 if (destination.IsRegister()) { | 1349 if (destination.IsRegister()) { |
| 1363 __ movq(destination.reg(), source.reg()); | 1350 __ movq(destination.reg(), source.reg()); |
| 1364 } else { | 1351 } else { |
| 1365 ASSERT(destination.IsStackSlot()); | 1352 ASSERT(destination.IsStackSlot()); |
| 1366 __ movq(ToStackSlotAddress(destination), source.reg()); | 1353 __ movq(destination.ToStackSlotAddress(), source.reg()); |
| 1367 } | 1354 } |
| 1368 } else if (source.IsStackSlot()) { | 1355 } else if (source.IsStackSlot()) { |
| 1369 if (destination.IsRegister()) { | 1356 if (destination.IsRegister()) { |
| 1370 __ movq(destination.reg(), ToStackSlotAddress(source)); | 1357 __ movq(destination.reg(), source.ToStackSlotAddress()); |
| 1371 } else { | 1358 } else { |
| 1372 ASSERT(destination.IsStackSlot()); | 1359 ASSERT(destination.IsStackSlot()); |
| 1373 MoveMemoryToMemory(ToStackSlotAddress(destination), | 1360 MoveMemoryToMemory(destination.ToStackSlotAddress(), |
| 1374 ToStackSlotAddress(source)); | 1361 source.ToStackSlotAddress()); |
| 1375 } | 1362 } |
| 1376 } else if (source.IsXmmRegister()) { | 1363 } else if (source.IsXmmRegister()) { |
| 1377 if (destination.IsXmmRegister()) { | 1364 if (destination.IsXmmRegister()) { |
| 1378 // Optimization manual recommends using MOVAPS for register | 1365 // Optimization manual recommends using MOVAPS for register |
| 1379 // to register moves. | 1366 // to register moves. |
| 1380 __ movaps(destination.xmm_reg(), source.xmm_reg()); | 1367 __ movaps(destination.xmm_reg(), source.xmm_reg()); |
| 1381 } else { | 1368 } else { |
| 1382 ASSERT(destination.IsDoubleStackSlot()); | 1369 ASSERT(destination.IsDoubleStackSlot()); |
| 1383 __ movsd(ToStackSlotAddress(destination), source.xmm_reg()); | 1370 __ movsd(destination.ToStackSlotAddress(), source.xmm_reg()); |
| 1384 } | 1371 } |
| 1385 } else if (source.IsDoubleStackSlot()) { | 1372 } else if (source.IsDoubleStackSlot()) { |
| 1386 if (destination.IsXmmRegister()) { | 1373 if (destination.IsXmmRegister()) { |
| 1387 __ movsd(destination.xmm_reg(), ToStackSlotAddress(source)); | 1374 __ movsd(destination.xmm_reg(), source.ToStackSlotAddress()); |
| 1388 } else { | 1375 } else { |
| 1389 ASSERT(destination.IsDoubleStackSlot()); | 1376 ASSERT(destination.IsDoubleStackSlot()); |
| 1390 __ movsd(XMM0, ToStackSlotAddress(source)); | 1377 __ movsd(XMM0, source.ToStackSlotAddress()); |
| 1391 __ movsd(ToStackSlotAddress(destination), XMM0); | 1378 __ movsd(destination.ToStackSlotAddress(), XMM0); |
| 1392 } | 1379 } |
| 1393 } else { | 1380 } else { |
| 1394 ASSERT(source.IsConstant()); | 1381 ASSERT(source.IsConstant()); |
| 1395 if (destination.IsRegister()) { | 1382 if (destination.IsRegister()) { |
| 1396 const Object& constant = source.constant(); | 1383 const Object& constant = source.constant(); |
| 1397 if (constant.IsSmi() && (Smi::Cast(constant).Value() == 0)) { | 1384 if (constant.IsSmi() && (Smi::Cast(constant).Value() == 0)) { |
| 1398 __ xorq(destination.reg(), destination.reg()); | 1385 __ xorq(destination.reg(), destination.reg()); |
| 1399 } else { | 1386 } else { |
| 1400 __ LoadObject(destination.reg(), constant); | 1387 __ LoadObject(destination.reg(), constant); |
| 1401 } | 1388 } |
| 1402 } else { | 1389 } else { |
| 1403 ASSERT(destination.IsStackSlot()); | 1390 ASSERT(destination.IsStackSlot()); |
| 1404 StoreObject(ToStackSlotAddress(destination), source.constant()); | 1391 StoreObject(destination.ToStackSlotAddress(), source.constant()); |
| 1405 } | 1392 } |
| 1406 } | 1393 } |
| 1407 | 1394 |
| 1408 move->Eliminate(); | 1395 move->Eliminate(); |
| 1409 } | 1396 } |
| 1410 | 1397 |
| 1411 | 1398 |
| 1412 void ParallelMoveResolver::EmitSwap(int index) { | 1399 void ParallelMoveResolver::EmitSwap(int index) { |
| 1413 MoveOperands* move = moves_[index]; | 1400 MoveOperands* move = moves_[index]; |
| 1414 const Location source = move->src(); | 1401 const Location source = move->src(); |
| 1415 const Location destination = move->dest(); | 1402 const Location destination = move->dest(); |
| 1416 | 1403 |
| 1417 if (source.IsRegister() && destination.IsRegister()) { | 1404 if (source.IsRegister() && destination.IsRegister()) { |
| 1418 __ xchgq(destination.reg(), source.reg()); | 1405 __ xchgq(destination.reg(), source.reg()); |
| 1419 } else if (source.IsRegister() && destination.IsStackSlot()) { | 1406 } else if (source.IsRegister() && destination.IsStackSlot()) { |
| 1420 Exchange(source.reg(), ToStackSlotAddress(destination)); | 1407 Exchange(source.reg(), destination.ToStackSlotAddress()); |
| 1421 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1408 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1422 Exchange(destination.reg(), ToStackSlotAddress(source)); | 1409 Exchange(destination.reg(), source.ToStackSlotAddress()); |
| 1423 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1410 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1424 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source)); | 1411 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); |
| 1425 } else if (source.IsXmmRegister() && destination.IsXmmRegister()) { | 1412 } else if (source.IsXmmRegister() && destination.IsXmmRegister()) { |
| 1426 __ movaps(XMM0, source.xmm_reg()); | 1413 __ movaps(XMM0, source.xmm_reg()); |
| 1427 __ movaps(source.xmm_reg(), destination.xmm_reg()); | 1414 __ movaps(source.xmm_reg(), destination.xmm_reg()); |
| 1428 __ movaps(destination.xmm_reg(), XMM0); | 1415 __ movaps(destination.xmm_reg(), XMM0); |
| 1429 } else if (source.IsXmmRegister() || destination.IsXmmRegister()) { | 1416 } else if (source.IsXmmRegister() || destination.IsXmmRegister()) { |
| 1430 ASSERT(destination.IsDoubleStackSlot() || source.IsDoubleStackSlot()); | 1417 ASSERT(destination.IsDoubleStackSlot() || source.IsDoubleStackSlot()); |
| 1431 XmmRegister reg = source.IsXmmRegister() ? source.xmm_reg() | 1418 XmmRegister reg = source.IsXmmRegister() ? source.xmm_reg() |
| 1432 : destination.xmm_reg(); | 1419 : destination.xmm_reg(); |
| 1433 Address slot_address = | 1420 Address slot_address = source.IsXmmRegister() |
| 1434 ToStackSlotAddress(source.IsXmmRegister() ? destination : source); | 1421 ? destination.ToStackSlotAddress() |
| 1422 : source.ToStackSlotAddress(); |
| 1435 | 1423 |
| 1436 __ movsd(XMM0, slot_address); | 1424 __ movsd(XMM0, slot_address); |
| 1437 __ movsd(slot_address, reg); | 1425 __ movsd(slot_address, reg); |
| 1438 __ movaps(reg, XMM0); | 1426 __ movaps(reg, XMM0); |
| 1439 } else { | 1427 } else { |
| 1440 UNREACHABLE(); | 1428 UNREACHABLE(); |
| 1441 } | 1429 } |
| 1442 | 1430 |
| 1443 // The swap of source and destination has executed a move from source to | 1431 // The swap of source and destination has executed a move from source to |
| 1444 // destination. | 1432 // destination. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1465 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1478 __ Exchange(mem1, mem2); | 1466 __ Exchange(mem1, mem2); |
| 1479 } | 1467 } |
| 1480 | 1468 |
| 1481 | 1469 |
| 1482 #undef __ | 1470 #undef __ |
| 1483 | 1471 |
| 1484 } // namespace dart | 1472 } // namespace dart |
| 1485 | 1473 |
| 1486 #endif // defined TARGET_ARCH_X64 | 1474 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |