rename_impl.hh (3798:ec59feae527b) | rename_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; --- 17 unchanged lines hidden (view full) --- 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 * Korey Sewell 30 */ 31 32#include <list> 33 | 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; --- 17 unchanged lines hidden (view full) --- 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 * Korey Sewell 30 */ 31 32#include <list> 33 |
34#include "arch/isa_traits.hh" 35#include "arch/regfile.hh" | |
36#include "config/full_system.hh" 37#include "cpu/o3/rename.hh" 38 39template <class Impl> 40DefaultRename<Impl>::DefaultRename(Params *params) 41 : iewToRenameDelay(params->iewToRenameDelay), 42 decodeToRenameDelay(params->decodeToRenameDelay), 43 commitToRenameDelay(params->commitToRenameDelay), 44 renameWidth(params->renameWidth), 45 commitWidth(params->commitWidth), | 34#include "config/full_system.hh" 35#include "cpu/o3/rename.hh" 36 37template <class Impl> 38DefaultRename<Impl>::DefaultRename(Params *params) 39 : iewToRenameDelay(params->iewToRenameDelay), 40 decodeToRenameDelay(params->decodeToRenameDelay), 41 commitToRenameDelay(params->commitToRenameDelay), 42 renameWidth(params->renameWidth), 43 commitWidth(params->commitWidth), |
46 resumeSerialize(false), 47 resumeUnblocking(false), | |
48 numThreads(params->numberOfThreads), 49 maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs) 50{ 51 _status = Inactive; 52 53 for (int i=0; i< numThreads; i++) { 54 renameStatus[i] = Idle; 55 --- 275 unchanged lines hidden (view full) --- 331DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, unsigned tid) 332{ 333 DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid); 334 335 // Clear the stall signal if rename was blocked or unblocking before. 336 // If it still needs to block, the blocking should happen the next 337 // cycle and there should be space to hold everything due to the squash. 338 if (renameStatus[tid] == Blocked || | 44 numThreads(params->numberOfThreads), 45 maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs) 46{ 47 _status = Inactive; 48 49 for (int i=0; i< numThreads; i++) { 50 renameStatus[i] = Idle; 51 --- 275 unchanged lines hidden (view full) --- 327DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, unsigned tid) 328{ 329 DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid); 330 331 // Clear the stall signal if rename was blocked or unblocking before. 332 // If it still needs to block, the blocking should happen the next 333 // cycle and there should be space to hold everything due to the squash. 334 if (renameStatus[tid] == Blocked || |
339 renameStatus[tid] == Unblocking) { | 335 renameStatus[tid] == Unblocking || 336 renameStatus[tid] == SerializeStall) { 337 |
340 toDecode->renameUnblock[tid] = 1; 341 | 338 toDecode->renameUnblock[tid] = 1; 339 |
342 resumeSerialize = false; | |
343 serializeInst[tid] = NULL; | 340 serializeInst[tid] = NULL; |
344 } else if (renameStatus[tid] == SerializeStall) { 345 if (serializeInst[tid]->seqNum <= squash_seq_num) { 346 DPRINTF(Rename, "Rename will resume serializing after squash\n"); 347 resumeSerialize = true; 348 assert(serializeInst[tid]); 349 } else { 350 resumeSerialize = false; 351 toDecode->renameUnblock[tid] = 1; 352 353 serializeInst[tid] = NULL; 354 } | |
355 } 356 357 // Set the status to Squashing. 358 renameStatus[tid] = Squashing; 359 360 // Squash any instructions from decode. 361 unsigned squashCount = 0; 362 --- 38 unchanged lines hidden (view full) --- 401 while (slist_it != skidBuffer[tid].end()) { 402 if ((*slist_it)->seqNum > squash_seq_num) { 403 (*slist_it)->setSquashed(); 404 DPRINTF(Rename, "Squashing skidbuffer instruction, [tid:%i] [sn:%i]" 405 "PC %08p.\n", tid, (*slist_it)->seqNum, (*slist_it)->PC); 406 } 407 slist_it++; 408 } | 341 } 342 343 // Set the status to Squashing. 344 renameStatus[tid] = Squashing; 345 346 // Squash any instructions from decode. 347 unsigned squashCount = 0; 348 --- 38 unchanged lines hidden (view full) --- 387 while (slist_it != skidBuffer[tid].end()) { 388 if ((*slist_it)->seqNum > squash_seq_num) { 389 (*slist_it)->setSquashed(); 390 DPRINTF(Rename, "Squashing skidbuffer instruction, [tid:%i] [sn:%i]" 391 "PC %08p.\n", tid, (*slist_it)->seqNum, (*slist_it)->PC); 392 } 393 slist_it++; 394 } |
409 resumeUnblocking = (skidBuffer[tid].size() != 0); 410 DPRINTF(Rename, "Resume unblocking set to %s\n", 411 resumeUnblocking ? "true" : "false"); | |
412#else 413 skidBuffer[tid].clear(); 414#endif 415 doSquash(squash_seq_num, tid); 416} 417 418template <class Impl> 419void --- 4 unchanged lines hidden (view full) --- 424 blockThisCycle = false; 425 426 bool status_change = false; 427 428 toIEWIndex = 0; 429 430 sortInsts(); 431 | 395#else 396 skidBuffer[tid].clear(); 397#endif 398 doSquash(squash_seq_num, tid); 399} 400 401template <class Impl> 402void --- 4 unchanged lines hidden (view full) --- 407 blockThisCycle = false; 408 409 bool status_change = false; 410 411 toIEWIndex = 0; 412 413 sortInsts(); 414 |
432 std::list<unsigned>::iterator threads = (*activeThreads).begin(); | 415 std::list<unsigned>::iterator threads = activeThreads->begin(); 416 std::list<unsigned>::iterator end = activeThreads->end(); |
433 434 // Check stall and squash signals. | 417 418 // Check stall and squash signals. |
435 while (threads != (*activeThreads).end()) { | 419 while (threads != end) { |
436 unsigned tid = *threads++; 437 438 DPRINTF(Rename, "Processing [tid:%i]\n", tid); 439 440 status_change = checkSignalsAndUpdate(tid) || status_change; 441 442 rename(status_change, tid); 443 } 444 445 if (status_change) { 446 updateStatus(); 447 } 448 449 if (wroteToTimeBuffer) { 450 DPRINTF(Activity, "Activity this cycle.\n"); 451 cpu->activityThisCycle(); 452 } 453 | 420 unsigned tid = *threads++; 421 422 DPRINTF(Rename, "Processing [tid:%i]\n", tid); 423 424 status_change = checkSignalsAndUpdate(tid) || status_change; 425 426 rename(status_change, tid); 427 } 428 429 if (status_change) { 430 updateStatus(); 431 } 432 433 if (wroteToTimeBuffer) { 434 DPRINTF(Activity, "Activity this cycle.\n"); 435 cpu->activityThisCycle(); 436 } 437 |
454 threads = (*activeThreads).begin(); | 438 threads = activeThreads->begin(); |
455 | 439 |
456 while (threads != (*activeThreads).end()) { | 440 while (threads != end) { |
457 unsigned tid = *threads++; 458 459 // If we committed this cycle then doneSeqNum will be > 0 460 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 461 !fromCommit->commitInfo[tid].squash && 462 renameStatus[tid] != Squashing) { 463 464 removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum, --- 22 unchanged lines hidden (view full) --- 487 // check if stall conditions have passed 488 489 if (renameStatus[tid] == Blocked) { 490 ++renameBlockCycles; 491 } else if (renameStatus[tid] == Squashing) { 492 ++renameSquashCycles; 493 } else if (renameStatus[tid] == SerializeStall) { 494 ++renameSerializeStallCycles; | 441 unsigned tid = *threads++; 442 443 // If we committed this cycle then doneSeqNum will be > 0 444 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 445 !fromCommit->commitInfo[tid].squash && 446 renameStatus[tid] != Squashing) { 447 448 removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum, --- 22 unchanged lines hidden (view full) --- 471 // check if stall conditions have passed 472 473 if (renameStatus[tid] == Blocked) { 474 ++renameBlockCycles; 475 } else if (renameStatus[tid] == Squashing) { 476 ++renameSquashCycles; 477 } else if (renameStatus[tid] == SerializeStall) { 478 ++renameSerializeStallCycles; |
495 // If we are currently in SerializeStall and resumeSerialize 496 // was set, then that means that we are resuming serializing 497 // this cycle. Tell the previous stages to block. 498 if (resumeSerialize) { 499 resumeSerialize = false; 500 block(tid); 501 toDecode->renameUnblock[tid] = false; 502 } 503 } else if (renameStatus[tid] == Unblocking) { 504 if (resumeUnblocking) { 505 block(tid); 506 resumeUnblocking = false; 507 toDecode->renameUnblock[tid] = false; 508 } | |
509 } 510 511 if (renameStatus[tid] == Running || 512 renameStatus[tid] == Idle) { 513 DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run " 514 "stage.\n", tid); 515 516 renameInsts(tid); --- 249 unchanged lines hidden (view full) --- 766 "skidBuffer\n", tid, inst->seqNum, inst->readPC()); 767 768 ++renameSkidInsts; 769 770 skidBuffer[tid].push_back(inst); 771 } 772 773 if (skidBuffer[tid].size() > skidBufferMax) | 479 } 480 481 if (renameStatus[tid] == Running || 482 renameStatus[tid] == Idle) { 483 DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run " 484 "stage.\n", tid); 485 486 renameInsts(tid); --- 249 unchanged lines hidden (view full) --- 736 "skidBuffer\n", tid, inst->seqNum, inst->readPC()); 737 738 ++renameSkidInsts; 739 740 skidBuffer[tid].push_back(inst); 741 } 742 743 if (skidBuffer[tid].size() > skidBufferMax) |
774 { 775 typename InstQueue::iterator it; 776 warn("Skidbuffer contents:\n"); 777 for(it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++) 778 { 779 warn("[tid:%u]: %s [sn:%i].\n", tid, 780 (*it)->staticInst->disassemble(inst->readPC()), 781 (*it)->seqNum); 782 } | |
783 panic("Skidbuffer Exceeded Max Size"); | 744 panic("Skidbuffer Exceeded Max Size"); |
784 } | |
785} 786 787template <class Impl> 788void 789DefaultRename<Impl>::sortInsts() 790{ 791 int insts_from_decode = fromDecode->size; 792#ifdef DEBUG --- 7 unchanged lines hidden (view full) --- 800 insts[inst->threadNumber].push_back(inst); 801 } 802} 803 804template<class Impl> 805bool 806DefaultRename<Impl>::skidsEmpty() 807{ | 745} 746 747template <class Impl> 748void 749DefaultRename<Impl>::sortInsts() 750{ 751 int insts_from_decode = fromDecode->size; 752#ifdef DEBUG --- 7 unchanged lines hidden (view full) --- 760 insts[inst->threadNumber].push_back(inst); 761 } 762} 763 764template<class Impl> 765bool 766DefaultRename<Impl>::skidsEmpty() 767{ |
808 std::list<unsigned>::iterator threads = (*activeThreads).begin(); | 768 std::list<unsigned>::iterator threads = activeThreads->begin(); 769 std::list<unsigned>::iterator end = activeThreads->end(); |
809 | 770 |
810 while (threads != (*activeThreads).end()) { 811 if (!skidBuffer[*threads++].empty()) | 771 while (threads != end) { 772 unsigned tid = *threads++; 773 774 if (!skidBuffer[tid].empty()) |
812 return false; 813 } 814 815 return true; 816} 817 818template<class Impl> 819void 820DefaultRename<Impl>::updateStatus() 821{ 822 bool any_unblocking = false; 823 | 775 return false; 776 } 777 778 return true; 779} 780 781template<class Impl> 782void 783DefaultRename<Impl>::updateStatus() 784{ 785 bool any_unblocking = false; 786 |
824 std::list<unsigned>::iterator threads = (*activeThreads).begin(); | 787 std::list<unsigned>::iterator threads = activeThreads->begin(); 788 std::list<unsigned>::iterator end = activeThreads->end(); |
825 | 789 |
826 threads = (*activeThreads).begin(); 827 828 while (threads != (*activeThreads).end()) { | 790 while (threads != end) { |
829 unsigned tid = *threads++; 830 831 if (renameStatus[tid] == Unblocking) { 832 any_unblocking = true; 833 break; 834 } 835 } 836 --- 26 unchanged lines hidden (view full) --- 863 864 // Add the current inputs onto the skid buffer, so they can be 865 // reprocessed when this stage unblocks. 866 skidInsert(tid); 867 868 // Only signal backwards to block if the previous stages do not think 869 // rename is already blocked. 870 if (renameStatus[tid] != Blocked) { | 791 unsigned tid = *threads++; 792 793 if (renameStatus[tid] == Unblocking) { 794 any_unblocking = true; 795 break; 796 } 797 } 798 --- 26 unchanged lines hidden (view full) --- 825 826 // Add the current inputs onto the skid buffer, so they can be 827 // reprocessed when this stage unblocks. 828 skidInsert(tid); 829 830 // Only signal backwards to block if the previous stages do not think 831 // rename is already blocked. 832 if (renameStatus[tid] != Blocked) { |
871 // If resumeUnblocking is set, we unblocked during the squash, 872 // but now we're have unblocking status. We need to tell earlier 873 // stages to block. 874 if (resumeUnblocking || renameStatus[tid] != Unblocking) { | 833 if (renameStatus[tid] != Unblocking) { |
875 toDecode->renameBlock[tid] = true; 876 toDecode->renameUnblock[tid] = false; 877 wroteToTimeBuffer = true; 878 } 879 880 // Rename can not go from SerializeStall to Blocked, otherwise 881 // it would not know to complete the serialize stall. 882 if (renameStatus[tid] != SerializeStall) { --- 116 unchanged lines hidden (view full) --- 999 1000 unsigned num_src_regs = inst->numSrcRegs(); 1001 1002 // Get the architectual register numbers from the source and 1003 // destination operands, and redirect them to the right register. 1004 // Will need to mark dependencies though. 1005 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) { 1006 RegIndex src_reg = inst->srcRegIdx(src_idx); | 834 toDecode->renameBlock[tid] = true; 835 toDecode->renameUnblock[tid] = false; 836 wroteToTimeBuffer = true; 837 } 838 839 // Rename can not go from SerializeStall to Blocked, otherwise 840 // it would not know to complete the serialize stall. 841 if (renameStatus[tid] != SerializeStall) { --- 116 unchanged lines hidden (view full) --- 958 959 unsigned num_src_regs = inst->numSrcRegs(); 960 961 // Get the architectual register numbers from the source and 962 // destination operands, and redirect them to the right register. 963 // Will need to mark dependencies though. 964 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) { 965 RegIndex src_reg = inst->srcRegIdx(src_idx); |
1007 RegIndex flat_src_reg = src_reg; 1008 if (src_reg < TheISA::FP_Base_DepTag) { 1009 flat_src_reg = TheISA::flattenIntIndex(inst->tcBase(), src_reg); 1010 DPRINTF(Rename, "Flattening index %d to %d.\n", (int)src_reg, (int)flat_src_reg); 1011 } 1012 inst->flattenSrcReg(src_idx, flat_src_reg); | |
1013 1014 // Look up the source registers to get the phys. register they've 1015 // been renamed to, and set the sources to those registers. | 966 967 // Look up the source registers to get the phys. register they've 968 // been renamed to, and set the sources to those registers. |
1016 PhysRegIndex renamed_reg = renameMap[tid]->lookup(flat_src_reg); | 969 PhysRegIndex renamed_reg = renameMap[tid]->lookup(src_reg); |
1017 1018 DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got " | 970 971 DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got " |
1019 "physical reg %i.\n", tid, (int)flat_src_reg, | 972 "physical reg %i.\n", tid, (int)src_reg, |
1020 (int)renamed_reg); 1021 1022 inst->renameSrcReg(src_idx, renamed_reg); 1023 1024 // See if the register is ready or not. 1025 if (scoreboard->getReg(renamed_reg) == true) { 1026 DPRINTF(Rename, "[tid:%u]: Register is ready.\n", tid); 1027 --- 10 unchanged lines hidden (view full) --- 1038{ 1039 typename RenameMap::RenameInfo rename_result; 1040 1041 unsigned num_dest_regs = inst->numDestRegs(); 1042 1043 // Rename the destination registers. 1044 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) { 1045 RegIndex dest_reg = inst->destRegIdx(dest_idx); | 973 (int)renamed_reg); 974 975 inst->renameSrcReg(src_idx, renamed_reg); 976 977 // See if the register is ready or not. 978 if (scoreboard->getReg(renamed_reg) == true) { 979 DPRINTF(Rename, "[tid:%u]: Register is ready.\n", tid); 980 --- 10 unchanged lines hidden (view full) --- 991{ 992 typename RenameMap::RenameInfo rename_result; 993 994 unsigned num_dest_regs = inst->numDestRegs(); 995 996 // Rename the destination registers. 997 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) { 998 RegIndex dest_reg = inst->destRegIdx(dest_idx); |
1046 RegIndex flat_dest_reg = dest_reg; 1047 if (dest_reg < TheISA::FP_Base_DepTag) { 1048 flat_dest_reg = TheISA::flattenIntIndex(inst->tcBase(), dest_reg); 1049 DPRINTF(Rename, "Flattening index %d to %d.\n", (int)dest_reg, (int)flat_dest_reg); 1050 } | |
1051 | 999 |
1052 inst->flattenDestReg(dest_idx, flat_dest_reg); 1053 | |
1054 // Get the physical register that the destination will be 1055 // renamed to. | 1000 // Get the physical register that the destination will be 1001 // renamed to. |
1056 rename_result = renameMap[tid]->rename(flat_dest_reg); | 1002 rename_result = renameMap[tid]->rename(dest_reg); |
1057 1058 //Mark Scoreboard entry as not ready 1059 scoreboard->unsetReg(rename_result.first); 1060 1061 DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical " | 1003 1004 //Mark Scoreboard entry as not ready 1005 scoreboard->unsetReg(rename_result.first); 1006 1007 DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical " |
1062 "reg %i.\n", tid, (int)flat_dest_reg, | 1008 "reg %i.\n", tid, (int)dest_reg, |
1063 (int)rename_result.first); 1064 1065 // Record the rename information so that a history can be kept. | 1009 (int)rename_result.first); 1010 1011 // Record the rename information so that a history can be kept. |
1066 RenameHistory hb_entry(inst->seqNum, flat_dest_reg, | 1012 RenameHistory hb_entry(inst->seqNum, dest_reg, |
1067 rename_result.first, 1068 rename_result.second); 1069 1070 historyBuffer[tid].push_front(hb_entry); 1071 1072 DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer " 1073 "(size=%i), [sn:%lli].\n",tid, 1074 historyBuffer[tid].size(), --- 207 unchanged lines hidden (view full) --- 1282 unblock(tid); 1283 1284 return true; 1285 } 1286 1287 if (renameStatus[tid] == Squashing) { 1288 // Switch status to running if rename isn't being told to block or 1289 // squash this cycle. | 1013 rename_result.first, 1014 rename_result.second); 1015 1016 historyBuffer[tid].push_front(hb_entry); 1017 1018 DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer " 1019 "(size=%i), [sn:%lli].\n",tid, 1020 historyBuffer[tid].size(), --- 207 unchanged lines hidden (view full) --- 1228 unblock(tid); 1229 1230 return true; 1231 } 1232 1233 if (renameStatus[tid] == Squashing) { 1234 // Switch status to running if rename isn't being told to block or 1235 // squash this cycle. |
1290 if (resumeSerialize) { 1291 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n", 1292 tid); | 1236 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n", 1237 tid); |
1293 | 1238 |
1294 renameStatus[tid] = SerializeStall; 1295 return true; 1296 } else if (resumeUnblocking) { 1297 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to unblocking.\n", 1298 tid); 1299 renameStatus[tid] = Unblocking; 1300 return true; 1301 } else { 1302 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n", 1303 tid); | 1239 renameStatus[tid] = Running; |
1304 | 1240 |
1305 renameStatus[tid] = Running; 1306 return false; 1307 } | 1241 return false; |
1308 } 1309 1310 if (renameStatus[tid] == SerializeStall) { 1311 // Stall ends once the ROB is free. 1312 DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to " 1313 "unblocking.\n", tid); 1314 1315 DynInstPtr serial_inst = serializeInst[tid]; --- 85 unchanged lines hidden --- | 1242 } 1243 1244 if (renameStatus[tid] == SerializeStall) { 1245 // Stall ends once the ROB is free. 1246 DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to " 1247 "unblocking.\n", tid); 1248 1249 DynInstPtr serial_inst = serializeInst[tid]; --- 85 unchanged lines hidden --- |