rename_impl.hh revision 1060
12SN/A#include <list> 212284Sjose.marinho@arm.com 39920Syasuko.eckert@amd.com#include "cpu/beta_cpu/rename.hh" 47338SAli.Saidi@ARM.com 57338SAli.Saidi@ARM.comtemplate<class Impl> 67338SAli.Saidi@ARM.comSimpleRename<Impl>::SimpleRename(Params ¶ms) 77338SAli.Saidi@ARM.com : iewToRenameDelay(params.iewToRenameDelay), 87338SAli.Saidi@ARM.com decodeToRenameDelay(params.decodeToRenameDelay), 97338SAli.Saidi@ARM.com commitToRenameDelay(params.commitToRenameDelay), 107338SAli.Saidi@ARM.com renameWidth(params.renameWidth), 117338SAli.Saidi@ARM.com commitWidth(params.commitWidth) 127338SAli.Saidi@ARM.com{ 137338SAli.Saidi@ARM.com _status = Idle; 147338SAli.Saidi@ARM.com} 151762SN/A 162SN/Atemplate<class Impl> 172SN/Avoid 182SN/ASimpleRename<Impl>::setCPU(FullCPU *cpu_ptr) 192SN/A{ 202SN/A DPRINTF(Rename, "Rename: Setting CPU pointer.\n"); 212SN/A cpu = cpu_ptr; 222SN/A} 232SN/A 242SN/Atemplate<class Impl> 252SN/Avoid 262SN/ASimpleRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 272SN/A{ 282SN/A DPRINTF(Rename, "Rename: Setting time buffer pointer.\n"); 292SN/A timeBuffer = tb_ptr; 302SN/A 312SN/A // Setup wire to read information from time buffer, from IEW stage. 322SN/A fromIEW = timeBuffer->getWire(-iewToRenameDelay); 332SN/A 342SN/A // Setup wire to read infromation from time buffer, from commit stage. 352SN/A fromCommit = timeBuffer->getWire(-commitToRenameDelay); 362SN/A 372SN/A // Setup wire to write information to previous stages. 382SN/A toDecode = timeBuffer->getWire(0); 392SN/A} 402665Ssaidi@eecs.umich.edu 412665Ssaidi@eecs.umich.edutemplate<class Impl> 422SN/Avoid 432SN/ASimpleRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 4411793Sbrandon.potter@amd.com{ 4511793Sbrandon.potter@amd.com DPRINTF(Rename, "Rename: Setting rename queue pointer.\n"); 468779Sgblack@eecs.umich.edu renameQueue = rq_ptr; 478779Sgblack@eecs.umich.edu 482439SN/A // Setup wire to write information to future stages. 498779Sgblack@eecs.umich.edu toIEW = renameQueue->getWire(0); 506216Snate@binkert.org} 51146SN/A 52146SN/Atemplate<class Impl> 5311793Sbrandon.potter@amd.comvoid 5412334Sgabeblack@google.comSimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) 55146SN/A{ 56146SN/A DPRINTF(Rename, "Rename: Setting decode queue pointer.\n"); 576216Snate@binkert.org decodeQueue = dq_ptr; 586658Snate@binkert.org 591717SN/A // Setup wire to get information from decode. 608887Sgeoffrey.blake@arm.com fromDecode = decodeQueue->getWire(-decodeToRenameDelay); 618887Sgeoffrey.blake@arm.com 62146SN/A} 6310061Sandreas@sandberg.pp.se 641977SN/Atemplate<class Impl> 6511147Smitch.hayenga@arm.comvoid 662683Sktlim@umich.eduSimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr) 671717SN/A{ 68146SN/A DPRINTF(Rename, "Rename: Setting rename map pointer.\n"); 692683Sktlim@umich.edu renameMap = rm_ptr; 708232Snate@binkert.org} 718232Snate@binkert.org 728232Snate@binkert.orgtemplate<class Impl> 738779Sgblack@eecs.umich.eduvoid 743348Sbinkertn@umich.eduSimpleRename<Impl>::setFreeList(FreeList *fl_ptr) 756105Ssteve.reinhardt@amd.com{ 766216Snate@binkert.org DPRINTF(Rename, "Rename: Setting free list pointer.\n"); 772036SN/A freeList = fl_ptr; 78146SN/A} 798817Sgblack@eecs.umich.edu 808793Sgblack@eecs.umich.edutemplate<class Impl> 8156SN/Avoid 8256SN/ASimpleRename<Impl>::dumpHistory() 83695SN/A{ 842901Ssaidi@eecs.umich.edu typename list<RenameHistory>::iterator buf_it = historyBuffer.begin(); 852SN/A 862SN/A while (buf_it != historyBuffer.end()) 872449SN/A { 881355SN/A cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys " 895529Snate@binkert.org "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg, 9010061Sandreas@sandberg.pp.se (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg); 9111147Smitch.hayenga@arm.com 9210061Sandreas@sandberg.pp.se buf_it++; 9311147Smitch.hayenga@arm.com } 9411147Smitch.hayenga@arm.com} 9511147Smitch.hayenga@arm.com 96224SN/Atemplate<class Impl> 9711147Smitch.hayenga@arm.comvoid 982SN/ASimpleRename<Impl>::block() 9911147Smitch.hayenga@arm.com{ 10011147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Blocking.\n"); 10111147Smitch.hayenga@arm.com // Set status to Blocked. 10211147Smitch.hayenga@arm.com _status = Blocked; 10311147Smitch.hayenga@arm.com 10411147Smitch.hayenga@arm.com // Add the current inputs onto the skid buffer, so they can be 10511147Smitch.hayenga@arm.com // reprocessed when this stage unblocks. 10611147Smitch.hayenga@arm.com skidBuffer.push(*fromDecode); 10711147Smitch.hayenga@arm.com 10811147Smitch.hayenga@arm.com // Note that this stage only signals previous stages to stall when 10911147Smitch.hayenga@arm.com // it is the cause of the stall originates at this stage. Otherwise 11011147Smitch.hayenga@arm.com // the previous stages are expected to check all possible stall signals. 1112SN/A} 1128733Sgeoffrey.blake@arm.com 11311147Smitch.hayenga@arm.comtemplate<class Impl> 11411147Smitch.hayenga@arm.cominline void 11511147Smitch.hayenga@arm.comSimpleRename<Impl>::unblock() 1168733Sgeoffrey.blake@arm.com{ 1178733Sgeoffrey.blake@arm.com DPRINTF(Rename, "Rename: Reading instructions out of skid " 1188733Sgeoffrey.blake@arm.com "buffer.\n"); 1198733Sgeoffrey.blake@arm.com // Remove the now processed instructions from the skid buffer. 12011147Smitch.hayenga@arm.com skidBuffer.pop(); 12111147Smitch.hayenga@arm.com 1228733Sgeoffrey.blake@arm.com // If there's still information in the skid buffer, then 1238733Sgeoffrey.blake@arm.com // continue to tell previous stages to stall. They will be 1248733Sgeoffrey.blake@arm.com // able to restart once the skid buffer is empty. 12511147Smitch.hayenga@arm.com if (!skidBuffer.empty()) { 1268733Sgeoffrey.blake@arm.com toDecode->renameInfo.stall = true; 12711147Smitch.hayenga@arm.com } else { 12811147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Done unblocking.\n"); 12911147Smitch.hayenga@arm.com _status = Running; 13011147Smitch.hayenga@arm.com } 1312SN/A} 13211147Smitch.hayenga@arm.com 13311147Smitch.hayenga@arm.comtemplate<class Impl> 13411147Smitch.hayenga@arm.comvoid 1354377Sgblack@eecs.umich.eduSimpleRename<Impl>::doSquash() 13611147Smitch.hayenga@arm.com{ 13711147Smitch.hayenga@arm.com typename list<RenameHistory>::iterator hb_it = historyBuffer.begin(); 13811147Smitch.hayenga@arm.com typename list<RenameHistory>::iterator delete_it; 13911147Smitch.hayenga@arm.com 14011147Smitch.hayenga@arm.com InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum; 14111147Smitch.hayenga@arm.com 1425169Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 14311147Smitch.hayenga@arm.com assert(!historyBuffer.empty()); 14411147Smitch.hayenga@arm.com#else 14511147Smitch.hayenga@arm.com // After a syscall squashes everything, the history buffer may be empty 14611147Smitch.hayenga@arm.com // but the ROB may still be squashing instructions. 14711147Smitch.hayenga@arm.com if (historyBuffer.empty()) { 14811147Smitch.hayenga@arm.com return; 14911147Smitch.hayenga@arm.com } 15011147Smitch.hayenga@arm.com#endif // FULL_SYSTEM 15111147Smitch.hayenga@arm.com 15211147Smitch.hayenga@arm.com // Go through the most recent instructions, undoing the mappings 15311147Smitch.hayenga@arm.com // they did and freeing up the registers. 15411147Smitch.hayenga@arm.com while ((*hb_it).instSeqNum > squashed_seq_num) 15511147Smitch.hayenga@arm.com { 15611147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Removing history entry with sequence " 15711147Smitch.hayenga@arm.com "number %i.\n", (*hb_it).instSeqNum); 15811147Smitch.hayenga@arm.com 15911147Smitch.hayenga@arm.com // If it's not simply a place holder, then add the registers. 16011147Smitch.hayenga@arm.com if (!(*hb_it).placeHolder) { 16111147Smitch.hayenga@arm.com // Tell the rename map to set the architected register to the 16211147Smitch.hayenga@arm.com // previous physical register that it was renamed to. 16311147Smitch.hayenga@arm.com renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg); 16411147Smitch.hayenga@arm.com 16511147Smitch.hayenga@arm.com // Put the renamed physical register back on the free list. 16611147Smitch.hayenga@arm.com freeList->addReg(hb_it->newPhysReg); 16711147Smitch.hayenga@arm.com } 16811147Smitch.hayenga@arm.com 16911147Smitch.hayenga@arm.com delete_it = hb_it; 17011147Smitch.hayenga@arm.com 17111147Smitch.hayenga@arm.com hb_it++; 17211147Smitch.hayenga@arm.com 17311147Smitch.hayenga@arm.com historyBuffer.erase(delete_it); 17411147Smitch.hayenga@arm.com } 17511147Smitch.hayenga@arm.com} 17611147Smitch.hayenga@arm.com 17711147Smitch.hayenga@arm.comtemplate<class Impl> 17811147Smitch.hayenga@arm.comvoid 17911147Smitch.hayenga@arm.comSimpleRename<Impl>::squash() 18011147Smitch.hayenga@arm.com{ 18111147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Squashing instructions.\n"); 18211147Smitch.hayenga@arm.com // Set the status to Squashing. 18311147Smitch.hayenga@arm.com _status = Squashing; 18411147Smitch.hayenga@arm.com 18511147Smitch.hayenga@arm.com // Clear the skid buffer in case it has any data in it. 18611147Smitch.hayenga@arm.com while (!skidBuffer.empty()) 18711147Smitch.hayenga@arm.com { 18811147Smitch.hayenga@arm.com skidBuffer.pop(); 18911147Smitch.hayenga@arm.com } 19011147Smitch.hayenga@arm.com 19111147Smitch.hayenga@arm.com doSquash(); 19211147Smitch.hayenga@arm.com} 19311147Smitch.hayenga@arm.com 19411147Smitch.hayenga@arm.com// In the future, when a SmartPtr is used for DynInst, then this function 19511147Smitch.hayenga@arm.com// itself can handle returning the instruction's physical registers to 19611147Smitch.hayenga@arm.com// the free list. 19711147Smitch.hayenga@arm.comtemplate<class Impl> 19811147Smitch.hayenga@arm.comvoid 19911147Smitch.hayenga@arm.comSimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num) 20011147Smitch.hayenga@arm.com{ 20111147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Removing a committed instruction from the " 20211147Smitch.hayenga@arm.com "history buffer, sequence number %lli.\n", inst_seq_num); 20311147Smitch.hayenga@arm.com typename list<RenameHistory>::iterator hb_it = historyBuffer.end(); 20411147Smitch.hayenga@arm.com 20511147Smitch.hayenga@arm.com hb_it--; 2062SN/A 2072SN/A if (hb_it->instSeqNum > inst_seq_num) { 2082623SN/A DPRINTF(Rename, "Rename: Old sequence number encountered. Ensure " 2092SN/A "that a syscall happened recently.\n"); 2102SN/A return; 2112SN/A } 212180SN/A 2138737Skoansin.tan@gmail.com for ( ; hb_it->instSeqNum != inst_seq_num; hb_it--) 214393SN/A { 215393SN/A // Make sure we haven't gone off the end of the list. 216393SN/A assert(hb_it != historyBuffer.end()); 21712284Sjose.marinho@arm.com 218393SN/A // In theory instructions at the end of the history buffer 219384SN/A // should be older than the instruction being removed, which 220189SN/A // means they will have a lower sequence number. Also the 221189SN/A // instruction being removed from the history really should 2222623SN/A // be the last instruction in the list, as it is the instruction 2232SN/A // that was just committed that is being removed. 224729SN/A assert(hb_it->instSeqNum < inst_seq_num); 225334SN/A DPRINTF(Rename, "Rename: Committed instruction is not the last " 2262SN/A "entry in the history buffer.\n"); 2272SN/A } 22811147Smitch.hayenga@arm.com 22911147Smitch.hayenga@arm.com if (!(*hb_it).placeHolder) { 2308834Satgutier@umich.edu freeList->addReg(hb_it->prevPhysReg); 23111147Smitch.hayenga@arm.com } 23211147Smitch.hayenga@arm.com 23311147Smitch.hayenga@arm.com historyBuffer.erase(hb_it); 2342SN/A 23511147Smitch.hayenga@arm.com} 23611147Smitch.hayenga@arm.com 23711147Smitch.hayenga@arm.comtemplate<class Impl> 23811147Smitch.hayenga@arm.comvoid 2397897Shestness@cs.utexas.eduSimpleRename<Impl>::tick() 24011147Smitch.hayenga@arm.com{ 24111147Smitch.hayenga@arm.com // Rename will need to try to rename as many instructions as it 24211147Smitch.hayenga@arm.com // has bandwidth, unless it is blocked. 24311147Smitch.hayenga@arm.com 2447897Shestness@cs.utexas.edu // Check if _status is BarrierStall. If so, then check if the number 24511147Smitch.hayenga@arm.com // of free ROB entries is equal to the number of total ROB entries. 24611147Smitch.hayenga@arm.com // Once equal then wake this stage up. Set status to unblocking maybe. 24711147Smitch.hayenga@arm.com 24811147Smitch.hayenga@arm.com if (_status != Blocked && _status != Squashing) { 2497897Shestness@cs.utexas.edu DPRINTF(Rename, "Rename: Status is not blocked, will attempt to " 25011147Smitch.hayenga@arm.com "run stage.\n"); 25111147Smitch.hayenga@arm.com // Make sure that the skid buffer has something in it if the 25211147Smitch.hayenga@arm.com // status is unblocking. 25311147Smitch.hayenga@arm.com assert(_status == Unblocking ? !skidBuffer.empty() : 1); 2547897Shestness@cs.utexas.edu 25512110SRekai.GonzalezAlberquilla@arm.com rename(); 25612110SRekai.GonzalezAlberquilla@arm.com 25712110SRekai.GonzalezAlberquilla@arm.com // If the status was unblocking, then instructions from the skid 25812110SRekai.GonzalezAlberquilla@arm.com // buffer were used. Remove those instructions and handle 25912110SRekai.GonzalezAlberquilla@arm.com // the rest of unblocking. 26011147Smitch.hayenga@arm.com if (_status == Unblocking) { 26111147Smitch.hayenga@arm.com unblock(); 26211147Smitch.hayenga@arm.com } 26311147Smitch.hayenga@arm.com } else if (_status == Blocked) { 2647897Shestness@cs.utexas.edu // If stage is blocked and still receiving valid instructions, 26511147Smitch.hayenga@arm.com // make sure to store them in the skid buffer. 26611147Smitch.hayenga@arm.com if (fromDecode->insts[0] != NULL) { 26711147Smitch.hayenga@arm.com 26811147Smitch.hayenga@arm.com block(); 2697897Shestness@cs.utexas.edu 27011147Smitch.hayenga@arm.com // Continue to tell previous stage to stall. 27111147Smitch.hayenga@arm.com toDecode->renameInfo.stall = true; 27211147Smitch.hayenga@arm.com } 27311147Smitch.hayenga@arm.com 2747897Shestness@cs.utexas.edu if (!fromIEW->iewInfo.stall && 27511147Smitch.hayenga@arm.com !fromCommit->commitInfo.stall && 27611147Smitch.hayenga@arm.com fromCommit->commitInfo.freeROBEntries != 0 && 27711147Smitch.hayenga@arm.com fromIEW->iewInfo.freeIQEntries != 0) { 27811147Smitch.hayenga@arm.com 2797897Shestness@cs.utexas.edu // Need to be sure to check all blocking conditions above. 28012110SRekai.GonzalezAlberquilla@arm.com // If they have cleared, then start unblocking. 28112110SRekai.GonzalezAlberquilla@arm.com DPRINTF(Rename, "Rename: Stall signals cleared, going to " 28212110SRekai.GonzalezAlberquilla@arm.com "unblock.\n"); 28312110SRekai.GonzalezAlberquilla@arm.com _status = Unblocking; 28412110SRekai.GonzalezAlberquilla@arm.com 28511147Smitch.hayenga@arm.com // Continue to tell previous stage to block until this stage 28611147Smitch.hayenga@arm.com // is done unblocking. 28711147Smitch.hayenga@arm.com toDecode->renameInfo.stall = true; 28811147Smitch.hayenga@arm.com } else { 2897897Shestness@cs.utexas.edu // Otherwise no conditions have changed. Tell previous 29011147Smitch.hayenga@arm.com // stage to continue blocking. 29111147Smitch.hayenga@arm.com toDecode->renameInfo.stall = true; 29211147Smitch.hayenga@arm.com } 29311147Smitch.hayenga@arm.com 2947897Shestness@cs.utexas.edu if (fromCommit->commitInfo.squash || 29511147Smitch.hayenga@arm.com fromCommit->commitInfo.robSquashing) { 29611147Smitch.hayenga@arm.com squash(); 29711147Smitch.hayenga@arm.com return; 29811147Smitch.hayenga@arm.com } 2999920Syasuko.eckert@amd.com } else if (_status == Squashing) { 30011147Smitch.hayenga@arm.com if (fromCommit->commitInfo.squash) { 30111147Smitch.hayenga@arm.com squash(); 30211147Smitch.hayenga@arm.com } else if (!fromCommit->commitInfo.squash && 30311147Smitch.hayenga@arm.com !fromCommit->commitInfo.robSquashing) { 3049920Syasuko.eckert@amd.com 30512109SRekai.GonzalezAlberquilla@arm.com DPRINTF(Rename, "Rename: Done squashing, going to running.\n"); 30612109SRekai.GonzalezAlberquilla@arm.com _status = Running; 30712109SRekai.GonzalezAlberquilla@arm.com } else { 30812109SRekai.GonzalezAlberquilla@arm.com doSquash(); 30912109SRekai.GonzalezAlberquilla@arm.com } 31012109SRekai.GonzalezAlberquilla@arm.com } 31112109SRekai.GonzalezAlberquilla@arm.com 31212109SRekai.GonzalezAlberquilla@arm.com // Ugly code, revamp all of the tick() functions eventually. 31312109SRekai.GonzalezAlberquilla@arm.com if (fromCommit->commitInfo.doneSeqNum != 0 && _status != Squashing) { 31412109SRekai.GonzalezAlberquilla@arm.com removeFromHistory(fromCommit->commitInfo.doneSeqNum); 31511147Smitch.hayenga@arm.com } 31611147Smitch.hayenga@arm.com 31711147Smitch.hayenga@arm.com // Perhaps put this outside of this function, since this will 31811147Smitch.hayenga@arm.com // happen regardless of whether or not the stage is blocked or 31911147Smitch.hayenga@arm.com // squashing. 3207897Shestness@cs.utexas.edu // Read from the time buffer any necessary data. 32111147Smitch.hayenga@arm.com // Read registers that are freed, and add them to the freelist. 32211147Smitch.hayenga@arm.com // This is unnecessary due to the history buffer (assuming the history 32311147Smitch.hayenga@arm.com // buffer works properly). 32411147Smitch.hayenga@arm.com/* 32511147Smitch.hayenga@arm.com while(!fromCommit->commitInfo.freeRegs.empty()) 3267897Shestness@cs.utexas.edu { 32711147Smitch.hayenga@arm.com PhysRegIndex freed_reg = fromCommit->commitInfo.freeRegs.back(); 32811147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Adding freed register %i to freelist.\n", 32911147Smitch.hayenga@arm.com (int)freed_reg); 33011147Smitch.hayenga@arm.com freeList->addReg(freed_reg); 3312SN/A 33211147Smitch.hayenga@arm.com fromCommit->commitInfo.freeRegs.pop_back(); 33311147Smitch.hayenga@arm.com } 33411147Smitch.hayenga@arm.com*/ 33511147Smitch.hayenga@arm.com 3361001SN/A} 33711147Smitch.hayenga@arm.com 33811147Smitch.hayenga@arm.comtemplate<class Impl> 33911147Smitch.hayenga@arm.comvoid 34011147Smitch.hayenga@arm.comSimpleRename<Impl>::rename() 3412SN/A{ 34211147Smitch.hayenga@arm.com // Check if any of the stages ahead of rename are telling rename 34311147Smitch.hayenga@arm.com // to squash. The squash() function will also take care of fixing up 34411147Smitch.hayenga@arm.com // the rename map and the free list. 34511147Smitch.hayenga@arm.com if (fromCommit->commitInfo.squash || 3467897Shestness@cs.utexas.edu fromCommit->commitInfo.robSquashing) { 34711147Smitch.hayenga@arm.com squash(); 34811147Smitch.hayenga@arm.com return; 34911147Smitch.hayenga@arm.com } 35011147Smitch.hayenga@arm.com 3517897Shestness@cs.utexas.edu // Check if time buffer is telling this stage to stall. 35211147Smitch.hayenga@arm.com if (fromIEW->iewInfo.stall || 35311147Smitch.hayenga@arm.com fromCommit->commitInfo.stall) { 35411147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Receiving signal from IEW/Commit to " 35511147Smitch.hayenga@arm.com "stall.\n"); 3562SN/A block(); 35711147Smitch.hayenga@arm.com return; 35811147Smitch.hayenga@arm.com } 35911147Smitch.hayenga@arm.com 36011147Smitch.hayenga@arm.com // Check if the current status is squashing. If so, set its status 3612SN/A // to running and resume execution the next cycle. 36211147Smitch.hayenga@arm.com if (_status == Squashing) { 36311147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Done squashing.\n"); 36411147Smitch.hayenga@arm.com _status = Running; 36511147Smitch.hayenga@arm.com return; 36611147Smitch.hayenga@arm.com } 36711147Smitch.hayenga@arm.com 36811147Smitch.hayenga@arm.com // Check the decode queue to see if instructions are available. 36911147Smitch.hayenga@arm.com // If there are no available instructions to rename, then do nothing. 37011147Smitch.hayenga@arm.com // Or, if the stage is currently unblocking, then go ahead and run it. 37111147Smitch.hayenga@arm.com if (fromDecode->insts[0] == NULL && _status != Unblocking) { 37211147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Nothing to do, breaking out early.\n"); 37311147Smitch.hayenga@arm.com // Should I change status to idle? 37411147Smitch.hayenga@arm.com return; 37511147Smitch.hayenga@arm.com } 37611147Smitch.hayenga@arm.com 37711147Smitch.hayenga@arm.com DynInst *inst; 37811147Smitch.hayenga@arm.com unsigned num_inst = 0; 37911147Smitch.hayenga@arm.com 38011147Smitch.hayenga@arm.com bool insts_available = _status == Unblocking ? 38111147Smitch.hayenga@arm.com skidBuffer.front().insts[num_inst] != NULL : 38211147Smitch.hayenga@arm.com fromDecode->insts[num_inst] != NULL; 38311147Smitch.hayenga@arm.com 38411147Smitch.hayenga@arm.com typename SimpleRenameMap::RenameInfo rename_result; 38511147Smitch.hayenga@arm.com 38611147Smitch.hayenga@arm.com unsigned num_src_regs; 38711147Smitch.hayenga@arm.com unsigned num_dest_regs; 38811147Smitch.hayenga@arm.com 38911147Smitch.hayenga@arm.com // Will have to do a different calculation for the number of free 39011147Smitch.hayenga@arm.com // entries. Number of free entries recorded on this cycle - 39111147Smitch.hayenga@arm.com // renameWidth * renameToDecodeDelay 39211147Smitch.hayenga@arm.com // Can I avoid a multiply? 39311147Smitch.hayenga@arm.com unsigned free_rob_entries = 39411147Smitch.hayenga@arm.com fromCommit->commitInfo.freeROBEntries - iewToRenameDelay; 39511147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: ROB has %d free entries.\n", 39611147Smitch.hayenga@arm.com free_rob_entries); 39711147Smitch.hayenga@arm.com unsigned free_iq_entries = 39811147Smitch.hayenga@arm.com fromIEW->iewInfo.freeIQEntries - iewToRenameDelay; 39911147Smitch.hayenga@arm.com 40011147Smitch.hayenga@arm.com // Check if there's any space left. 40111147Smitch.hayenga@arm.com if (free_rob_entries == 0 || free_iq_entries == 0) { 40211147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Blocking due to no free ROB or IQ " 40310193SCurtis.Dunham@arm.com "entries.\n" 4042SN/A "Rename: ROB has %d free entries.\n" 4052SN/A "Rename: IQ has %d free entries.\n", 4062SN/A free_rob_entries, 4072623SN/A free_iq_entries); 408334SN/A block(); 40911147Smitch.hayenga@arm.com // Tell previous stage to stall. 41011147Smitch.hayenga@arm.com toDecode->renameInfo.stall = true; 41111147Smitch.hayenga@arm.com 412334SN/A return; 413334SN/A } 414334SN/A 41510905Sandreas.sandberg@arm.com unsigned min_iq_rob = min(free_rob_entries, free_iq_entries); 4162SN/A unsigned num_insts_to_rename = min(min_iq_rob, renameWidth); 4179448SAndreas.Sandberg@ARM.com 4189448SAndreas.Sandberg@ARM.com while (insts_available && 41911147Smitch.hayenga@arm.com num_inst < num_insts_to_rename) { 4202SN/A DPRINTF(Rename, "Rename: Sending instructions to iew.\n"); 4212SN/A 4222SN/A // Get the next instruction either from the skid buffer or the 42310905Sandreas.sandberg@arm.com // decode queue. 4242SN/A inst = _status == Unblocking ? skidBuffer.front().insts[num_inst] : 42511147Smitch.hayenga@arm.com fromDecode->insts[num_inst]; 4262SN/A 4272SN/A DPRINTF(Rename, "Rename: Processing instruction %i with PC %#x.\n", 4282SN/A inst, inst->readPC()); 4296221Snate@binkert.org 4302SN/A // If it's a trap instruction, then it needs to wait here within 4312SN/A // rename until the ROB is empty. Needs a way to detect that the 4322SN/A // ROB is empty. Maybe an event? 4332SN/A // Would be nice if it could be avoided putting this into a 4342623SN/A // specific stage and instead just put it into the AlphaFullCPU. 4352SN/A // Might not really be feasible though... 43611147Smitch.hayenga@arm.com // (EXCB, TRAPB) 4372SN/A if (inst->isSerializing()) { 4382SN/A panic("Rename: Serializing instruction encountered.\n"); 4392SN/A DPRINTF(Rename, "Rename: Serializing instruction " 44011151Smitch.hayenga@arm.com "encountered.\n"); 4412SN/A block(); 44211151Smitch.hayenga@arm.com 44311151Smitch.hayenga@arm.com // Change status over to BarrierStall so that other stages know 44411151Smitch.hayenga@arm.com // what this is blocked on. 44511151Smitch.hayenga@arm.com _status = BarrierStall; 44611151Smitch.hayenga@arm.com 44711147Smitch.hayenga@arm.com // Tell the previous stage to stall. 4482SN/A toDecode->renameInfo.stall = true; 4492SN/A 4502SN/A break; 4512623SN/A } 4522SN/A 45311147Smitch.hayenga@arm.com // Make sure there's enough room in the ROB and the IQ. 45411147Smitch.hayenga@arm.com // This doesn't really need to be done dynamically; consider 45511147Smitch.hayenga@arm.com // moving outside of this function. 45611147Smitch.hayenga@arm.com if (free_rob_entries == 0 || free_iq_entries == 0) { 4575704Snate@binkert.org DPRINTF(Rename, "Rename: Blocking due to lack of ROB or IQ " 45811150Smitch.hayenga@arm.com "entries.\n"); 4592SN/A // Call some sort of function to handle all the setup of being 4603520Sgblack@eecs.umich.edu // blocked. 46111147Smitch.hayenga@arm.com block(); 46211150Smitch.hayenga@arm.com 4633520Sgblack@eecs.umich.edu // Not really sure how to schedule an event properly, but an 4649023Sgblack@eecs.umich.edu // event must be scheduled such that upon freeing a ROB entry, 4652SN/A // this stage will restart up. Perhaps add in a ptr to an Event 4662SN/A // within the ROB that will be able to execute that Event 4672623SN/A // if a free register is added to the freelist. 4682SN/A 4692623SN/A // Tell the previous stage to stall. 4705894Sgblack@eecs.umich.edu toDecode->renameInfo.stall = true; 47112749Sgiacomo.travaglini@arm.com 4722623SN/A break; 47311147Smitch.hayenga@arm.com } 47411147Smitch.hayenga@arm.com 47511147Smitch.hayenga@arm.com // Temporary variables to hold number of source and destination regs. 4767720Sgblack@eecs.umich.edu num_src_regs = inst->numSrcRegs(); 47712372Smattdsinclair@gmail.com num_dest_regs = inst->numDestRegs(); 4784495Sacolyte@umich.edu 4792623SN/A // Check here to make sure there are enough destination registers 48012372Smattdsinclair@gmail.com // to rename to. Otherwise block. 4812623SN/A if (renameMap->numFreeEntries() < num_dest_regs) 48212372Smattdsinclair@gmail.com { 48312372Smattdsinclair@gmail.com DPRINTF(Rename, "Rename: Blocking due to lack of free " 4842623SN/A "physical registers to rename to.\n"); 4852623SN/A // Call function to handle blocking. 4862623SN/A block(); 4872623SN/A 4882623SN/A // Need some sort of event based on a register being freed. 4892623SN/A 49011147Smitch.hayenga@arm.com // Tell the previous stage to stall. 49111147Smitch.hayenga@arm.com toDecode->renameInfo.stall = true; 49211147Smitch.hayenga@arm.com 4932SN/A // Break out of rename loop. 4942683Sktlim@umich.edu break; 4952427SN/A } 49613611Sgabeblack@google.com 4972427SN/A // Get the architectual register numbers from the source and 4982SN/A // destination operands, and redirect them to the right register. 4992623SN/A // Will need to mark dependencies though. 50011147Smitch.hayenga@arm.com for (int src_idx = 0; src_idx < num_src_regs; src_idx++) 5017897Shestness@cs.utexas.edu { 5022SN/A RegIndex src_reg = inst->srcRegIdx(src_idx); 5032623SN/A 5042623SN/A // Look up the source registers to get the phys. register they've 5054377Sgblack@eecs.umich.edu // been renamed to, and set the sources to those registers. 5067720Sgblack@eecs.umich.edu RegIndex renamed_reg = renameMap->lookup(src_reg); 5074377Sgblack@eecs.umich.edu 5087720Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Looking up arch reg %i, got " 50911147Smitch.hayenga@arm.com "physical reg %i.\n", (int)src_reg, (int)renamed_reg); 5107720Sgblack@eecs.umich.edu 5117720Sgblack@eecs.umich.edu inst->renameSrcReg(src_idx, renamed_reg); 5125665Sgblack@eecs.umich.edu 5135665Sgblack@eecs.umich.edu // Either incorporate it into the info passed back, 5144181Sgblack@eecs.umich.edu // or make another function call to see if that register is 5154181Sgblack@eecs.umich.edu // ready or not. 5169023Sgblack@eecs.umich.edu if (renameMap->isReady(renamed_reg)) { 5179023Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Register is ready.\n"); 5184181Sgblack@eecs.umich.edu 5194182Sgblack@eecs.umich.edu inst->markSrcRegReady(src_idx); 52011147Smitch.hayenga@arm.com } 52111321Ssteve.reinhardt@amd.com } 5229023Sgblack@eecs.umich.edu 5234593Sgblack@eecs.umich.edu // Rename the destination registers. 5249023Sgblack@eecs.umich.edu for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) 5254377Sgblack@eecs.umich.edu { 5269023Sgblack@eecs.umich.edu RegIndex dest_reg = inst->destRegIdx(dest_idx); 5274377Sgblack@eecs.umich.edu 5289023Sgblack@eecs.umich.edu // Get the physical register that the destination will be 5299023Sgblack@eecs.umich.edu // renamed to. 53011147Smitch.hayenga@arm.com rename_result = renameMap->rename(dest_reg); 5317720Sgblack@eecs.umich.edu 5324377Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Renaming arch reg %i to physical " 53311147Smitch.hayenga@arm.com "register %i.\n", (int)dest_reg, 53411147Smitch.hayenga@arm.com (int)rename_result.first); 5354377Sgblack@eecs.umich.edu 5364181Sgblack@eecs.umich.edu // Record the rename information so that a history can be kept. 5374181Sgblack@eecs.umich.edu RenameHistory hb_entry(inst->seqNum, dest_reg, 5384181Sgblack@eecs.umich.edu rename_result.first, 5394539Sgblack@eecs.umich.edu rename_result.second); 5403276Sgblack@eecs.umich.edu 54111147Smitch.hayenga@arm.com historyBuffer.push_front(hb_entry); 54211147Smitch.hayenga@arm.com 5433280Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Adding instruction to history buffer, " 5443280Sgblack@eecs.umich.edu "sequence number %lli.\n", inst->seqNum); 5453276Sgblack@eecs.umich.edu 5463276Sgblack@eecs.umich.edu // Tell the instruction to rename the appropriate destination 5473276Sgblack@eecs.umich.edu // register (dest_idx) to the new physical register 5487720Sgblack@eecs.umich.edu // (rename_result.first), and record the previous physical 5493276Sgblack@eecs.umich.edu // register that the same logical register was renamed to 5503276Sgblack@eecs.umich.edu // (rename_result.second). 5514181Sgblack@eecs.umich.edu inst->renameDestReg(dest_idx, 5528955Sgblack@eecs.umich.edu rename_result.first, 5534522Ssaidi@eecs.umich.edu rename_result.second); 55411147Smitch.hayenga@arm.com } 5557720Sgblack@eecs.umich.edu 5562470SN/A // If it's an instruction with no destination registers, then put 5578955Sgblack@eecs.umich.edu // a placeholder within the history buffer. It might be better 5584181Sgblack@eecs.umich.edu // to not put it in the history buffer at all (other than branches, 5594522Ssaidi@eecs.umich.edu // which always need at least a place holder), and differentiate 5604181Sgblack@eecs.umich.edu // between instructions with and without destination registers 56110061Sandreas@sandberg.pp.se // when getting from commit the instructions that committed. 56211147Smitch.hayenga@arm.com if (num_dest_regs == 0) { 56311147Smitch.hayenga@arm.com RenameHistory hb_entry(inst->seqNum); 56410061Sandreas@sandberg.pp.se 56510061Sandreas@sandberg.pp.se historyBuffer.push_front(hb_entry); 56610061Sandreas@sandberg.pp.se 56711147Smitch.hayenga@arm.com DPRINTF(Rename, "Rename: Adding placeholder instruction to " 56810061Sandreas@sandberg.pp.se "history buffer, sequence number %lli.\n", 56911147Smitch.hayenga@arm.com inst->seqNum); 57011147Smitch.hayenga@arm.com } 57110061Sandreas@sandberg.pp.se 57210061Sandreas@sandberg.pp.se // Put instruction in rename queue. 57311147Smitch.hayenga@arm.com toIEW->insts[num_inst] = inst; 57410061Sandreas@sandberg.pp.se 5752623SN/A // Decrease the number of free ROB and IQ entries. 5762623SN/A --free_rob_entries; 5772623SN/A --free_iq_entries; 5782623SN/A 5792623SN/A // Increment which instruction we're on. 58011147Smitch.hayenga@arm.com ++num_inst; 58111147Smitch.hayenga@arm.com 58211147Smitch.hayenga@arm.com // Check whether or not there are instructions available. 5837720Sgblack@eecs.umich.edu // Either need to check within the skid buffer, or the decode 5847720Sgblack@eecs.umich.edu // queue, depending if this stage is unblocking or not. 58511147Smitch.hayenga@arm.com // Hmm, dangerous check. Can touch memory not allocated. Might 5867720Sgblack@eecs.umich.edu // be better to just do check at beginning of loop. Or better 5878780Sgblack@eecs.umich.edu // yet actually pass the number of instructions issued. 58811147Smitch.hayenga@arm.com insts_available = _status == Unblocking ? 5897720Sgblack@eecs.umich.edu skidBuffer.front().insts[num_inst] != NULL : 59011147Smitch.hayenga@arm.com fromDecode->insts[num_inst] != NULL; 59111147Smitch.hayenga@arm.com } 5922623SN/A 5932683Sktlim@umich.edu} 5942623SN/A