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 |