2c2
< * Copyright (c) 2004-2006 The Regents of The University of Michigan
---
> * Copyright (c) 2004-2005 The Regents of The University of Michigan
26a27,28
> *
> * Authors: Kevin Lim
34,35d35
< using namespace std;
<
37,43c37,43
< DefaultRename<Impl>::DefaultRename(Params *params)
< : iewToRenameDelay(params->iewToRenameDelay),
< decodeToRenameDelay(params->decodeToRenameDelay),
< commitToRenameDelay(params->commitToRenameDelay),
< renameWidth(params->renameWidth),
< commitWidth(params->commitWidth),
< numThreads(params->numberOfThreads)
---
> SimpleRename<Impl>::SimpleRename(Params &params)
> : iewToRenameDelay(params.iewToRenameDelay),
> decodeToRenameDelay(params.decodeToRenameDelay),
> commitToRenameDelay(params.commitToRenameDelay),
> renameWidth(params.renameWidth),
> commitWidth(params.commitWidth),
> numInst(0)
45,66c45
< _status = Inactive;
<
< for (int i=0; i< numThreads; i++) {
< renameStatus[i] = Idle;
<
< freeEntries[i].iqEntries = 0;
< freeEntries[i].lsqEntries = 0;
< freeEntries[i].robEntries = 0;
<
< stalls[i].iew = false;
< stalls[i].commit = false;
< serializeInst[i] = NULL;
<
< instsInProgress[i] = 0;
<
< emptyROB[i] = true;
<
< serializeOnNextInst[i] = false;
< }
<
< // @todo: Make into a parameter.
< skidBufferMax = (2 * (iewToRenameDelay * params->decodeWidth)) + renameWidth;
---
> _status = Idle;
70,76d48
< std::string
< DefaultRename<Impl>::name() const
< {
< return cpu->name() + ".rename";
< }
<
< template <class Impl>
78c50
< DefaultRename<Impl>::regStats()
---
> SimpleRename<Impl>::regStats()
81c53
< .name(name() + ".RENAME:SquashCycles")
---
> .name(name() + ".renameSquashCycles")
85c57
< .name(name() + ".RENAME:IdleCycles")
---
> .name(name() + ".renameIdleCycles")
89c61
< .name(name() + ".RENAME:BlockCycles")
---
> .name(name() + ".renameBlockCycles")
92,99d63
< renameSerializeStallCycles
< .name(name() + ".RENAME:serializeStallCycles")
< .desc("count of cycles rename stalled for serializing inst")
< .flags(Stats::total);
< renameRunCycles
< .name(name() + ".RENAME:RunCycles")
< .desc("Number of cycles rename is running")
< .prereq(renameIdleCycles);
101c65
< .name(name() + ".RENAME:UnblockCycles")
---
> .name(name() + ".renameUnblockCycles")
105c69
< .name(name() + ".RENAME:RenamedInsts")
---
> .name(name() + ".renameRenamedInsts")
109c73
< .name(name() + ".RENAME:SquashedInsts")
---
> .name(name() + ".renameSquashedInsts")
113,114c77,78
< .name(name() + ".RENAME:ROBFullEvents")
< .desc("Number of times rename has blocked due to ROB full")
---
> .name(name() + ".renameROBFullEvents")
> .desc("Number of times rename has considered the ROB 'full'")
117,118c81,82
< .name(name() + ".RENAME:IQFullEvents")
< .desc("Number of times rename has blocked due to IQ full")
---
> .name(name() + ".renameIQFullEvents")
> .desc("Number of times rename has considered the IQ 'full'")
120,123d83
< renameLSQFullEvents
< .name(name() + ".RENAME:LSQFullEvents")
< .desc("Number of times rename has blocked due to LSQ full")
< .prereq(renameLSQFullEvents);
125c85
< .name(name() + ".RENAME:FullRegisterEvents")
---
> .name(name() + ".renameFullRegisterEvents")
129c89
< .name(name() + ".RENAME:RenamedOperands")
---
> .name(name() + ".renameRenamedOperands")
133c93
< .name(name() + ".RENAME:RenameLookups")
---
> .name(name() + ".renameRenameLookups")
135a96,99
> renameHBPlaceHolders
> .name(name() + ".renameHBPlaceHolders")
> .desc("Number of place holders added to the history buffer")
> .prereq(renameHBPlaceHolders);
137c101
< .name(name() + ".RENAME:CommittedMaps")
---
> .name(name() + ".renameCommittedMaps")
141c105
< .name(name() + ".RENAME:UndoneMaps")
---
> .name(name() + ".renameUndoneMaps")
144,158c108,111
< renamedSerializing
< .name(name() + ".RENAME:serializingInsts")
< .desc("count of serializing insts renamed")
< .flags(Stats::total)
< ;
< renamedTempSerializing
< .name(name() + ".RENAME:tempSerializingInsts")
< .desc("count of temporary serializing insts renamed")
< .flags(Stats::total)
< ;
< renameSkidInsts
< .name(name() + ".RENAME:skidInsts")
< .desc("count of insts added to the skid buffer")
< .flags(Stats::total)
< ;
---
> renameValidUndoneMaps
> .name(name() + ".renameValidUndoneMaps")
> .desc("Number of HB maps that are undone, and are not place holders")
> .prereq(renameValidUndoneMaps);
163c116
< DefaultRename<Impl>::setCPU(FullCPU *cpu_ptr)
---
> SimpleRename<Impl>::setCPU(FullCPU *cpu_ptr)
165c118
< DPRINTF(Rename, "Setting CPU pointer.\n");
---
> DPRINTF(Rename, "Rename: Setting CPU pointer.\n");
171c124
< DefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
---
> SimpleRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
173c126
< DPRINTF(Rename, "Setting time buffer pointer.\n");
---
> DPRINTF(Rename, "Rename: Setting time buffer pointer.\n");
188c141
< DefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
---
> SimpleRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
190c143
< DPRINTF(Rename, "Setting rename queue pointer.\n");
---
> DPRINTF(Rename, "Rename: Setting rename queue pointer.\n");
199c152
< DefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
---
> SimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
201c154
< DPRINTF(Rename, "Setting decode queue pointer.\n");
---
> DPRINTF(Rename, "Rename: Setting decode queue pointer.\n");
210c163
< DefaultRename<Impl>::initStage()
---
> SimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr)
212,218c165,166
< // Grab the number of free entries directly from the stages.
< for (int tid=0; tid < numThreads; tid++) {
< freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
< freeEntries[tid].lsqEntries = iew_ptr->ldstQueue.numFreeEntries(tid);
< freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
< emptyROB[tid] = true;
< }
---
> DPRINTF(Rename, "Rename: Setting rename map pointer.\n");
> renameMap = rm_ptr;
221,229d168
< template<class Impl>
< void
< DefaultRename<Impl>::setActiveThreads(list<unsigned> *at_ptr)
< {
< DPRINTF(Rename, "Setting active threads list pointer.\n");
< activeThreads = at_ptr;
< }
<
<
232c171
< DefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[])
---
> SimpleRename<Impl>::setFreeList(FreeList *fl_ptr)
234,245c173
< DPRINTF(Rename, "Setting rename map pointers.\n");
<
< for (int i=0; i<numThreads; i++) {
< renameMap[i] = &rm_ptr[i];
< }
< }
<
< template <class Impl>
< void
< DefaultRename<Impl>::setFreeList(FreeList *fl_ptr)
< {
< DPRINTF(Rename, "Setting free list pointer.\n");
---
> DPRINTF(Rename, "Rename: Setting free list pointer.\n");
249,256d176
< template<class Impl>
< void
< DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
< {
< DPRINTF(Rename, "Setting scoreboard pointer.\n");
< scoreboard = _scoreboard;
< }
<
259c179
< DefaultRename<Impl>::switchOut()
---
> SimpleRename<Impl>::dumpHistory()
261,262c181
< cpu->signalSwitched();
< }
---
> typename list<RenameHistory>::iterator buf_it = historyBuffer.begin();
264,269c183,187
< template <class Impl>
< void
< DefaultRename<Impl>::doSwitchOut()
< {
< for (int i = 0; i < numThreads; i++) {
< typename list<RenameHistory>::iterator hb_it = historyBuffer[i].begin();
---
> while (buf_it != historyBuffer.end())
> {
> cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
> "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
> (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
271,287c189
< while (!historyBuffer[i].empty()) {
< assert(hb_it != historyBuffer[i].end());
<
< DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
< "number %i.\n", i, (*hb_it).instSeqNum);
<
< // Tell the rename map to set the architected register to the
< // previous physical register that it was renamed to.
< renameMap[i]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
<
< // Put the renamed physical register back on the free list.
< freeList->addReg(hb_it->newPhysReg);
<
< historyBuffer[i].erase(hb_it++);
< }
< insts[i].clear();
< skidBuffer[i].clear();
---
> buf_it++;
293c195
< DefaultRename<Impl>::takeOverFrom()
---
> SimpleRename<Impl>::block()
295,296c197,199
< _status = Inactive;
< initStage();
---
> DPRINTF(Rename, "Rename: Blocking.\n");
> // Set status to Blocked.
> _status = Blocked;
298,300c201,203
< // Reset all state prior to taking over from the other CPU.
< for (int i=0; i< numThreads; i++) {
< renameStatus[i] = Idle;
---
> // Add the current inputs onto the skid buffer, so they can be
> // reprocessed when this stage unblocks.
> skidBuffer.push(*fromDecode);
302,311c205,207
< stalls[i].iew = false;
< stalls[i].commit = false;
< serializeInst[i] = NULL;
<
< instsInProgress[i] = 0;
<
< emptyROB[i] = true;
<
< serializeOnNextInst[i] = false;
< }
---
> // Note that this stage only signals previous stages to stall when
> // it is the cause of the stall originates at this stage. Otherwise
> // the previous stages are expected to check all possible stall signals.
315,316c211,212
< void
< DefaultRename<Impl>::squash(unsigned tid)
---
> inline void
> SimpleRename<Impl>::unblock()
318c214,217
< DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid);
---
> DPRINTF(Rename, "Rename: Read instructions out of skid buffer this "
> "cycle.\n");
> // Remove the now processed instructions from the skid buffer.
> skidBuffer.pop();
320,338c219,226
< // Clear the stall signal if rename was blocked or unblocking before.
< // If it still needs to block, the blocking should happen the next
< // cycle and there should be space to hold everything due to the squash.
< if (renameStatus[tid] == Blocked ||
< renameStatus[tid] == Unblocking ||
< renameStatus[tid] == SerializeStall) {
< #if 0
< // In syscall emulation, we can have both a block and a squash due
< // to a syscall in the same cycle. This would cause both signals to
< // be high. This shouldn't happen in full system.
< if (toDecode->renameBlock[tid]) {
< toDecode->renameBlock[tid] = 0;
< } else {
< toDecode->renameUnblock[tid] = 1;
< }
< #else
< toDecode->renameUnblock[tid] = 1;
< #endif
< serializeInst[tid] = NULL;
---
> // If there's still information in the skid buffer, then
> // continue to tell previous stages to stall. They will be
> // able to restart once the skid buffer is empty.
> if (!skidBuffer.empty()) {
> toDecode->renameInfo.stall = true;
> } else {
> DPRINTF(Rename, "Rename: Done unblocking.\n");
> _status = Running;
340,360d227
<
< // Set the status to Squashing.
< renameStatus[tid] = Squashing;
<
< // Squash any instructions from decode.
< unsigned squashCount = 0;
<
< for (int i=0; i<fromDecode->size; i++) {
< if (fromDecode->insts[i]->threadNumber == tid) {
< fromDecode->insts[i]->squashed = true;
< wroteToTimeBuffer = true;
< squashCount++;
< }
< }
<
< insts[tid].clear();
<
< // Clear the skid buffer in case it has any data in it.
< skidBuffer[tid].clear();
<
< doSquash(tid);
365c232
< DefaultRename<Impl>::tick()
---
> SimpleRename<Impl>::doSquash()
367c234
< wroteToTimeBuffer = false;
---
> typename list<RenameHistory>::iterator hb_it = historyBuffer.begin();
369c236
< blockThisCycle = false;
---
> InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum;
371,478c238,243
< bool status_change = false;
<
< toIEWIndex = 0;
<
< sortInsts();
<
< list<unsigned>::iterator threads = (*activeThreads).begin();
<
< // Check stall and squash signals.
< while (threads != (*activeThreads).end()) {
< unsigned tid = *threads++;
<
< DPRINTF(Rename, "Processing [tid:%i]\n", tid);
<
< status_change = checkSignalsAndUpdate(tid) || status_change;
<
< rename(status_change, tid);
< }
<
< if (status_change) {
< updateStatus();
< }
<
< if (wroteToTimeBuffer) {
< DPRINTF(Activity, "Activity this cycle.\n");
< cpu->activityThisCycle();
< }
<
< threads = (*activeThreads).begin();
<
< while (threads != (*activeThreads).end()) {
< unsigned tid = *threads++;
<
< // If we committed this cycle then doneSeqNum will be > 0
< if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
< !fromCommit->commitInfo[tid].squash &&
< renameStatus[tid] != Squashing) {
<
< removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,
< tid);
< }
< }
<
< // @todo: make into updateProgress function
< for (int tid=0; tid < numThreads; tid++) {
< instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
<
< assert(instsInProgress[tid] >=0);
< }
<
< }
<
< template<class Impl>
< void
< DefaultRename<Impl>::rename(bool &status_change, unsigned tid)
< {
< // If status is Running or idle,
< // call renameInsts()
< // If status is Unblocking,
< // buffer any instructions coming from decode
< // continue trying to empty skid buffer
< // check if stall conditions have passed
<
< if (renameStatus[tid] == Blocked) {
< ++renameBlockCycles;
< } else if (renameStatus[tid] == Squashing) {
< ++renameSquashCycles;
< } else if (renameStatus[tid] == SerializeStall) {
< ++renameSerializeStallCycles;
< }
<
< if (renameStatus[tid] == Running ||
< renameStatus[tid] == Idle) {
< DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run "
< "stage.\n", tid);
<
< renameInsts(tid);
< } else if (renameStatus[tid] == Unblocking) {
< renameInsts(tid);
<
< if (validInsts()) {
< // Add the current inputs to the skid buffer so they can be
< // reprocessed when this stage unblocks.
< skidInsert(tid);
< }
<
< // If we switched over to blocking, then there's a potential for
< // an overall status change.
< status_change = unblock(tid) || status_change || blockThisCycle;
< }
< }
<
< template <class Impl>
< void
< DefaultRename<Impl>::renameInsts(unsigned tid)
< {
< // Instructions can be either in the skid buffer or the queue of
< // instructions coming from decode, depending on the status.
< int insts_available = renameStatus[tid] == Unblocking ?
< skidBuffer[tid].size() : insts[tid].size();
<
< // Check the decode queue to see if instructions are available.
< // If there are no available instructions to rename, then do nothing.
< if (insts_available == 0) {
< DPRINTF(Rename, "[tid:%u]: Nothing to do, breaking out early.\n",
< tid);
< // Should I change status to idle?
< ++renameIdleCycles;
---
> #if FULL_SYSTEM
> assert(!historyBuffer.empty());
> #else
> // After a syscall squashes everything, the history buffer may be empty
> // but the ROB may still be squashing instructions.
> if (historyBuffer.empty()) {
480,483d244
< } else if (renameStatus[tid] == Unblocking) {
< ++renameUnblockCycles;
< } else if (renameStatus[tid] == Running) {
< ++renameRunCycles;
484a246
> #endif // FULL_SYSTEM
486c248,252
< DynInstPtr inst;
---
> // Go through the most recent instructions, undoing the mappings
> // they did and freeing up the registers.
> while ((*hb_it).instSeqNum > squashed_seq_num)
> {
> assert(hb_it != historyBuffer.end());
488,493c254,255
< // Will have to do a different calculation for the number of free
< // entries.
< int free_rob_entries = calcFreeROBEntries(tid);
< int free_iq_entries = calcFreeIQEntries(tid);
< int free_lsq_entries = calcFreeLSQEntries(tid);
< int min_free_entries = free_rob_entries;
---
> DPRINTF(Rename, "Rename: Removing history entry with sequence "
> "number %i.\n", (*hb_it).instSeqNum);
495c257,261
< FullSource source = ROB;
---
> // If it's not simply a place holder, then add the registers.
> if (!(*hb_it).placeHolder) {
> // Tell the rename map to set the architected register to the
> // previous physical register that it was renamed to.
> renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg);
497,500c263,264
< if (free_iq_entries < min_free_entries) {
< min_free_entries = free_iq_entries;
< source = IQ;
< }
---
> // Put the renamed physical register back on the free list.
> freeList->addReg(hb_it->newPhysReg);
502,555c266
< if (free_lsq_entries < min_free_entries) {
< min_free_entries = free_lsq_entries;
< source = LSQ;
< }
<
< // Check if there's any space left.
< if (min_free_entries <= 0) {
< DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/LSQ "
< "entries.\n"
< "ROB has %i free entries.\n"
< "IQ has %i free entries.\n"
< "LSQ has %i free entries.\n",
< tid,
< free_rob_entries,
< free_iq_entries,
< free_lsq_entries);
<
< blockThisCycle = true;
<
< block(tid);
<
< incrFullStat(source);
<
< return;
< } else if (min_free_entries < insts_available) {
< DPRINTF(Rename, "[tid:%u]: Will have to block this cycle."
< "%i insts available, but only %i insts can be "
< "renamed due to ROB/IQ/LSQ limits.\n",
< tid, insts_available, min_free_entries);
<
< insts_available = min_free_entries;
<
< blockThisCycle = true;
<
< incrFullStat(source);
< }
<
< InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ?
< skidBuffer[tid] : insts[tid];
<
< DPRINTF(Rename, "[tid:%u]: %i available instructions to "
< "send iew.\n", tid, insts_available);
<
< DPRINTF(Rename, "[tid:%u]: %i insts pipelining from Rename | %i insts "
< "dispatched to IQ last cycle.\n",
< tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched);
<
< // Handle serializing the next instruction if necessary.
< if (serializeOnNextInst[tid]) {
< if (emptyROB[tid] && instsInProgress[tid] == 0) {
< // ROB already empty; no need to serialize.
< serializeOnNextInst[tid] = false;
< } else if (!insts_to_rename.empty()) {
< insts_to_rename.front()->setSerializeBefore();
---
> ++renameValidUndoneMaps;
557d267
< }
559c269
< int renamed_insts = 0;
---
> historyBuffer.erase(hb_it++);
561,660c271
< while (insts_available > 0 && toIEWIndex < renameWidth) {
< DPRINTF(Rename, "[tid:%u]: Sending instructions to IEW.\n", tid);
<
< assert(!insts_to_rename.empty());
<
< inst = insts_to_rename.front();
<
< insts_to_rename.pop_front();
<
< if (renameStatus[tid] == Unblocking) {
< DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%#x from rename "
< "skidBuffer\n",
< tid, inst->seqNum, inst->readPC());
< }
<
< if (inst->isSquashed()) {
< DPRINTF(Rename, "[tid:%u]: instruction %i with PC %#x is "
< "squashed, skipping.\n",
< tid, inst->seqNum, inst->threadNumber,inst->readPC());
<
< ++renameSquashedInsts;
<
< // Decrement how many instructions are available.
< --insts_available;
<
< continue;
< }
<
< DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
< "PC %#x.\n",
< tid, inst->seqNum, inst->readPC());
<
< // Handle serializeAfter/serializeBefore instructions.
< // serializeAfter marks the next instruction as serializeBefore.
< // serializeBefore makes the instruction wait in rename until the ROB
< // is empty.
<
< // In this model, IPR accesses are serialize before
< // instructions, and store conditionals are serialize after
< // instructions. This is mainly due to lack of support for
< // out-of-order operations of either of those classes of
< // instructions.
< if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
< !inst->isSerializeHandled()) {
< DPRINTF(Rename, "Serialize before instruction encountered.\n");
<
< if (!inst->isTempSerializeBefore()) {
< renamedSerializing++;
< inst->setSerializeHandled();
< } else {
< renamedTempSerializing++;
< }
<
< // Change status over to SerializeStall so that other stages know
< // what this is blocked on.
< renameStatus[tid] = SerializeStall;
<
< serializeInst[tid] = inst;
<
< blockThisCycle = true;
<
< break;
< } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
< !inst->isSerializeHandled()) {
< DPRINTF(Rename, "Serialize after instruction encountered.\n");
<
< renamedSerializing++;
<
< inst->setSerializeHandled();
<
< serializeAfter(insts_to_rename, tid);
< }
<
< // Check here to make sure there are enough destination registers
< // to rename to. Otherwise block.
< if (renameMap[tid]->numFreeEntries() < inst->numDestRegs()) {
< DPRINTF(Rename, "Blocking due to lack of free "
< "physical registers to rename to.\n");
< blockThisCycle = true;
<
< ++renameFullRegistersEvents;
<
< break;
< }
<
< renameSrcRegs(inst, inst->threadNumber);
<
< renameDestRegs(inst, inst->threadNumber);
<
< ++renamed_insts;
<
< // Put instruction in rename queue.
< toIEW->insts[toIEWIndex] = inst;
< ++(toIEW->size);
<
< // Increment which instruction we're on.
< ++toIEWIndex;
<
< // Decrement how many instructions are available.
< --insts_available;
---
> ++renameUndoneMaps;
662,680d272
<
< instsInProgress[tid] += renamed_insts;
< renameRenamedInsts += renamed_insts;
<
< // If we wrote to the time buffer, record this.
< if (toIEWIndex) {
< wroteToTimeBuffer = true;
< }
<
< // Check if there's any instructions left that haven't yet been renamed.
< // If so then block.
< if (insts_available) {
< blockThisCycle = true;
< }
<
< if (blockThisCycle) {
< block(tid);
< toDecode->renameUnblock[tid] = false;
< }
683,707d274
< template<class Impl>
< void
< DefaultRename<Impl>::skidInsert(unsigned tid)
< {
< DynInstPtr inst = NULL;
<
< while (!insts[tid].empty()) {
< inst = insts[tid].front();
<
< insts[tid].pop_front();
<
< assert(tid == inst->threadNumber);
<
< DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC:%#x into Rename "
< "skidBuffer\n", tid, inst->seqNum, inst->readPC());
<
< ++renameSkidInsts;
<
< skidBuffer[tid].push_back(inst);
< }
<
< if (skidBuffer[tid].size() > skidBufferMax)
< panic("Skidbuffer Exceeded Max Size");
< }
<
710c277
< DefaultRename<Impl>::sortInsts()
---
> SimpleRename<Impl>::squash()
712,721c279,281
< int insts_from_decode = fromDecode->size;
< #ifdef DEBUG
< for (int i=0; i < numThreads; i++)
< assert(insts[i].empty());
< #endif
< for (int i = 0; i < insts_from_decode; ++i) {
< DynInstPtr inst = fromDecode->insts[i];
< insts[inst->threadNumber].push_back(inst);
< }
< }
---
> DPRINTF(Rename, "Rename: Squashing instructions.\n");
> // Set the status to Squashing.
> _status = Squashing;
723,727c283
< template<class Impl>
< bool
< DefaultRename<Impl>::skidsEmpty()
< {
< list<unsigned>::iterator threads = (*activeThreads).begin();
---
> numInst = 0;
729,731c285,288
< while (threads != (*activeThreads).end()) {
< if (!skidBuffer[*threads++].empty())
< return false;
---
> // Clear the skid buffer in case it has any data in it.
> while (!skidBuffer.empty())
> {
> skidBuffer.pop();
734c291
< return true;
---
> doSquash();
739c296
< DefaultRename<Impl>::updateStatus()
---
> SimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num)
741c298,300
< bool any_unblocking = false;
---
> DPRINTF(Rename, "Rename: Removing a committed instruction from the "
> "history buffer, until sequence number %lli.\n", inst_seq_num);
> typename list<RenameHistory>::iterator hb_it = historyBuffer.end();
743c302
< list<unsigned>::iterator threads = (*activeThreads).begin();
---
> --hb_it;
745,753c304,307
< threads = (*activeThreads).begin();
<
< while (threads != (*activeThreads).end()) {
< unsigned tid = *threads++;
<
< if (renameStatus[tid] == Unblocking) {
< any_unblocking = true;
< break;
< }
---
> if (hb_it->instSeqNum > inst_seq_num) {
> DPRINTF(Rename, "Rename: Old sequence number encountered. Ensure "
> "that a syscall happened recently.\n");
> return;
756,759c310,313
< // Rename will have activity if it's unblocking.
< if (any_unblocking) {
< if (_status == Inactive) {
< _status = Active;
---
> while ((*hb_it).instSeqNum != inst_seq_num)
> {
> // Make sure we haven't gone off the end of the list.
> assert(hb_it != historyBuffer.end());
761c315,324
< DPRINTF(Activity, "Activating stage.\n");
---
> // In theory instructions at the end of the history buffer
> // should be older than the instruction being removed, which
> // means they will have a lower sequence number. Also the
> // instruction being removed from the history really should
> // be the last instruction in the list, as it is the instruction
> // that was just committed that is being removed.
> assert(hb_it->instSeqNum < inst_seq_num);
> DPRINTF(Rename, "Rename: Freeing up older rename of reg %i, sequence"
> " number %i.\n",
> (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
763c326,328
< cpu->activateStage(FullCPU::RenameIdx);
---
> if (!(*hb_it).placeHolder) {
> freeList->addReg((*hb_it).prevPhysReg);
> ++renameCommittedMaps;
765,770d329
< } else {
< // If it's not unblocking, then rename will not have any internal
< // activity. Switch it to inactive.
< if (_status == Active) {
< _status = Inactive;
< DPRINTF(Activity, "Deactivating stage.\n");
772,773c331
< cpu->deactivateStage(FullCPU::RenameIdx);
< }
---
> historyBuffer.erase(hb_it--);
775d332
< }
777,802c334,338
< template <class Impl>
< bool
< DefaultRename<Impl>::block(unsigned tid)
< {
< DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid);
<
< // Add the current inputs onto the skid buffer, so they can be
< // reprocessed when this stage unblocks.
< skidInsert(tid);
<
< // Only signal backwards to block if the previous stages do not think
< // rename is already blocked.
< if (renameStatus[tid] != Blocked) {
< if (renameStatus[tid] != Unblocking) {
< toDecode->renameBlock[tid] = true;
< toDecode->renameUnblock[tid] = false;
< wroteToTimeBuffer = true;
< }
<
< // Rename can not go from SerializeStall to Blocked, otherwise
< // it would not know to complete the serialize stall.
< if (renameStatus[tid] != SerializeStall) {
< // Set status to Blocked.
< renameStatus[tid] = Blocked;
< return true;
< }
---
> // Finally free up the previous register of the finished instruction
> // itself.
> if (!(*hb_it).placeHolder) {
> freeList->addReg(hb_it->prevPhysReg);
> ++renameCommittedMaps;
805c341
< return false;
---
> historyBuffer.erase(hb_it);
809,905d344
< bool
< DefaultRename<Impl>::unblock(unsigned tid)
< {
< DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid);
<
< // Rename is done unblocking if the skid buffer is empty.
< if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
<
< DPRINTF(Rename, "[tid:%u]: Done unblocking.\n", tid);
<
< toDecode->renameUnblock[tid] = true;
< wroteToTimeBuffer = true;
<
< renameStatus[tid] = Running;
< return true;
< }
<
< return false;
< }
<
< template <class Impl>
< void
< DefaultRename<Impl>::doSquash(unsigned tid)
< {
< typename list<RenameHistory>::iterator hb_it = historyBuffer[tid].begin();
<
< InstSeqNum squashed_seq_num = fromCommit->commitInfo[tid].doneSeqNum;
<
< // After a syscall squashes everything, the history buffer may be empty
< // but the ROB may still be squashing instructions.
< if (historyBuffer[tid].empty()) {
< return;
< }
<
< // Go through the most recent instructions, undoing the mappings
< // they did and freeing up the registers.
< while (!historyBuffer[tid].empty() &&
< (*hb_it).instSeqNum > squashed_seq_num) {
< assert(hb_it != historyBuffer[tid].end());
<
< DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
< "number %i.\n", tid, (*hb_it).instSeqNum);
<
< // Tell the rename map to set the architected register to the
< // previous physical register that it was renamed to.
< renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
<
< // Put the renamed physical register back on the free list.
< freeList->addReg(hb_it->newPhysReg);
<
< historyBuffer[tid].erase(hb_it++);
<
< ++renameUndoneMaps;
< }
< }
<
< template<class Impl>
< void
< DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, unsigned tid)
< {
< DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the "
< "history buffer %u (size=%i), until [sn:%lli].\n",
< tid, tid, historyBuffer[tid].size(), inst_seq_num);
<
< typename list<RenameHistory>::iterator hb_it = historyBuffer[tid].end();
<
< --hb_it;
<
< if (historyBuffer[tid].empty()) {
< DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid);
< return;
< } else if (hb_it->instSeqNum > inst_seq_num) {
< DPRINTF(Rename, "[tid:%u]: Old sequence number encountered. Ensure "
< "that a syscall happened recently.\n", tid);
< return;
< }
<
< // Commit all the renames up until (and including) the committed sequence
< // number. Some or even all of the committed instructions may not have
< // rename histories if they did not have destination registers that were
< // renamed.
< while (!historyBuffer[tid].empty() &&
< hb_it != historyBuffer[tid].end() &&
< (*hb_it).instSeqNum <= inst_seq_num) {
<
< DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "
< "[sn:%lli].\n",
< tid, (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
<
< freeList->addReg((*hb_it).prevPhysReg);
< ++renameCommittedMaps;
<
< historyBuffer[tid].erase(hb_it--);
< }
< }
<
< template <class Impl>
907c346
< DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid)
---
> SimpleRename<Impl>::renameSrcRegs(DynInstPtr &inst)
909,910d347
< assert(renameMap[tid] != 0);
<
916c353,354
< for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
---
> for (int src_idx = 0; src_idx < num_src_regs; src_idx++)
> {
921c359
< PhysRegIndex renamed_reg = renameMap[tid]->lookup(src_reg);
---
> PhysRegIndex renamed_reg = renameMap->lookup(src_reg);
923,925c361,362
< DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got "
< "physical reg %i.\n", tid, (int)src_reg,
< (int)renamed_reg);
---
> DPRINTF(Rename, "Rename: Looking up arch reg %i, got "
> "physical reg %i.\n", (int)src_reg, (int)renamed_reg);
929,931c366,370
< // See if the register is ready or not.
< if (scoreboard->getReg(renamed_reg) == true) {
< DPRINTF(Rename, "[tid:%u]: Register is ready.\n", tid);
---
> // Either incorporate it into the info passed back,
> // or make another function call to see if that register is
> // ready or not.
> if (renameMap->isReady(renamed_reg)) {
> DPRINTF(Rename, "Rename: Register is ready.\n");
942c381
< DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst,unsigned tid)
---
> SimpleRename<Impl>::renameDestRegs(DynInstPtr &inst)
944c383
< typename RenameMap::RenameInfo rename_result;
---
> typename SimpleRenameMap::RenameInfo rename_result;
948,950c387,394
< // Rename the destination registers.
< for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
< RegIndex dest_reg = inst->destRegIdx(dest_idx);
---
> // If it's an instruction with no destination registers, then put
> // a placeholder within the history buffer. It might be better
> // to not put it in the history buffer at all (other than branches,
> // which always need at least a place holder), and differentiate
> // between instructions with and without destination registers
> // when getting from commit the instructions that committed.
> if (num_dest_regs == 0) {
> RenameHistory hb_entry(inst->seqNum);
952,954c396
< // Get the physical register that the destination will be
< // renamed to.
< rename_result = renameMap[tid]->rename(dest_reg);
---
> historyBuffer.push_front(hb_entry);
956,957c398,400
< //Mark Scoreboard entry as not ready
< scoreboard->unsetReg(rename_result.first);
---
> DPRINTF(Rename, "Rename: Adding placeholder instruction to "
> "history buffer, sequence number %lli.\n",
> inst->seqNum);
959,961c402,403
< DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
< "reg %i.\n", tid, (int)dest_reg,
< (int)rename_result.first);
---
> ++renameHBPlaceHolders;
> } else {
963,966c405,408
< // Record the rename information so that a history can be kept.
< RenameHistory hb_entry(inst->seqNum, dest_reg,
< rename_result.first,
< rename_result.second);
---
> // Rename the destination registers.
> for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++)
> {
> RegIndex dest_reg = inst->destRegIdx(dest_idx);
968c410,412
< historyBuffer[tid].push_front(hb_entry);
---
> // Get the physical register that the destination will be
> // renamed to.
> rename_result = renameMap->rename(dest_reg);
970,972c414,416
< DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer, "
< "[sn:%lli].\n",tid,
< (*historyBuffer[tid].begin()).instSeqNum);
---
> DPRINTF(Rename, "Rename: Renaming arch reg %i to physical "
> "reg %i.\n", (int)dest_reg,
> (int)rename_result.first);
974,981c418,421
< // Tell the instruction to rename the appropriate destination
< // register (dest_idx) to the new physical register
< // (rename_result.first), and record the previous physical
< // register that the same logical register was renamed to
< // (rename_result.second).
< inst->renameDestReg(dest_idx,
< rename_result.first,
< rename_result.second);
---
> // Record the rename information so that a history can be kept.
> RenameHistory hb_entry(inst->seqNum, dest_reg,
> rename_result.first,
> rename_result.second);
983c423,439
< ++renameRenamedOperands;
---
> historyBuffer.push_front(hb_entry);
>
> DPRINTF(Rename, "Rename: Adding instruction to history buffer, "
> "sequence number %lli.\n",
> (*historyBuffer.begin()).instSeqNum);
>
> // Tell the instruction to rename the appropriate destination
> // register (dest_idx) to the new physical register
> // (rename_result.first), and record the previous physical
> // register that the same logical register was renamed to
> // (rename_result.second).
> inst->renameDestReg(dest_idx,
> rename_result.first,
> rename_result.second);
>
> ++renameRenamedOperands;
> }
989c445
< DefaultRename<Impl>::calcFreeROBEntries(unsigned tid)
---
> SimpleRename<Impl>::calcFreeROBEntries()
991,996c447,448
< int num_free = freeEntries[tid].robEntries -
< (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
<
< //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free);
<
< return num_free;
---
> return fromCommit->commitInfo.freeROBEntries -
> renameWidth * iewToRenameDelay;
1001c453
< DefaultRename<Impl>::calcFreeIQEntries(unsigned tid)
---
> SimpleRename<Impl>::calcFreeIQEntries()
1003,1008c455
< int num_free = freeEntries[tid].iqEntries -
< (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
<
< //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free);
<
< return num_free;
---
> return fromIEW->iewInfo.freeIQEntries - renameWidth * iewToRenameDelay;
1011,1013c458,460
< template <class Impl>
< inline int
< DefaultRename<Impl>::calcFreeLSQEntries(unsigned tid)
---
> template<class Impl>
> void
> SimpleRename<Impl>::tick()
1015,1016c462,463
< int num_free = freeEntries[tid].lsqEntries -
< (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLSQ);
---
> // Rename will need to try to rename as many instructions as it
> // has bandwidth, unless it is blocked.
1018c465,467
< //DPRINTF(Rename,"[tid:%i]: %i lsq free\n",tid,num_free);
---
> // Check if _status is BarrierStall. If so, then check if the number
> // of free ROB entries is equal to the number of total ROB entries.
> // Once equal then wake this stage up. Set status to unblocking maybe.
1020,1021c469,474
< return num_free;
< }
---
> if (_status != Blocked && _status != Squashing) {
> DPRINTF(Rename, "Rename: Status is not blocked, will attempt to "
> "run stage.\n");
> // Make sure that the skid buffer has something in it if the
> // status is unblocking.
> assert(_status == Unblocking ? !skidBuffer.empty() : 1);
1023,1027c476
< template <class Impl>
< unsigned
< DefaultRename<Impl>::validInsts()
< {
< unsigned inst_count = 0;
---
> rename();
1029,1032c478,482
< for (int i=0; i<fromDecode->size; i++) {
< if (!fromDecode->insts[i]->squashed)
< inst_count++;
< }
---
> // If the status was unblocking, then instructions from the skid
> // buffer were used. Remove those instructions and handle
> // the rest of unblocking.
> if (_status == Unblocking) {
> ++renameUnblockCycles;
1034,1035c484,488
< return inst_count;
< }
---
> if (fromDecode->size > 0) {
> // Add the current inputs onto the skid buffer, so they can be
> // reprocessed when this stage unblocks.
> skidBuffer.push(*fromDecode);
> }
1037,1043c490,493
< template <class Impl>
< void
< DefaultRename<Impl>::readStallSignals(unsigned tid)
< {
< if (fromIEW->iewBlock[tid]) {
< stalls[tid].iew = true;
< }
---
> unblock();
> }
> } else if (_status == Blocked) {
> ++renameBlockCycles;
1045,1048c495,497
< if (fromIEW->iewUnblock[tid]) {
< assert(stalls[tid].iew);
< stalls[tid].iew = false;
< }
---
> // If stage is blocked and still receiving valid instructions,
> // make sure to store them in the skid buffer.
> if (fromDecode->size > 0) {
1050,1052c499
< if (fromCommit->commitBlock[tid]) {
< stalls[tid].commit = true;
< }
---
> block();
1054,1058c501,503
< if (fromCommit->commitUnblock[tid]) {
< assert(stalls[tid].commit);
< stalls[tid].commit = false;
< }
< }
---
> // Continue to tell previous stage to stall.
> toDecode->renameInfo.stall = true;
> }
1060,1064c505,509
< template <class Impl>
< bool
< DefaultRename<Impl>::checkStall(unsigned tid)
< {
< bool ret_val = false;
---
> if (!fromIEW->iewInfo.stall &&
> !fromCommit->commitInfo.stall &&
> calcFreeROBEntries() > 0 &&
> calcFreeIQEntries() > 0 &&
> renameMap->numFreeEntries() > 0) {
1066,1089c511,544
< if (stalls[tid].iew) {
< DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid);
< ret_val = true;
< } else if (stalls[tid].commit) {
< DPRINTF(Rename,"[tid:%i]: Stall from Commit stage detected.\n", tid);
< ret_val = true;
< } else if (calcFreeROBEntries(tid) <= 0) {
< DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid);
< ret_val = true;
< } else if (calcFreeIQEntries(tid) <= 0) {
< DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid);
< ret_val = true;
< } else if (calcFreeLSQEntries(tid) <= 0) {
< DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid);
< ret_val = true;
< } else if (renameMap[tid]->numFreeEntries() <= 0) {
< DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid);
< ret_val = true;
< } else if (renameStatus[tid] == SerializeStall &&
< (!emptyROB[tid] || instsInProgress[tid])) {
< DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not "
< "empty.\n",
< tid);
< ret_val = true;
---
> // Need to be sure to check all blocking conditions above.
> // If they have cleared, then start unblocking.
> DPRINTF(Rename, "Rename: Stall signals cleared, going to "
> "unblock.\n");
> _status = Unblocking;
>
> // Continue to tell previous stage to block until this stage
> // is done unblocking.
> toDecode->renameInfo.stall = true;
> } else {
> // Otherwise no conditions have changed. Tell previous
> // stage to continue blocking.
> toDecode->renameInfo.stall = true;
> }
>
> if (fromCommit->commitInfo.squash ||
> fromCommit->commitInfo.robSquashing) {
> squash();
> return;
> }
> } else if (_status == Squashing) {
> ++renameSquashCycles;
>
> if (fromCommit->commitInfo.squash) {
> squash();
> } else if (!fromCommit->commitInfo.squash &&
> !fromCommit->commitInfo.robSquashing) {
>
> DPRINTF(Rename, "Rename: Done squashing, going to running.\n");
> _status = Running;
> rename();
> } else {
> doSquash();
> }
1092c547,557
< return ret_val;
---
> // Ugly code, revamp all of the tick() functions eventually.
> if (fromCommit->commitInfo.doneSeqNum != 0 && _status != Squashing) {
> #if !FULL_SYSTEM
> if (!fromCommit->commitInfo.squash) {
> removeFromHistory(fromCommit->commitInfo.doneSeqNum);
> }
> #else
> removeFromHistory(fromCommit->commitInfo.doneSeqNum);
> #endif
> }
>
1095c560
< template <class Impl>
---
> template<class Impl>
1097c562
< DefaultRename<Impl>::readFreeEntries(unsigned tid)
---
> SimpleRename<Impl>::rename()
1099,1103c564,571
< bool updated = false;
< if (fromIEW->iewInfo[tid].usedIQ) {
< freeEntries[tid].iqEntries =
< fromIEW->iewInfo[tid].freeIQEntries;
< updated = true;
---
> // Check if any of the stages ahead of rename are telling rename
> // to squash. The squash() function will also take care of fixing up
> // the rename map and the free list.
> if (fromCommit->commitInfo.squash ||
> fromCommit->commitInfo.robSquashing) {
> DPRINTF(Rename, "Rename: Receiving signal from Commit to squash.\n");
> squash();
> return;
1106,1109c574,580
< if (fromIEW->iewInfo[tid].usedLSQ) {
< freeEntries[tid].lsqEntries =
< fromIEW->iewInfo[tid].freeLSQEntries;
< updated = true;
---
> // Check if time buffer is telling this stage to stall.
> if (fromIEW->iewInfo.stall ||
> fromCommit->commitInfo.stall) {
> DPRINTF(Rename, "Rename: Receiving signal from IEW/Commit to "
> "stall.\n");
> block();
> return;
1112,1116c583,588
< if (fromCommit->commitInfo[tid].usedROB) {
< freeEntries[tid].robEntries =
< fromCommit->commitInfo[tid].freeROBEntries;
< emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
< updated = true;
---
> // Check if the current status is squashing. If so, set its status
> // to running and resume execution the next cycle.
> if (_status == Squashing) {
> DPRINTF(Rename, "Rename: Done squashing.\n");
> _status = Running;
> return;
1119,1123c591,598
< DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, Free LSQ: %i\n",
< tid,
< freeEntries[tid].iqEntries,
< freeEntries[tid].robEntries,
< freeEntries[tid].lsqEntries);
---
> // Check the decode queue to see if instructions are available.
> // If there are no available instructions to rename, then do nothing.
> // Or, if the stage is currently unblocking, then go ahead and run it.
> if (fromDecode->size == 0 && _status != Unblocking) {
> DPRINTF(Rename, "Rename: Nothing to do, breaking out early.\n");
> // Should I change status to idle?
> return;
> }
1125,1127c600,602
< DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n",
< tid, instsInProgress[tid]);
< }
---
> ////////////////////////////////////
> // Actual rename part.
> ////////////////////////////////////
1129,1141c604
< template <class Impl>
< bool
< DefaultRename<Impl>::checkSignalsAndUpdate(unsigned tid)
< {
< // Check if there's a squash signal, squash if there is
< // Check stall signals, block if necessary.
< // If status was blocked
< // check if stall conditions have passed
< // if so then go to unblocking
< // If status was Squashing
< // check if squashing is not high. Switch to running this cycle.
< // If status was serialize stall
< // check if ROB is empty and no insts are in flight to the ROB
---
> DynInstPtr inst;
1143,1144c606,611
< readFreeEntries(tid);
< readStallSignals(tid);
---
> // If we're unblocking, then we may be in the middle of an instruction
> // group. Subtract off numInst to get the proper number of instructions
> // left.
> int insts_available = _status == Unblocking ?
> skidBuffer.front().size - numInst :
> fromDecode->size;
1146,1148c613
< if (fromCommit->commitInfo[tid].squash) {
< DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from "
< "commit.\n", tid);
---
> bool block_this_cycle = false;
1150c615,620
< squash(tid);
---
> // Will have to do a different calculation for the number of free
> // entries. Number of free entries recorded on this cycle -
> // renameWidth * renameToDecodeDelay
> int free_rob_entries = calcFreeROBEntries();
> int free_iq_entries = calcFreeIQEntries();
> int min_iq_rob = min(free_rob_entries, free_iq_entries);
1152,1153c622
< return true;
< }
---
> unsigned to_iew_index = 0;
1155,1156c624,634
< if (fromCommit->commitInfo[tid].robSquashing) {
< DPRINTF(Rename, "[tid:%u]: ROB is still squashing.\n", tid);
---
> // Check if there's any space left.
> if (min_iq_rob <= 0) {
> DPRINTF(Rename, "Rename: Blocking due to no free ROB or IQ "
> "entries.\n"
> "Rename: ROB has %d free entries.\n"
> "Rename: IQ has %d free entries.\n",
> free_rob_entries,
> free_iq_entries);
> block();
> // Tell previous stage to stall.
> toDecode->renameInfo.stall = true;
1158c636,640
< renameStatus[tid] = Squashing;
---
> if (free_rob_entries <= 0) {
> ++renameROBFullEvents;
> } else {
> ++renameIQFullEvents;
> }
1160,1161c642,646
< return true;
< }
---
> return;
> } else if (min_iq_rob < insts_available) {
> DPRINTF(Rename, "Rename: Will have to block this cycle. Only "
> "%i insts can be renamed due to IQ/ROB limits.\n",
> min_iq_rob);
1163,1165c648
< if (checkStall(tid)) {
< return block(tid);
< }
---
> insts_available = min_iq_rob;
1167,1169c650
< if (renameStatus[tid] == Blocked) {
< DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n",
< tid);
---
> block_this_cycle = true;
1171c652,657
< renameStatus[tid] = Unblocking;
---
> if (free_rob_entries < free_iq_entries) {
> ++renameROBFullEvents;
> } else {
> ++renameIQFullEvents;
> }
> }
1173c659,660
< unblock(tid);
---
> while (insts_available > 0) {
> DPRINTF(Rename, "Rename: Sending instructions to iew.\n");
1175,1176c662,665
< return true;
< }
---
> // Get the next instruction either from the skid buffer or the
> // decode queue.
> inst = _status == Unblocking ? skidBuffer.front().insts[numInst] :
> fromDecode->insts[numInst];
1178,1182c667,670
< if (renameStatus[tid] == Squashing) {
< // Switch status to running if rename isn't being told to block or
< // squash this cycle.
< DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n",
< tid);
---
> if (inst->isSquashed()) {
> DPRINTF(Rename, "Rename: instruction %i with PC %#x is "
> "squashed, skipping.\n",
> inst->seqNum, inst->readPC());
1184c672,673
< renameStatus[tid] = Running;
---
> // Go to the next instruction.
> ++numInst;
1186,1187c675
< return false;
< }
---
> ++renameSquashedInsts;
1189,1192c677,678
< if (renameStatus[tid] == SerializeStall) {
< // Stall ends once the ROB is free.
< DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to "
< "unblocking.\n", tid);
---
> // Decrement how many instructions are available.
> --insts_available;
1194c680,681
< DynInstPtr serial_inst = serializeInst[tid];
---
> continue;
> }
1196c683,684
< renameStatus[tid] = Unblocking;
---
> DPRINTF(Rename, "Rename: Processing instruction %i with PC %#x.\n",
> inst->seqNum, inst->readPC());
1198c686,696
< unblock(tid);
---
> // If it's a trap instruction, then it needs to wait here within
> // rename until the ROB is empty. Needs a way to detect that the
> // ROB is empty. Maybe an event?
> // Would be nice if it could be avoided putting this into a
> // specific stage and instead just put it into the AlphaFullCPU.
> // Might not really be feasible though...
> // (EXCB, TRAPB)
> if (inst->isSerializing()) {
> panic("Rename: Serializing instruction encountered.\n");
> DPRINTF(Rename, "Rename: Serializing instruction "
> "encountered.\n");
1200,1202c698,700
< DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with "
< "PC %#x.\n",
< tid, serial_inst->seqNum, serial_inst->readPC());
---
> // Change status over to BarrierStall so that other stages know
> // what this is blocked on.
> _status = BarrierStall;
1204,1205c702
< // Put instruction into queue here.
< serial_inst->clearSerializeBefore();
---
> block_this_cycle = true;
1207,1210c704
< if (!skidBuffer[tid].empty()) {
< skidBuffer[tid].push_front(serial_inst);
< } else {
< insts[tid].push_front(serial_inst);
---
> break;
1213,1214c707,713
< DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename."
< " Adding to front of list.", tid);
---
> // Check here to make sure there are enough destination registers
> // to rename to. Otherwise block.
> if (renameMap->numFreeEntries() < inst->numDestRegs())
> {
> DPRINTF(Rename, "Rename: Blocking due to lack of free "
> "physical registers to rename to.\n");
> // Need some sort of event based on a register being freed.
1216c715
< serializeInst[tid] = NULL;
---
> block_this_cycle = true;
1218,1219c717
< return true;
< }
---
> ++renameFullRegistersEvents;
1221,1224c719,720
< // If we've reached this point, we have not gotten any signals that
< // cause rename to change its status. Rename remains the same as before.
< return false;
< }
---
> break;
> }
1226,1235c722
< template<class Impl>
< void
< DefaultRename<Impl>::serializeAfter(InstQueue &inst_list,
< unsigned tid)
< {
< if (inst_list.empty()) {
< // Mark a bit to say that I must serialize on the next instruction.
< serializeOnNextInst[tid] = true;
< return;
< }
---
> renameSrcRegs(inst);
1237,1239c724
< // Set the next instruction as serializing.
< inst_list.front()->setSerializeBefore();
< }
---
> renameDestRegs(inst);
1241,1259c726,728
< template <class Impl>
< inline void
< DefaultRename<Impl>::incrFullStat(const FullSource &source)
< {
< switch (source) {
< case ROB:
< ++renameROBFullEvents;
< break;
< case IQ:
< ++renameIQFullEvents;
< break;
< case LSQ:
< ++renameLSQFullEvents;
< break;
< default:
< panic("Rename full stall stat should be incremented for a reason!");
< break;
< }
< }
---
> // Put instruction in rename queue.
> toIEW->insts[to_iew_index] = inst;
> ++(toIEW->size);
1261,1265c730,732
< template <class Impl>
< void
< DefaultRename<Impl>::dumpHistory()
< {
< typename list<RenameHistory>::iterator buf_it;
---
> // Decrease the number of free ROB and IQ entries.
> --free_rob_entries;
> --free_iq_entries;
1267c734,736
< for (int i = 0; i < numThreads; i++) {
---
> // Increment which instruction we're on.
> ++to_iew_index;
> ++numInst;
1269c738
< buf_it = historyBuffer[i].begin();
---
> ++renameRenamedInsts;
1271,1274c740,742
< while (buf_it != historyBuffer[i].end()) {
< cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
< "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
< (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
---
> // Decrement how many instructions are available.
> --insts_available;
> }
1276,1277c744,754
< buf_it++;
< }
---
> // Check if there's any instructions left that haven't yet been renamed.
> // If so then block.
> if (block_this_cycle) {
> block();
>
> toDecode->renameInfo.stall = true;
> } else {
> // If we had a successful rename and didn't have to exit early, then
> // reset numInst so it will refer to the correct instruction on next
> // run.
> numInst = 0;