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 --- |