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 &params)
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