rename_impl.hh revision 1060
12SN/A#include <list> 29448SAndreas.Sandberg@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) 448779Sgblack@eecs.umich.edu{ 458779Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Setting rename queue pointer.\n"); 468779Sgblack@eecs.umich.edu renameQueue = rq_ptr; 472439SN/A 488779Sgblack@eecs.umich.edu // Setup wire to write information to future stages. 498229Snate@binkert.org toIEW = renameQueue->getWire(0); 506216Snate@binkert.org} 51146SN/A 52146SN/Atemplate<class Impl> 53146SN/Avoid 54146SN/ASimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) 55146SN/A{ 566216Snate@binkert.org DPRINTF(Rename, "Rename: Setting decode queue pointer.\n"); 576658Snate@binkert.org decodeQueue = dq_ptr; 588229Snate@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} 631977SN/A 642683Sktlim@umich.edutemplate<class Impl> 651717SN/Avoid 66146SN/ASimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr) 672683Sktlim@umich.edu{ 688232Snate@binkert.org DPRINTF(Rename, "Rename: Setting rename map pointer.\n"); 698232Snate@binkert.org renameMap = rm_ptr; 708232Snate@binkert.org} 718779Sgblack@eecs.umich.edu 723348Sbinkertn@umich.edutemplate<class Impl> 736105Ssteve.reinhardt@amd.comvoid 746216Snate@binkert.orgSimpleRename<Impl>::setFreeList(FreeList *fl_ptr) 752036SN/A{ 76146SN/A DPRINTF(Rename, "Rename: Setting free list pointer.\n"); 778817Sgblack@eecs.umich.edu freeList = fl_ptr; 788793Sgblack@eecs.umich.edu} 7956SN/A 8056SN/Atemplate<class Impl> 81695SN/Avoid 822901Ssaidi@eecs.umich.eduSimpleRename<Impl>::dumpHistory() 832SN/A{ 842SN/A typename list<RenameHistory>::iterator buf_it = historyBuffer.begin(); 852449SN/A 861355SN/A while (buf_it != historyBuffer.end()) 875529Snate@binkert.org { 889023Sgblack@eecs.umich.edu cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys " 89224SN/A "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg, 908793Sgblack@eecs.umich.edu (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg); 919384SAndreas.Sandberg@arm.com 929384SAndreas.Sandberg@arm.com buf_it++; 938793Sgblack@eecs.umich.edu } 948820Sgblack@eecs.umich.edu} 959384SAndreas.Sandberg@arm.com 962SN/Atemplate<class Impl> 976029Ssteve.reinhardt@amd.comvoid 982672Sktlim@umich.eduSimpleRename<Impl>::block() 992683Sktlim@umich.edu{ 1002SN/A DPRINTF(Rename, "Rename: Blocking.\n"); 1018733Sgeoffrey.blake@arm.com // Set status to Blocked. 1028733Sgeoffrey.blake@arm.com _status = Blocked; 1038733Sgeoffrey.blake@arm.com 1048733Sgeoffrey.blake@arm.com // Add the current inputs onto the skid buffer, so they can be 1058733Sgeoffrey.blake@arm.com // reprocessed when this stage unblocks. 1068733Sgeoffrey.blake@arm.com skidBuffer.push(*fromDecode); 1078733Sgeoffrey.blake@arm.com 1088733Sgeoffrey.blake@arm.com // Note that this stage only signals previous stages to stall when 1098733Sgeoffrey.blake@arm.com // it is the cause of the stall originates at this stage. Otherwise 1108733Sgeoffrey.blake@arm.com // the previous stages are expected to check all possible stall signals. 1118733Sgeoffrey.blake@arm.com} 1122SN/A 113334SN/Atemplate<class Impl> 1148834Satgutier@umich.eduinline void 1158834Satgutier@umich.eduSimpleRename<Impl>::unblock() 116140SN/A{ 117334SN/A DPRINTF(Rename, "Rename: Reading instructions out of skid " 1182SN/A "buffer.\n"); 1192SN/A // Remove the now processed instructions from the skid buffer. 1202SN/A skidBuffer.pop(); 1212680Sktlim@umich.edu 1224377Sgblack@eecs.umich.edu // If there's still information in the skid buffer, then 1235169Ssaidi@eecs.umich.edu // continue to tell previous stages to stall. They will be 1244377Sgblack@eecs.umich.edu // able to restart once the skid buffer is empty. 1254377Sgblack@eecs.umich.edu if (!skidBuffer.empty()) { 1262SN/A toDecode->renameInfo.stall = true; 1272SN/A } else { 1282623SN/A DPRINTF(Rename, "Rename: Done unblocking.\n"); 1292SN/A _status = Running; 1302SN/A } 1312SN/A} 132180SN/A 1338737Skoansin.tan@gmail.comtemplate<class Impl> 134393SN/Avoid 135393SN/ASimpleRename<Impl>::doSquash() 136393SN/A{ 137393SN/A typename list<RenameHistory>::iterator hb_it = historyBuffer.begin(); 138384SN/A typename list<RenameHistory>::iterator delete_it; 139384SN/A 140393SN/A InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum; 1418737Skoansin.tan@gmail.com 142393SN/A#ifdef FULL_SYSTEM 143393SN/A assert(!historyBuffer.empty()); 144393SN/A#else 145393SN/A // After a syscall squashes everything, the history buffer may be empty 146384SN/A // but the ROB may still be squashing instructions. 147189SN/A if (historyBuffer.empty()) { 148189SN/A return; 1492623SN/A } 1502SN/A#endif // FULL_SYSTEM 151729SN/A 152334SN/A // Go through the most recent instructions, undoing the mappings 1532SN/A // they did and freeing up the registers. 1542SN/A while ((*hb_it).instSeqNum > squashed_seq_num) 1552SN/A { 1568834Satgutier@umich.edu DPRINTF(Rename, "Rename: Removing history entry with sequence " 1578834Satgutier@umich.edu "number %i.\n", (*hb_it).instSeqNum); 1588834Satgutier@umich.edu 1598834Satgutier@umich.edu // If it's not simply a place holder, then add the registers. 1608834Satgutier@umich.edu if (!(*hb_it).placeHolder) { 1618834Satgutier@umich.edu // Tell the rename map to set the architected register to the 1628834Satgutier@umich.edu // previous physical register that it was renamed to. 1632SN/A renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg); 1642SN/A 1657897Shestness@cs.utexas.edu // Put the renamed physical register back on the free list. 1667897Shestness@cs.utexas.edu freeList->addReg(hb_it->newPhysReg); 1677897Shestness@cs.utexas.edu } 1687897Shestness@cs.utexas.edu 1697897Shestness@cs.utexas.edu delete_it = hb_it; 1707897Shestness@cs.utexas.edu 1717897Shestness@cs.utexas.edu hb_it++; 1727897Shestness@cs.utexas.edu 1737897Shestness@cs.utexas.edu historyBuffer.erase(delete_it); 1747897Shestness@cs.utexas.edu } 1757897Shestness@cs.utexas.edu} 1767897Shestness@cs.utexas.edu 1777897Shestness@cs.utexas.edutemplate<class Impl> 1787897Shestness@cs.utexas.eduvoid 1797897Shestness@cs.utexas.eduSimpleRename<Impl>::squash() 1807897Shestness@cs.utexas.edu{ 1817897Shestness@cs.utexas.edu DPRINTF(Rename, "Rename: Squashing instructions.\n"); 1827897Shestness@cs.utexas.edu // Set the status to Squashing. 1837897Shestness@cs.utexas.edu _status = Squashing; 1847897Shestness@cs.utexas.edu 1857897Shestness@cs.utexas.edu // Clear the skid buffer in case it has any data in it. 1867897Shestness@cs.utexas.edu while (!skidBuffer.empty()) 1877897Shestness@cs.utexas.edu { 1887897Shestness@cs.utexas.edu skidBuffer.pop(); 1897897Shestness@cs.utexas.edu } 1907897Shestness@cs.utexas.edu 1917897Shestness@cs.utexas.edu doSquash(); 1927897Shestness@cs.utexas.edu} 1937897Shestness@cs.utexas.edu 1947897Shestness@cs.utexas.edu// In the future, when a SmartPtr is used for DynInst, then this function 1957897Shestness@cs.utexas.edu// itself can handle returning the instruction's physical registers to 1967897Shestness@cs.utexas.edu// the free list. 1977897Shestness@cs.utexas.edutemplate<class Impl> 1987897Shestness@cs.utexas.eduvoid 1997897Shestness@cs.utexas.eduSimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num) 2007897Shestness@cs.utexas.edu{ 2017897Shestness@cs.utexas.edu DPRINTF(Rename, "Rename: Removing a committed instruction from the " 2027897Shestness@cs.utexas.edu "history buffer, sequence number %lli.\n", inst_seq_num); 2037897Shestness@cs.utexas.edu typename list<RenameHistory>::iterator hb_it = historyBuffer.end(); 2047897Shestness@cs.utexas.edu 2057897Shestness@cs.utexas.edu hb_it--; 2067897Shestness@cs.utexas.edu 2077897Shestness@cs.utexas.edu if (hb_it->instSeqNum > inst_seq_num) { 2087897Shestness@cs.utexas.edu DPRINTF(Rename, "Rename: Old sequence number encountered. Ensure " 2097897Shestness@cs.utexas.edu "that a syscall happened recently.\n"); 2107897Shestness@cs.utexas.edu return; 2117897Shestness@cs.utexas.edu } 2127897Shestness@cs.utexas.edu 2137897Shestness@cs.utexas.edu for ( ; hb_it->instSeqNum != inst_seq_num; hb_it--) 2147897Shestness@cs.utexas.edu { 2159920Syasuko.eckert@amd.com // Make sure we haven't gone off the end of the list. 2169920Syasuko.eckert@amd.com assert(hb_it != historyBuffer.end()); 2179920Syasuko.eckert@amd.com 2189920Syasuko.eckert@amd.com // In theory instructions at the end of the history buffer 2199920Syasuko.eckert@amd.com // should be older than the instruction being removed, which 2209920Syasuko.eckert@amd.com // means they will have a lower sequence number. Also the 2219920Syasuko.eckert@amd.com // instruction being removed from the history really should 2229920Syasuko.eckert@amd.com // be the last instruction in the list, as it is the instruction 2239920Syasuko.eckert@amd.com // that was just committed that is being removed. 2249920Syasuko.eckert@amd.com assert(hb_it->instSeqNum < inst_seq_num); 2259920Syasuko.eckert@amd.com DPRINTF(Rename, "Rename: Committed instruction is not the last " 2269920Syasuko.eckert@amd.com "entry in the history buffer.\n"); 2272SN/A } 2287897Shestness@cs.utexas.edu 2297897Shestness@cs.utexas.edu if (!(*hb_it).placeHolder) { 2307897Shestness@cs.utexas.edu freeList->addReg(hb_it->prevPhysReg); 2317897Shestness@cs.utexas.edu } 2327897Shestness@cs.utexas.edu 2337897Shestness@cs.utexas.edu historyBuffer.erase(hb_it); 2347897Shestness@cs.utexas.edu 2357897Shestness@cs.utexas.edu} 2367897Shestness@cs.utexas.edu 2377897Shestness@cs.utexas.edutemplate<class Impl> 2387897Shestness@cs.utexas.eduvoid 2397897Shestness@cs.utexas.eduSimpleRename<Impl>::tick() 2402SN/A{ 2412SN/A // Rename will need to try to rename as many instructions as it 2421001SN/A // has bandwidth, unless it is blocked. 2431001SN/A 2441001SN/A // Check if _status is BarrierStall. If so, then check if the number 2451001SN/A // of free ROB entries is equal to the number of total ROB entries. 2461001SN/A // Once equal then wake this stage up. Set status to unblocking maybe. 2472SN/A 2482SN/A if (_status != Blocked && _status != Squashing) { 2492SN/A DPRINTF(Rename, "Rename: Status is not blocked, will attempt to " 2502SN/A "run stage.\n"); 2512SN/A // Make sure that the skid buffer has something in it if the 2527897Shestness@cs.utexas.edu // status is unblocking. 2537897Shestness@cs.utexas.edu assert(_status == Unblocking ? !skidBuffer.empty() : 1); 2547897Shestness@cs.utexas.edu 2557897Shestness@cs.utexas.edu rename(); 2567897Shestness@cs.utexas.edu 2577897Shestness@cs.utexas.edu // If the status was unblocking, then instructions from the skid 2587897Shestness@cs.utexas.edu // buffer were used. Remove those instructions and handle 2597897Shestness@cs.utexas.edu // the rest of unblocking. 2607897Shestness@cs.utexas.edu if (_status == Unblocking) { 2617897Shestness@cs.utexas.edu unblock(); 2622SN/A } 2632SN/A } else if (_status == Blocked) { 2642SN/A // If stage is blocked and still receiving valid instructions, 2652SN/A // make sure to store them in the skid buffer. 2662SN/A if (fromDecode->insts[0] != NULL) { 2672SN/A 2682SN/A block(); 2692SN/A 2702SN/A // Continue to tell previous stage to stall. 2712SN/A toDecode->renameInfo.stall = true; 2722SN/A } 2732SN/A 2742390SN/A if (!fromIEW->iewInfo.stall && 2752390SN/A !fromCommit->commitInfo.stall && 2762390SN/A fromCommit->commitInfo.freeROBEntries != 0 && 2772390SN/A fromIEW->iewInfo.freeIQEntries != 0) { 2782390SN/A 2792390SN/A // Need to be sure to check all blocking conditions above. 2802390SN/A // If they have cleared, then start unblocking. 2812390SN/A DPRINTF(Rename, "Rename: Stall signals cleared, going to " 2822390SN/A "unblock.\n"); 2832390SN/A _status = Unblocking; 2842390SN/A 2852390SN/A // Continue to tell previous stage to block until this stage 286385SN/A // is done unblocking. 2877897Shestness@cs.utexas.edu toDecode->renameInfo.stall = true; 2887897Shestness@cs.utexas.edu } else { 2892SN/A // Otherwise no conditions have changed. Tell previous 2902SN/A // stage to continue blocking. 2912SN/A toDecode->renameInfo.stall = true; 2922623SN/A } 293334SN/A 2942361SN/A if (fromCommit->commitInfo.squash || 2955496Ssaidi@eecs.umich.edu fromCommit->commitInfo.robSquashing) { 296334SN/A squash(); 297334SN/A return; 298334SN/A } 2999448SAndreas.Sandberg@ARM.com } else if (_status == Squashing) { 3002SN/A if (fromCommit->commitInfo.squash) { 3019448SAndreas.Sandberg@ARM.com squash(); 3029448SAndreas.Sandberg@ARM.com } else if (!fromCommit->commitInfo.squash && 3039448SAndreas.Sandberg@ARM.com !fromCommit->commitInfo.robSquashing) { 3042683Sktlim@umich.edu 3052SN/A DPRINTF(Rename, "Rename: Done squashing, going to running.\n"); 3062SN/A _status = Running; 3072SN/A } else { 3089448SAndreas.Sandberg@ARM.com doSquash(); 3099448SAndreas.Sandberg@ARM.com } 3102SN/A } 3119448SAndreas.Sandberg@ARM.com 3129448SAndreas.Sandberg@ARM.com // Ugly code, revamp all of the tick() functions eventually. 3139448SAndreas.Sandberg@ARM.com if (fromCommit->commitInfo.doneSeqNum != 0 && _status != Squashing) { 3142SN/A removeFromHistory(fromCommit->commitInfo.doneSeqNum); 3152SN/A } 3162SN/A 3176221Snate@binkert.org // Perhaps put this outside of this function, since this will 3182SN/A // happen regardless of whether or not the stage is blocked or 3192SN/A // squashing. 3202SN/A // Read from the time buffer any necessary data. 3212SN/A // Read registers that are freed, and add them to the freelist. 3222623SN/A // This is unnecessary due to the history buffer (assuming the history 3232SN/A // buffer works properly). 3242680Sktlim@umich.edu/* 3252SN/A while(!fromCommit->commitInfo.freeRegs.empty()) 3262SN/A { 3272SN/A PhysRegIndex freed_reg = fromCommit->commitInfo.freeRegs.back(); 3285807Snate@binkert.org DPRINTF(Rename, "Rename: Adding freed register %i to freelist.\n", 3292SN/A (int)freed_reg); 3305807Snate@binkert.org freeList->addReg(freed_reg); 3315807Snate@binkert.org 3322SN/A fromCommit->commitInfo.freeRegs.pop_back(); 3335807Snate@binkert.org } 3345807Snate@binkert.org*/ 3352SN/A 3362SN/A} 3372SN/A 3382623SN/Atemplate<class Impl> 3392SN/Avoid 3405704Snate@binkert.orgSimpleRename<Impl>::rename() 3415647Sgblack@eecs.umich.edu{ 3422SN/A // Check if any of the stages ahead of rename are telling rename 3433520Sgblack@eecs.umich.edu // to squash. The squash() function will also take care of fixing up 3447338SAli.Saidi@ARM.com // the rename map and the free list. 3455647Sgblack@eecs.umich.edu if (fromCommit->commitInfo.squash || 3463520Sgblack@eecs.umich.edu fromCommit->commitInfo.robSquashing) { 3479023Sgblack@eecs.umich.edu squash(); 3482SN/A return; 3492SN/A } 3502623SN/A 3512SN/A // Check if time buffer is telling this stage to stall. 3522623SN/A if (fromIEW->iewInfo.stall || 3535894Sgblack@eecs.umich.edu fromCommit->commitInfo.stall) { 3542662Sstever@eecs.umich.edu DPRINTF(Rename, "Rename: Receiving signal from IEW/Commit to " 3552623SN/A "stall.\n"); 3567720Sgblack@eecs.umich.edu block(); 3574495Sacolyte@umich.edu return; 3582623SN/A } 3597720Sgblack@eecs.umich.edu 3602623SN/A // Check if the current status is squashing. If so, set its status 3617720Sgblack@eecs.umich.edu // to running and resume execution the next cycle. 3628832SAli.Saidi@ARM.com if (_status == Squashing) { 3638832SAli.Saidi@ARM.com DPRINTF(Rename, "Rename: Done squashing.\n"); 3642623SN/A _status = Running; 3652623SN/A return; 3662623SN/A } 3672623SN/A 3682623SN/A // Check the decode queue to see if instructions are available. 3692623SN/A // If there are no available instructions to rename, then do nothing. 3702SN/A // Or, if the stage is currently unblocking, then go ahead and run it. 3712683Sktlim@umich.edu if (fromDecode->insts[0] == NULL && _status != Unblocking) { 3722427SN/A DPRINTF(Rename, "Rename: Nothing to do, breaking out early.\n"); 3732683Sktlim@umich.edu // Should I change status to idle? 3742427SN/A return; 3752SN/A } 3762623SN/A 3772623SN/A DynInst *inst; 3787897Shestness@cs.utexas.edu unsigned num_inst = 0; 3792SN/A 3802623SN/A bool insts_available = _status == Unblocking ? 3812623SN/A skidBuffer.front().insts[num_inst] != NULL : 3824377Sgblack@eecs.umich.edu fromDecode->insts[num_inst] != NULL; 3837720Sgblack@eecs.umich.edu 3844377Sgblack@eecs.umich.edu typename SimpleRenameMap::RenameInfo rename_result; 3857720Sgblack@eecs.umich.edu 3865665Sgblack@eecs.umich.edu unsigned num_src_regs; 3877720Sgblack@eecs.umich.edu unsigned num_dest_regs; 3887720Sgblack@eecs.umich.edu 3895665Sgblack@eecs.umich.edu // Will have to do a different calculation for the number of free 3905665Sgblack@eecs.umich.edu // entries. Number of free entries recorded on this cycle - 3914181Sgblack@eecs.umich.edu // renameWidth * renameToDecodeDelay 3924181Sgblack@eecs.umich.edu // Can I avoid a multiply? 3939023Sgblack@eecs.umich.edu unsigned free_rob_entries = 3949023Sgblack@eecs.umich.edu fromCommit->commitInfo.freeROBEntries - iewToRenameDelay; 3954181Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: ROB has %d free entries.\n", 3964182Sgblack@eecs.umich.edu free_rob_entries); 3977720Sgblack@eecs.umich.edu unsigned free_iq_entries = 3989023Sgblack@eecs.umich.edu fromIEW->iewInfo.freeIQEntries - iewToRenameDelay; 3999023Sgblack@eecs.umich.edu 4004593Sgblack@eecs.umich.edu // Check if there's any space left. 4019023Sgblack@eecs.umich.edu if (free_rob_entries == 0 || free_iq_entries == 0) { 4024377Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Blocking due to no free ROB or IQ " 4039023Sgblack@eecs.umich.edu "entries.\n" 4044377Sgblack@eecs.umich.edu "Rename: ROB has %d free entries.\n" 4059023Sgblack@eecs.umich.edu "Rename: IQ has %d free entries.\n", 4069023Sgblack@eecs.umich.edu free_rob_entries, 4074377Sgblack@eecs.umich.edu free_iq_entries); 4087720Sgblack@eecs.umich.edu block(); 4094377Sgblack@eecs.umich.edu // Tell previous stage to stall. 4104377Sgblack@eecs.umich.edu toDecode->renameInfo.stall = true; 4114377Sgblack@eecs.umich.edu 4124377Sgblack@eecs.umich.edu return; 4134181Sgblack@eecs.umich.edu } 4144181Sgblack@eecs.umich.edu 4154181Sgblack@eecs.umich.edu unsigned min_iq_rob = min(free_rob_entries, free_iq_entries); 4164539Sgblack@eecs.umich.edu unsigned num_insts_to_rename = min(min_iq_rob, renameWidth); 4173276Sgblack@eecs.umich.edu 4187720Sgblack@eecs.umich.edu while (insts_available && 4193280Sgblack@eecs.umich.edu num_inst < num_insts_to_rename) { 4203280Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Sending instructions to iew.\n"); 4213276Sgblack@eecs.umich.edu 4223276Sgblack@eecs.umich.edu // Get the next instruction either from the skid buffer or the 4233276Sgblack@eecs.umich.edu // decode queue. 4247720Sgblack@eecs.umich.edu inst = _status == Unblocking ? skidBuffer.front().insts[num_inst] : 4253276Sgblack@eecs.umich.edu fromDecode->insts[num_inst]; 4263276Sgblack@eecs.umich.edu 4274181Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Processing instruction %i with PC %#x.\n", 4288955Sgblack@eecs.umich.edu inst, inst->readPC()); 4294522Ssaidi@eecs.umich.edu 4307823Ssteve.reinhardt@amd.com // If it's a trap instruction, then it needs to wait here within 4317720Sgblack@eecs.umich.edu // rename until the ROB is empty. Needs a way to detect that the 4322470SN/A // ROB is empty. Maybe an event? 4338955Sgblack@eecs.umich.edu // Would be nice if it could be avoided putting this into a 4344181Sgblack@eecs.umich.edu // specific stage and instead just put it into the AlphaFullCPU. 4354522Ssaidi@eecs.umich.edu // Might not really be feasible though... 4364181Sgblack@eecs.umich.edu // (EXCB, TRAPB) 4372623SN/A if (inst->isSerializing()) { 4382623SN/A panic("Rename: Serializing instruction encountered.\n"); 4392623SN/A DPRINTF(Rename, "Rename: Serializing instruction " 4402623SN/A "encountered.\n"); 4412623SN/A block(); 4427720Sgblack@eecs.umich.edu 4437720Sgblack@eecs.umich.edu // Change status over to BarrierStall so that other stages know 4447720Sgblack@eecs.umich.edu // what this is blocked on. 4457720Sgblack@eecs.umich.edu _status = BarrierStall; 4468780Sgblack@eecs.umich.edu 4473577Sgblack@eecs.umich.edu // Tell the previous stage to stall. 4487720Sgblack@eecs.umich.edu toDecode->renameInfo.stall = true; 4495086Sgblack@eecs.umich.edu 4502623SN/A break; 4512683Sktlim@umich.edu } 4522623SN/A 4532SN/A // Make sure there's enough room in the ROB and the IQ. 4542623SN/A // This doesn't really need to be done dynamically; consider 4552623SN/A // moving outside of this function. 4562SN/A if (free_rob_entries == 0 || free_iq_entries == 0) { 4572SN/A DPRINTF(Rename, "Rename: Blocking due to lack of ROB or IQ " 4582623SN/A "entries.\n"); 4592623SN/A // Call some sort of function to handle all the setup of being 4602623SN/A // blocked. 4612623SN/A block(); 4622SN/A 4635953Ssaidi@eecs.umich.edu // Not really sure how to schedule an event properly, but an 4647720Sgblack@eecs.umich.edu // event must be scheduled such that upon freeing a ROB entry, 4655953Ssaidi@eecs.umich.edu // this stage will restart up. Perhaps add in a ptr to an Event 4665953Ssaidi@eecs.umich.edu // within the ROB that will be able to execute that Event 4677897Shestness@cs.utexas.edu // if a free register is added to the freelist. 4687897Shestness@cs.utexas.edu 4697897Shestness@cs.utexas.edu // Tell the previous stage to stall. 4707897Shestness@cs.utexas.edu toDecode->renameInfo.stall = true; 4717897Shestness@cs.utexas.edu 4727897Shestness@cs.utexas.edu break; 4737897Shestness@cs.utexas.edu } 4747897Shestness@cs.utexas.edu 4757897Shestness@cs.utexas.edu // Temporary variables to hold number of source and destination regs. 4767897Shestness@cs.utexas.edu num_src_regs = inst->numSrcRegs(); 4777897Shestness@cs.utexas.edu num_dest_regs = inst->numDestRegs(); 4787897Shestness@cs.utexas.edu 4797897Shestness@cs.utexas.edu // Check here to make sure there are enough destination registers 4807897Shestness@cs.utexas.edu // to rename to. Otherwise block. 4817897Shestness@cs.utexas.edu if (renameMap->numFreeEntries() < num_dest_regs) 4827897Shestness@cs.utexas.edu { 4837897Shestness@cs.utexas.edu DPRINTF(Rename, "Rename: Blocking due to lack of free " 4847897Shestness@cs.utexas.edu "physical registers to rename to.\n"); 4857897Shestness@cs.utexas.edu // Call function to handle blocking. 4867897Shestness@cs.utexas.edu block(); 4877897Shestness@cs.utexas.edu 4887897Shestness@cs.utexas.edu // Need some sort of event based on a register being freed. 4897897Shestness@cs.utexas.edu 4907897Shestness@cs.utexas.edu // Tell the previous stage to stall. 4917897Shestness@cs.utexas.edu toDecode->renameInfo.stall = true; 4927897Shestness@cs.utexas.edu 4937897Shestness@cs.utexas.edu // Break out of rename loop. 4947897Shestness@cs.utexas.edu break; 4957897Shestness@cs.utexas.edu } 4967897Shestness@cs.utexas.edu 4977897Shestness@cs.utexas.edu // Get the architectual register numbers from the source and 4987897Shestness@cs.utexas.edu // destination operands, and redirect them to the right register. 4997897Shestness@cs.utexas.edu // Will need to mark dependencies though. 5008780Sgblack@eecs.umich.edu for (int src_idx = 0; src_idx < num_src_regs; src_idx++) 5018780Sgblack@eecs.umich.edu { 5022644Sstever@eecs.umich.edu RegIndex src_reg = inst->srcRegIdx(src_idx); 5032644Sstever@eecs.umich.edu 5044046Sbinkertn@umich.edu // Look up the source registers to get the phys. register they've 5054046Sbinkertn@umich.edu // been renamed to, and set the sources to those registers. 5064046Sbinkertn@umich.edu RegIndex renamed_reg = renameMap->lookup(src_reg); 5072644Sstever@eecs.umich.edu 5082623SN/A DPRINTF(Rename, "Rename: Looking up arch reg %i, got " 5092SN/A "physical reg %i.\n", (int)src_reg, (int)renamed_reg); 5102SN/A 5112623SN/A inst->renameSrcReg(src_idx, renamed_reg); 5122623SN/A 5132623SN/A // Either incorporate it into the info passed back, 5144377Sgblack@eecs.umich.edu // or make another function call to see if that register is 5154377Sgblack@eecs.umich.edu // ready or not. 5162090SN/A if (renameMap->isReady(renamed_reg)) { 5173905Ssaidi@eecs.umich.edu DPRINTF(Rename, "Rename: Register is ready.\n"); 5187678Sgblack@eecs.umich.edu 5199023Sgblack@eecs.umich.edu inst->markSrcRegReady(src_idx); 5204377Sgblack@eecs.umich.edu } 5217720Sgblack@eecs.umich.edu } 5227720Sgblack@eecs.umich.edu 5237720Sgblack@eecs.umich.edu // Rename the destination registers. 5247720Sgblack@eecs.umich.edu for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) 5257720Sgblack@eecs.umich.edu { 5267720Sgblack@eecs.umich.edu RegIndex dest_reg = inst->destRegIdx(dest_idx); 5273276Sgblack@eecs.umich.edu 5282SN/A // Get the physical register that the destination will be 5292SN/A // renamed to. 5302SN/A rename_result = renameMap->rename(dest_reg); 5319461Snilay@cs.wisc.edu 5329461Snilay@cs.wisc.edu DPRINTF(Rename, "Rename: Renaming arch reg %i to physical " 5339461Snilay@cs.wisc.edu "register %i.\n", (int)dest_reg, 5349461Snilay@cs.wisc.edu (int)rename_result.first); 5359461Snilay@cs.wisc.edu 5369461Snilay@cs.wisc.edu // Record the rename information so that a history can be kept. 537 RenameHistory hb_entry(inst->seqNum, dest_reg, 538 rename_result.first, 539 rename_result.second); 540 541 historyBuffer.push_front(hb_entry); 542 543 DPRINTF(Rename, "Rename: Adding instruction to history buffer, " 544 "sequence number %lli.\n", inst->seqNum); 545 546 // Tell the instruction to rename the appropriate destination 547 // register (dest_idx) to the new physical register 548 // (rename_result.first), and record the previous physical 549 // register that the same logical register was renamed to 550 // (rename_result.second). 551 inst->renameDestReg(dest_idx, 552 rename_result.first, 553 rename_result.second); 554 } 555 556 // If it's an instruction with no destination registers, then put 557 // a placeholder within the history buffer. It might be better 558 // to not put it in the history buffer at all (other than branches, 559 // which always need at least a place holder), and differentiate 560 // between instructions with and without destination registers 561 // when getting from commit the instructions that committed. 562 if (num_dest_regs == 0) { 563 RenameHistory hb_entry(inst->seqNum); 564 565 historyBuffer.push_front(hb_entry); 566 567 DPRINTF(Rename, "Rename: Adding placeholder instruction to " 568 "history buffer, sequence number %lli.\n", 569 inst->seqNum); 570 } 571 572 // Put instruction in rename queue. 573 toIEW->insts[num_inst] = inst; 574 575 // Decrease the number of free ROB and IQ entries. 576 --free_rob_entries; 577 --free_iq_entries; 578 579 // Increment which instruction we're on. 580 ++num_inst; 581 582 // Check whether or not there are instructions available. 583 // Either need to check within the skid buffer, or the decode 584 // queue, depending if this stage is unblocking or not. 585 // Hmm, dangerous check. Can touch memory not allocated. Might 586 // be better to just do check at beginning of loop. Or better 587 // yet actually pass the number of instructions issued. 588 insts_available = _status == Unblocking ? 589 skidBuffer.front().insts[num_inst] != NULL : 590 fromDecode->insts[num_inst] != NULL; 591 } 592 593} 594