iew_impl.hh (3795:60ecc96c3cee) iew_impl.hh (3867:807483cfab77)
1/*
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 467 unchanged lines hidden (view full) ---

476 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
477
478 toCommit->squash[tid] = true;
479 toCommit->squashedSeqNum[tid] = inst->seqNum;
480 toCommit->mispredPC[tid] = inst->readPC();
481 toCommit->branchMispredict[tid] = true;
482
483#if ISA_HAS_DELAY_SLOT
1/*
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 467 unchanged lines hidden (view full) ---

476 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
477
478 toCommit->squash[tid] = true;
479 toCommit->squashedSeqNum[tid] = inst->seqNum;
480 toCommit->mispredPC[tid] = inst->readPC();
481 toCommit->branchMispredict[tid] = true;
482
483#if ISA_HAS_DELAY_SLOT
484 int instSize = sizeof(TheISA::MachInst);
485 bool branch_taken =
486 !(inst->readNextPC() + instSize == inst->readNextNPC() &&
487 (inst->readNextPC() == inst->readPC() + instSize ||
488 inst->readNextPC() == inst->readPC() + 2 * instSize));
489 DPRINTF(Sparc, "Branch taken = %s [sn:%i]\n",
490 branch_taken ? "true": "false", inst->seqNum);
484 bool branch_taken = inst->readNextNPC() !=
485 (inst->readNextPC() + sizeof(TheISA::MachInst));
491
492 toCommit->branchTaken[tid] = branch_taken;
493
486
487 toCommit->branchTaken[tid] = branch_taken;
488
494 bool squashDelaySlot = true;
495// (inst->readNextPC() != inst->readPC() + sizeof(TheISA::MachInst));
496 DPRINTF(Sparc, "Squash delay slot = %s [sn:%i]\n",
497 squashDelaySlot ? "true": "false", inst->seqNum);
498 toCommit->squashDelaySlot[tid] = squashDelaySlot;
499 //If we're squashing the delay slot, we need to pick back up at NextPC.
500 //Otherwise, NextPC isn't being squashed, so we should pick back up at
501 //NextNPC.
502 if (squashDelaySlot) {
489 toCommit->condDelaySlotBranch[tid] = inst->isCondDelaySlot();
490
491 if (inst->isCondDelaySlot() && branch_taken) {
503 toCommit->nextPC[tid] = inst->readNextPC();
492 toCommit->nextPC[tid] = inst->readNextPC();
504 toCommit->nextNPC[tid] = inst->readNextNPC();
505 } else
493 } else {
506 toCommit->nextPC[tid] = inst->readNextNPC();
494 toCommit->nextPC[tid] = inst->readNextNPC();
495 }
507#else
508 toCommit->branchTaken[tid] = inst->readNextPC() !=
509 (inst->readPC() + sizeof(TheISA::MachInst));
510 toCommit->nextPC[tid] = inst->readNextPC();
511#endif
512
513 toCommit->includeSquashInst[tid] = false;
514

--- 5 unchanged lines hidden (view full) ---

520DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
521{
522 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
523 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
524
525 toCommit->squash[tid] = true;
526 toCommit->squashedSeqNum[tid] = inst->seqNum;
527 toCommit->nextPC[tid] = inst->readNextPC();
496#else
497 toCommit->branchTaken[tid] = inst->readNextPC() !=
498 (inst->readPC() + sizeof(TheISA::MachInst));
499 toCommit->nextPC[tid] = inst->readNextPC();
500#endif
501
502 toCommit->includeSquashInst[tid] = false;
503

--- 5 unchanged lines hidden (view full) ---

509DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
510{
511 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
512 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
513
514 toCommit->squash[tid] = true;
515 toCommit->squashedSeqNum[tid] = inst->seqNum;
516 toCommit->nextPC[tid] = inst->readNextPC();
528#if ISA_HAS_DELAY_SLOT
529 toCommit->nextNPC[tid] = inst->readNextNPC();
530#endif
517 toCommit->branchMispredict[tid] = false;
531
532 toCommit->includeSquashInst[tid] = false;
533
534 wroteToTimeBuffer = true;
535}
536
537template<class Impl>
538void
539DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
540{
541 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
542 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
543
544 toCommit->squash[tid] = true;
545 toCommit->squashedSeqNum[tid] = inst->seqNum;
546 toCommit->nextPC[tid] = inst->readPC();
518
519 toCommit->includeSquashInst[tid] = false;
520
521 wroteToTimeBuffer = true;
522}
523
524template<class Impl>
525void
526DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
527{
528 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
529 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
530
531 toCommit->squash[tid] = true;
532 toCommit->squashedSeqNum[tid] = inst->seqNum;
533 toCommit->nextPC[tid] = inst->readPC();
547#if ISA_HAS_DELAY_SLOT
548 toCommit->nextNPC[tid] = inst->readNextNPC();
549#endif
534 toCommit->branchMispredict[tid] = false;
550
551 // Must include the broadcasted SN in the squash.
552 toCommit->includeSquashInst[tid] = true;
553
554 ldstQueue.setLoadBlockedHandled(tid);
555
556 wroteToTimeBuffer = true;
557}

--- 123 unchanged lines hidden (view full) ---

681}
682
683template<class Impl>
684int
685DefaultIEW<Impl>::skidCount()
686{
687 int max=0;
688
535
536 // Must include the broadcasted SN in the squash.
537 toCommit->includeSquashInst[tid] = true;
538
539 ldstQueue.setLoadBlockedHandled(tid);
540
541 wroteToTimeBuffer = true;
542}

--- 123 unchanged lines hidden (view full) ---

666}
667
668template<class Impl>
669int
670DefaultIEW<Impl>::skidCount()
671{
672 int max=0;
673
689 std::list<unsigned>::iterator threads = (*activeThreads).begin();
674 std::list<unsigned>::iterator threads = activeThreads->begin();
675 std::list<unsigned>::iterator end = activeThreads->end();
690
676
691 while (threads != (*activeThreads).end()) {
692 unsigned thread_count = skidBuffer[*threads++].size();
677 while (threads != end) {
678 unsigned tid = *threads++;
679 unsigned thread_count = skidBuffer[tid].size();
693 if (max < thread_count)
694 max = thread_count;
695 }
696
697 return max;
698}
699
700template<class Impl>
701bool
702DefaultIEW<Impl>::skidsEmpty()
703{
680 if (max < thread_count)
681 max = thread_count;
682 }
683
684 return max;
685}
686
687template<class Impl>
688bool
689DefaultIEW<Impl>::skidsEmpty()
690{
704 std::list<unsigned>::iterator threads = (*activeThreads).begin();
691 std::list<unsigned>::iterator threads = activeThreads->begin();
692 std::list<unsigned>::iterator end = activeThreads->end();
705
693
706 while (threads != (*activeThreads).end()) {
707 if (!skidBuffer[*threads++].empty())
694 while (threads != end) {
695 unsigned tid = *threads++;
696
697 if (!skidBuffer[tid].empty())
708 return false;
709 }
710
711 return true;
712}
713
714template <class Impl>
715void
716DefaultIEW<Impl>::updateStatus()
717{
718 bool any_unblocking = false;
719
698 return false;
699 }
700
701 return true;
702}
703
704template <class Impl>
705void
706DefaultIEW<Impl>::updateStatus()
707{
708 bool any_unblocking = false;
709
720 std::list<unsigned>::iterator threads = (*activeThreads).begin();
710 std::list<unsigned>::iterator threads = activeThreads->begin();
711 std::list<unsigned>::iterator end = activeThreads->end();
721
712
722 threads = (*activeThreads).begin();
723
724 while (threads != (*activeThreads).end()) {
713 while (threads != end) {
725 unsigned tid = *threads++;
726
727 if (dispatchStatus[tid] == Unblocking) {
728 any_unblocking = true;
729 break;
730 }
731 }
732

--- 503 unchanged lines hidden (view full) ---

1236
1237template <class Impl>
1238void
1239DefaultIEW<Impl>::executeInsts()
1240{
1241 wbNumInst = 0;
1242 wbCycle = 0;
1243
714 unsigned tid = *threads++;
715
716 if (dispatchStatus[tid] == Unblocking) {
717 any_unblocking = true;
718 break;
719 }
720 }
721

--- 503 unchanged lines hidden (view full) ---

1225
1226template <class Impl>
1227void
1228DefaultIEW<Impl>::executeInsts()
1229{
1230 wbNumInst = 0;
1231 wbCycle = 0;
1232
1244 std::list<unsigned>::iterator threads = (*activeThreads).begin();
1233 std::list<unsigned>::iterator threads = activeThreads->begin();
1234 std::list<unsigned>::iterator end = activeThreads->end();
1245
1235
1246 while (threads != (*activeThreads).end()) {
1236 while (threads != end) {
1247 unsigned tid = *threads++;
1248 fetchRedirect[tid] = false;
1249 }
1250
1251 // Uncomment this if you want to see all available instructions.
1252// printAvailableInsts();
1253
1254 // Execute/writeback any instructions that are available.

--- 48 unchanged lines hidden (view full) ---

1303 // If the store had a fault then it may not have a mem req
1304 if (!inst->isStoreConditional() && fault == NoFault) {
1305 inst->setExecuted();
1306
1307 instToCommit(inst);
1308 } else if (fault != NoFault) {
1309 // If the instruction faulted, then we need to send it along to commit
1310 // without the instruction completing.
1237 unsigned tid = *threads++;
1238 fetchRedirect[tid] = false;
1239 }
1240
1241 // Uncomment this if you want to see all available instructions.
1242// printAvailableInsts();
1243
1244 // Execute/writeback any instructions that are available.

--- 48 unchanged lines hidden (view full) ---

1293 // If the store had a fault then it may not have a mem req
1294 if (!inst->isStoreConditional() && fault == NoFault) {
1295 inst->setExecuted();
1296
1297 instToCommit(inst);
1298 } else if (fault != NoFault) {
1299 // If the instruction faulted, then we need to send it along to commit
1300 // without the instruction completing.
1311 DPRINTF(IEW, "Store has fault! [sn:%lli]\n", inst->seqNum);
1301 DPRINTF(IEW, "Store has fault %s! [sn:%lli]\n",
1302 fault->name(), inst->seqNum);
1312
1313 // Send this instruction to commit, also make sure iew stage
1314 // realizes there is activity.
1315 inst->setExecuted();
1316
1317 instToCommit(inst);
1318 activityThisCycle();
1319 }

--- 20 unchanged lines hidden (view full) ---

1340 // handle this if there hasn't already been something that
1341 // redirects fetch in this group of instructions.
1342
1343 // This probably needs to prioritize the redirects if a different
1344 // scheduler is used. Currently the scheduler schedules the oldest
1345 // instruction first, so the branch resolution order will be correct.
1346 unsigned tid = inst->threadNumber;
1347
1303
1304 // Send this instruction to commit, also make sure iew stage
1305 // realizes there is activity.
1306 inst->setExecuted();
1307
1308 instToCommit(inst);
1309 activityThisCycle();
1310 }

--- 20 unchanged lines hidden (view full) ---

1331 // handle this if there hasn't already been something that
1332 // redirects fetch in this group of instructions.
1333
1334 // This probably needs to prioritize the redirects if a different
1335 // scheduler is used. Currently the scheduler schedules the oldest
1336 // instruction first, so the branch resolution order will be correct.
1337 unsigned tid = inst->threadNumber;
1338
1348 if (!fetchRedirect[tid]) {
1339 if (!fetchRedirect[tid] ||
1340 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1349
1350 if (inst->mispredicted()) {
1351 fetchRedirect[tid] = true;
1352
1353 DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1341
1342 if (inst->mispredicted()) {
1343 fetchRedirect[tid] = true;
1344
1345 DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1354 DPRINTF(IEW, "Predicted target was %#x.\n", inst->predPC);
1355#if ISA_HAS_DELAY_SLOT
1356 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
1357 inst->nextNPC);
1358#else
1359 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
1360 inst->nextPC);
1361#endif
1362 // If incorrect, then signal the ROB that it must be squashed.
1363 squashDueToBranch(inst, tid);
1364
1346#if ISA_HAS_DELAY_SLOT
1347 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
1348 inst->nextNPC);
1349#else
1350 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
1351 inst->nextPC);
1352#endif
1353 // If incorrect, then signal the ROB that it must be squashed.
1354 squashDueToBranch(inst, tid);
1355
1365 if (inst->readPredTaken()) {
1356 if (inst->predTaken()) {
1366 predictedTakenIncorrect++;
1367 } else {
1368 predictedNotTakenIncorrect++;
1369 }
1370 } else if (ldstQueue.violation(tid)) {
1357 predictedTakenIncorrect++;
1358 } else {
1359 predictedNotTakenIncorrect++;
1360 }
1361 } else if (ldstQueue.violation(tid)) {
1371 fetchRedirect[tid] = true;
1372
1373 // If there was an ordering violation, then get the
1374 // DynInst that caused the violation. Note that this
1375 // clears the violation signal.
1376 DynInstPtr violator;
1377 violator = ldstQueue.getMemDepViolator(tid);
1378
1379 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: "
1380 "%#x, inst PC: %#x. Addr is: %#x.\n",
1381 violator->readPC(), inst->readPC(), inst->physEffAddr);
1382
1362 // If there was an ordering violation, then get the
1363 // DynInst that caused the violation. Note that this
1364 // clears the violation signal.
1365 DynInstPtr violator;
1366 violator = ldstQueue.getMemDepViolator(tid);
1367
1368 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: "
1369 "%#x, inst PC: %#x. Addr is: %#x.\n",
1370 violator->readPC(), inst->readPC(), inst->physEffAddr);
1371
1372 // Ensure the violating instruction is older than
1373 // current squash
1374 if (fetchRedirect[tid] &&
1375 violator->seqNum >= toCommit->squashedSeqNum[tid])
1376 continue;
1377
1378 fetchRedirect[tid] = true;
1379
1383 // Tell the instruction queue that a violation has occured.
1384 instQueue.violation(inst, violator);
1385
1386 // Squash.
1387 squashDueToMemOrder(inst,tid);
1388
1389 ++memOrderViolationEvents;
1390 } else if (ldstQueue.loadBlocked(tid) &&

--- 81 unchanged lines hidden (view full) ---

1472 wroteToTimeBuffer = false;
1473 updatedQueues = false;
1474
1475 sortInsts();
1476
1477 // Free function units marked as being freed this cycle.
1478 fuPool->processFreeUnits();
1479
1380 // Tell the instruction queue that a violation has occured.
1381 instQueue.violation(inst, violator);
1382
1383 // Squash.
1384 squashDueToMemOrder(inst,tid);
1385
1386 ++memOrderViolationEvents;
1387 } else if (ldstQueue.loadBlocked(tid) &&

--- 81 unchanged lines hidden (view full) ---

1469 wroteToTimeBuffer = false;
1470 updatedQueues = false;
1471
1472 sortInsts();
1473
1474 // Free function units marked as being freed this cycle.
1475 fuPool->processFreeUnits();
1476
1480 std::list<unsigned>::iterator threads = (*activeThreads).begin();
1477 std::list<unsigned>::iterator threads = activeThreads->begin();
1478 std::list<unsigned>::iterator end = activeThreads->end();
1481
1482 // Check stall and squash signals, dispatch any instructions.
1479
1480 // Check stall and squash signals, dispatch any instructions.
1483 while (threads != (*activeThreads).end()) {
1484 unsigned tid = *threads++;
1481 while (threads != end) {
1482 unsigned tid = *threads++;
1485
1486 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
1487
1488 checkSignalsAndUpdate(tid);
1489 dispatch(tid);
1490 }
1491
1492 if (exeStatus != Squashing) {

--- 23 unchanged lines hidden (view full) ---

1516 // Writeback any stores using any leftover bandwidth.
1517 ldstQueue.writebackStores();
1518
1519 // Check the committed load/store signals to see if there's a load
1520 // or store to commit. Also check if it's being told to execute a
1521 // nonspeculative instruction.
1522 // This is pretty inefficient...
1523
1483
1484 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
1485
1486 checkSignalsAndUpdate(tid);
1487 dispatch(tid);
1488 }
1489
1490 if (exeStatus != Squashing) {

--- 23 unchanged lines hidden (view full) ---

1514 // Writeback any stores using any leftover bandwidth.
1515 ldstQueue.writebackStores();
1516
1517 // Check the committed load/store signals to see if there's a load
1518 // or store to commit. Also check if it's being told to execute a
1519 // nonspeculative instruction.
1520 // This is pretty inefficient...
1521
1524 threads = (*activeThreads).begin();
1525 while (threads != (*activeThreads).end()) {
1522 threads = activeThreads->begin();
1523 while (threads != end) {
1526 unsigned tid = (*threads++);
1527
1528 DPRINTF(IEW,"Processing [tid:%i]\n",tid);
1529
1530 // Update structures based on instructions committed.
1531 if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
1532 !fromCommit->commitInfo[tid].squash &&
1533 !fromCommit->commitInfo[tid].robSquashing) {

--- 88 unchanged lines hidden ---
1524 unsigned tid = (*threads++);
1525
1526 DPRINTF(IEW,"Processing [tid:%i]\n",tid);
1527
1528 // Update structures based on instructions committed.
1529 if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
1530 !fromCommit->commitInfo[tid].squash &&
1531 !fromCommit->commitInfo[tid].robSquashing) {

--- 88 unchanged lines hidden ---