iew_impl.hh (7616:1a0ab2308bbe) iew_impl.hh (7720:65d338a8dba4)
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

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

444
445 emptyRenameInsts(tid);
446}
447
448template<class Impl>
449void
450DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
451{
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

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

444
445 emptyRenameInsts(tid);
446}
447
448template<class Impl>
449void
450DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
451{
452 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x "
453 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
452 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %s "
453 "[sn:%i].\n", tid, inst->pcState(), inst->seqNum);
454
455 toCommit->squash[tid] = true;
456 toCommit->squashedSeqNum[tid] = inst->seqNum;
454
455 toCommit->squash[tid] = true;
456 toCommit->squashedSeqNum[tid] = inst->seqNum;
457 toCommit->mispredPC[tid] = inst->readPC();
457 toCommit->mispredPC[tid] = inst->instAddr();
458 toCommit->branchMispredict[tid] = true;
459
458 toCommit->branchMispredict[tid] = true;
459
460#if ISA_HAS_DELAY_SLOT
461 int instSize = sizeof(TheISA::MachInst);
462 toCommit->branchTaken[tid] =
463 !(inst->readNextPC() + instSize == inst->readNextNPC() &&
464 (inst->readNextPC() == inst->readPC() + instSize ||
465 inst->readNextPC() == inst->readPC() + 2 * instSize));
466#else
467 toCommit->branchTaken[tid] = inst->readNextPC() !=
468 (inst->readPC() + sizeof(TheISA::MachInst));
469#endif
470 toCommit->nextPC[tid] = inst->readNextPC();
471 toCommit->nextNPC[tid] = inst->readNextNPC();
472 toCommit->nextMicroPC[tid] = inst->readNextMicroPC();
460 toCommit->branchTaken[tid] = inst->pcState().branching();
461 TheISA::PCState pc = inst->pcState();
462 TheISA::advancePC(pc, inst->staticInst);
463 toCommit->pc[tid] = pc;
473
474 toCommit->includeSquashInst[tid] = false;
475
476 wroteToTimeBuffer = true;
477}
478
479template<class Impl>
480void
481DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
482{
483 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
464
465 toCommit->includeSquashInst[tid] = false;
466
467 wroteToTimeBuffer = true;
468}
469
470template<class Impl>
471void
472DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
473{
474 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
484 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
475 "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
485
486 toCommit->squash[tid] = true;
487 toCommit->squashedSeqNum[tid] = inst->seqNum;
476
477 toCommit->squash[tid] = true;
478 toCommit->squashedSeqNum[tid] = inst->seqNum;
488 toCommit->nextPC[tid] = inst->readNextPC();
489 toCommit->nextNPC[tid] = inst->readNextNPC();
479 TheISA::PCState pc = inst->pcState();
480 TheISA::advancePC(pc, inst->staticInst);
481 toCommit->pc[tid] = pc;
490 toCommit->branchMispredict[tid] = false;
491
492 toCommit->includeSquashInst[tid] = false;
493
494 wroteToTimeBuffer = true;
495}
496
497template<class Impl>
498void
499DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid)
500{
501 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
482 toCommit->branchMispredict[tid] = false;
483
484 toCommit->includeSquashInst[tid] = false;
485
486 wroteToTimeBuffer = true;
487}
488
489template<class Impl>
490void
491DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid)
492{
493 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
502 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
494 "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
503
504 toCommit->squash[tid] = true;
505 toCommit->squashedSeqNum[tid] = inst->seqNum;
495
496 toCommit->squash[tid] = true;
497 toCommit->squashedSeqNum[tid] = inst->seqNum;
506 toCommit->nextPC[tid] = inst->readPC();
507 toCommit->nextNPC[tid] = inst->readNextPC();
498 toCommit->pc[tid] = inst->pcState();
508 toCommit->branchMispredict[tid] = false;
509
510 // Must include the broadcasted SN in the squash.
511 toCommit->includeSquashInst[tid] = true;
512
513 ldstQueue.setLoadBlockedHandled(tid);
514
515 wroteToTimeBuffer = true;

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

623{
624 DynInstPtr inst = NULL;
625
626 while (!insts[tid].empty()) {
627 inst = insts[tid].front();
628
629 insts[tid].pop();
630
499 toCommit->branchMispredict[tid] = false;
500
501 // Must include the broadcasted SN in the squash.
502 toCommit->includeSquashInst[tid] = true;
503
504 ldstQueue.setLoadBlockedHandled(tid);
505
506 wroteToTimeBuffer = true;

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

614{
615 DynInstPtr inst = NULL;
616
617 while (!insts[tid].empty()) {
618 inst = insts[tid].front();
619
620 insts[tid].pop();
621
631 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into "
622 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%s into "
632 "dispatch skidBuffer %i\n",tid, inst->seqNum,
623 "dispatch skidBuffer %i\n",tid, inst->seqNum,
633 inst->readPC(),tid);
624 inst->pcState(),tid);
634
635 skidBuffer[tid].push(inst);
636 }
637
638 assert(skidBuffer[tid].size() <= skidBufferMax &&
639 "Skidbuffer Exceeded Max Size");
640}
641

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

981 if (dispatchStatus[tid] == Unblocking) {
982 DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid "
983 "buffer\n", tid);
984 }
985
986 // Make sure there's a valid instruction there.
987 assert(inst);
988
625
626 skidBuffer[tid].push(inst);
627 }
628
629 assert(skidBuffer[tid].size() <= skidBufferMax &&
630 "Skidbuffer Exceeded Max Size");
631}
632

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

972 if (dispatchStatus[tid] == Unblocking) {
973 DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid "
974 "buffer\n", tid);
975 }
976
977 // Make sure there's a valid instruction there.
978 assert(inst);
979
989 DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to "
980 DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %s [sn:%lli] [tid:%i] to "
990 "IQ.\n",
981 "IQ.\n",
991 tid, inst->readPC(), inst->seqNum, inst->threadNumber);
982 tid, inst->pcState(), inst->seqNum, inst->threadNumber);
992
993 // Be sure to mark these instructions as ready so that the
994 // commit stage can go ahead and execute them, and mark
995 // them as issued so the IQ doesn't reprocess them.
996
997 // Check for squashed instructions.
998 if (inst->isSquashed()) {
999 DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, "

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

1160 int inst = 0;
1161
1162 std::cout << "Available Instructions: ";
1163
1164 while (fromIssue->insts[inst]) {
1165
1166 if (inst%3==0) std::cout << "\n\t";
1167
983
984 // Be sure to mark these instructions as ready so that the
985 // commit stage can go ahead and execute them, and mark
986 // them as issued so the IQ doesn't reprocess them.
987
988 // Check for squashed instructions.
989 if (inst->isSquashed()) {
990 DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, "

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

1151 int inst = 0;
1152
1153 std::cout << "Available Instructions: ";
1154
1155 while (fromIssue->insts[inst]) {
1156
1157 if (inst%3==0) std::cout << "\n\t";
1158
1168 std::cout << "PC: " << fromIssue->insts[inst]->readPC()
1159 std::cout << "PC: " << fromIssue->insts[inst]->pcState()
1169 << " TN: " << fromIssue->insts[inst]->threadNumber
1170 << " SN: " << fromIssue->insts[inst]->seqNum << " | ";
1171
1172 inst++;
1173
1174 }
1175
1176 std::cout << "\n";

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

1200 int inst_num = 0;
1201 for (; inst_num < insts_to_execute;
1202 ++inst_num) {
1203
1204 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
1205
1206 DynInstPtr inst = instQueue.getInstToExecute();
1207
1160 << " TN: " << fromIssue->insts[inst]->threadNumber
1161 << " SN: " << fromIssue->insts[inst]->seqNum << " | ";
1162
1163 inst++;
1164
1165 }
1166
1167 std::cout << "\n";

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

1191 int inst_num = 0;
1192 for (; inst_num < insts_to_execute;
1193 ++inst_num) {
1194
1195 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
1196
1197 DynInstPtr inst = instQueue.getInstToExecute();
1198
1208 DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n",
1209 inst->readPC(), inst->threadNumber,inst->seqNum);
1199 DPRINTF(IEW, "Execute: Processing PC %s, [tid:%i] [sn:%i].\n",
1200 inst->pcState(), inst->threadNumber,inst->seqNum);
1210
1211 // Check if the instruction is squashed; if so then skip it
1212 if (inst->isSquashed()) {
1213 DPRINTF(IEW, "Execute: Instruction was squashed.\n");
1214
1215 // Consider this instruction executed so that commit can go
1216 // ahead and retire the instruction.
1217 inst->setExecuted();

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

1293 if (!fetchRedirect[tid] ||
1294 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1295
1296 if (inst->mispredicted()) {
1297 fetchRedirect[tid] = true;
1298
1299 DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1300 DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
1201
1202 // Check if the instruction is squashed; if so then skip it
1203 if (inst->isSquashed()) {
1204 DPRINTF(IEW, "Execute: Instruction was squashed.\n");
1205
1206 // Consider this instruction executed so that commit can go
1207 // ahead and retire the instruction.
1208 inst->setExecuted();

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

1284 if (!fetchRedirect[tid] ||
1285 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1286
1287 if (inst->mispredicted()) {
1288 fetchRedirect[tid] = true;
1289
1290 DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1291 DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
1301 inst->readPredPC(), inst->readPredNPC());
1302 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
1303 " NPC: %#x.\n", inst->readNextPC(),
1304 inst->readNextNPC());
1292 inst->predInstAddr(), inst->predNextInstAddr());
1293 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %s.\n",
1294 inst->pcState(), inst->nextInstAddr());
1305 // If incorrect, then signal the ROB that it must be squashed.
1306 squashDueToBranch(inst, tid);
1307
1308 if (inst->readPredTaken()) {
1309 predictedTakenIncorrect++;
1310 } else {
1311 predictedNotTakenIncorrect++;
1312 }
1313 } else if (ldstQueue.violation(tid)) {
1314 assert(inst->isMemRef());
1315 // If there was an ordering violation, then get the
1316 // DynInst that caused the violation. Note that this
1317 // clears the violation signal.
1318 DynInstPtr violator;
1319 violator = ldstQueue.getMemDepViolator(tid);
1320
1295 // If incorrect, then signal the ROB that it must be squashed.
1296 squashDueToBranch(inst, tid);
1297
1298 if (inst->readPredTaken()) {
1299 predictedTakenIncorrect++;
1300 } else {
1301 predictedNotTakenIncorrect++;
1302 }
1303 } else if (ldstQueue.violation(tid)) {
1304 assert(inst->isMemRef());
1305 // If there was an ordering violation, then get the
1306 // DynInst that caused the violation. Note that this
1307 // clears the violation signal.
1308 DynInstPtr violator;
1309 violator = ldstQueue.getMemDepViolator(tid);
1310
1321 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %#x "
1322 "[sn:%lli], inst PC: %#x [sn:%lli]. Addr is: %#x.\n",
1323 violator->readPC(), violator->seqNum,
1324 inst->readPC(), inst->seqNum, inst->physEffAddr);
1325 // Ensure the violating instruction is older than
1326 // current squash
1327/* if (fetchRedirect[tid] &&
1328 violator->seqNum >= toCommit->squashedSeqNum[tid] + 1)
1329 continue;
1330*/
1311 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %s "
1312 "[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n",
1313 violator->pcState(), violator->seqNum,
1314 inst->pcState(), inst->seqNum, inst->physEffAddr);
1315
1331 fetchRedirect[tid] = true;
1332
1333 // Tell the instruction queue that a violation has occured.
1334 instQueue.violation(inst, violator);
1335
1336 // Squash.
1337 squashDueToMemOrder(inst,tid);
1338
1339 ++memOrderViolationEvents;
1340 } else if (ldstQueue.loadBlocked(tid) &&
1341 !ldstQueue.isLoadBlockedHandled(tid)) {
1342 fetchRedirect[tid] = true;
1343
1344 DPRINTF(IEW, "Load operation couldn't execute because the "
1316 fetchRedirect[tid] = true;
1317
1318 // Tell the instruction queue that a violation has occured.
1319 instQueue.violation(inst, violator);
1320
1321 // Squash.
1322 squashDueToMemOrder(inst,tid);
1323
1324 ++memOrderViolationEvents;
1325 } else if (ldstQueue.loadBlocked(tid) &&
1326 !ldstQueue.isLoadBlockedHandled(tid)) {
1327 fetchRedirect[tid] = true;
1328
1329 DPRINTF(IEW, "Load operation couldn't execute because the "
1345 "memory system is blocked. PC: %#x [sn:%lli]\n",
1346 inst->readPC(), inst->seqNum);
1330 "memory system is blocked. PC: %s [sn:%lli]\n",
1331 inst->pcState(), inst->seqNum);
1347
1348 squashDueToMemBlocked(inst, tid);
1349 }
1350 } else {
1351 // Reset any state associated with redirects that will not
1352 // be used.
1353 if (ldstQueue.violation(tid)) {
1354 assert(inst->isMemRef());
1355
1356 DynInstPtr violator = ldstQueue.getMemDepViolator(tid);
1357
1358 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: "
1332
1333 squashDueToMemBlocked(inst, tid);
1334 }
1335 } else {
1336 // Reset any state associated with redirects that will not
1337 // be used.
1338 if (ldstQueue.violation(tid)) {
1339 assert(inst->isMemRef());
1340
1341 DynInstPtr violator = ldstQueue.getMemDepViolator(tid);
1342
1343 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: "
1359 "%#x, inst PC: %#x. Addr is: %#x.\n",
1360 violator->readPC(), inst->readPC(), inst->physEffAddr);
1344 "%s, inst PC: %s. Addr is: %#x.\n",
1345 violator->pcState(), inst->pcState(),
1346 inst->physEffAddr);
1361 DPRINTF(IEW, "Violation will not be handled because "
1362 "already squashing\n");
1363
1364 ++memOrderViolationEvents;
1365 }
1366 if (ldstQueue.loadBlocked(tid) &&
1367 !ldstQueue.isLoadBlockedHandled(tid)) {
1368 DPRINTF(IEW, "Load operation couldn't execute because the "
1347 DPRINTF(IEW, "Violation will not be handled because "
1348 "already squashing\n");
1349
1350 ++memOrderViolationEvents;
1351 }
1352 if (ldstQueue.loadBlocked(tid) &&
1353 !ldstQueue.isLoadBlockedHandled(tid)) {
1354 DPRINTF(IEW, "Load operation couldn't execute because the "
1369 "memory system is blocked. PC: %#x [sn:%lli]\n",
1370 inst->readPC(), inst->seqNum);
1355 "memory system is blocked. PC: %s [sn:%lli]\n",
1356 inst->pcState(), inst->seqNum);
1371 DPRINTF(IEW, "Blocked load will not be handled because "
1372 "already squashing\n");
1373
1374 ldstQueue.setLoadBlockedHandled(tid);
1375 }
1376
1377 }
1378 }

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

1403 // mark scoreboard that this instruction is finally complete.
1404 // Either have IEW have direct access to scoreboard, or have this
1405 // as part of backwards communication.
1406 for (int inst_num = 0; inst_num < wbWidth &&
1407 toCommit->insts[inst_num]; inst_num++) {
1408 DynInstPtr inst = toCommit->insts[inst_num];
1409 ThreadID tid = inst->threadNumber;
1410
1357 DPRINTF(IEW, "Blocked load will not be handled because "
1358 "already squashing\n");
1359
1360 ldstQueue.setLoadBlockedHandled(tid);
1361 }
1362
1363 }
1364 }

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

1389 // mark scoreboard that this instruction is finally complete.
1390 // Either have IEW have direct access to scoreboard, or have this
1391 // as part of backwards communication.
1392 for (int inst_num = 0; inst_num < wbWidth &&
1393 toCommit->insts[inst_num]; inst_num++) {
1394 DynInstPtr inst = toCommit->insts[inst_num];
1395 ThreadID tid = inst->threadNumber;
1396
1411 DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n",
1412 inst->seqNum, inst->readPC());
1397 DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %s.\n",
1398 inst->seqNum, inst->pcState());
1413
1414 iewInstsToCommit[tid]++;
1415
1416 // Some instructions will be sent to commit without having
1417 // executed because they need commit to handle them.
1418 // E.g. Uncached loads have not actually executed when they
1419 // are first sent to commit. Instead commit must tell the LSQ
1420 // when it's ready to execute the uncached load.

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

1608 if (!fetchRedirect[tid] ||
1609 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1610
1611 if (inst->mispredicted()) {
1612 fetchRedirect[tid] = true;
1613
1614 DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1615 DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
1399
1400 iewInstsToCommit[tid]++;
1401
1402 // Some instructions will be sent to commit without having
1403 // executed because they need commit to handle them.
1404 // E.g. Uncached loads have not actually executed when they
1405 // are first sent to commit. Instead commit must tell the LSQ
1406 // when it's ready to execute the uncached load.

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

1594 if (!fetchRedirect[tid] ||
1595 toCommit->squashedSeqNum[tid] > inst->seqNum) {
1596
1597 if (inst->mispredicted()) {
1598 fetchRedirect[tid] = true;
1599
1600 DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1601 DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
1616 inst->readPredPC(), inst->readPredNPC());
1602 inst->predInstAddr(), inst->predNextInstAddr());
1617 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
1603 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
1618 " NPC: %#x.\n", inst->readNextPC(),
1619 inst->readNextNPC());
1604 " NPC: %#x.\n", inst->nextInstAddr(),
1605 inst->nextInstAddr());
1620 // If incorrect, then signal the ROB that it must be squashed.
1621 squashDueToBranch(inst, tid);
1622
1623 if (inst->readPredTaken()) {
1624 predictedTakenIncorrect++;
1625 } else {
1626 predictedNotTakenIncorrect++;
1627 }
1628 }
1629 }
1630}
1606 // If incorrect, then signal the ROB that it must be squashed.
1607 squashDueToBranch(inst, tid);
1608
1609 if (inst->readPredTaken()) {
1610 predictedTakenIncorrect++;
1611 } else {
1612 predictedNotTakenIncorrect++;
1613 }
1614 }
1615 }
1616}