free_list.hh revision 1684
12810SN/A#ifndef __CPU_BETA_CPU_FREE_LIST_HH__
22810SN/A#define __CPU_BETA_CPU_FREE_LIST_HH__
32810SN/A
42810SN/A#include <iostream>
52810SN/A#include <queue>
62810SN/A
72810SN/A#include "arch/alpha/isa_traits.hh"
82810SN/A#include "base/trace.hh"
92810SN/A#include "base/traceflags.hh"
102810SN/A#include "cpu/beta_cpu/comm.hh"
112810SN/A
122810SN/A/**
132810SN/A * FreeList class that simply holds the list of free integer and floating
142810SN/A * point registers.  Can request for a free register of either type, and
152810SN/A * also send back free registers of either type.  This is a very simple
162810SN/A * class, but it should be sufficient for most implementations.  Like all
172810SN/A * other classes, it assumes that the indices for the floating point
182810SN/A * registers starts after the integer registers end.  Hence the variable
192810SN/A * numPhysicalIntRegs is logically equivalent to the baseFP dependency.
202810SN/A * Note that
212810SN/A * while this most likely should be called FreeList, the name "FreeList"
222810SN/A * is used in a typedef within the CPU Policy, and therefore no class
232810SN/A * can be named simply "FreeList".
242810SN/A * @todo: Give a better name to the base FP dependency.
252810SN/A */
262810SN/Aclass SimpleFreeList
272810SN/A{
282810SN/A  private:
292810SN/A    /** The list of free integer registers. */
302810SN/A    std::queue<PhysRegIndex> freeIntRegs;
312810SN/A
322810SN/A    /** The list of free floating point registers. */
332810SN/A    std::queue<PhysRegIndex> freeFloatRegs;
342810SN/A
352810SN/A    /** Number of logical integer registers. */
362810SN/A    int numLogicalIntRegs;
372810SN/A
382810SN/A    /** Number of physical integer registers. */
394626SN/A    int numPhysicalIntRegs;
404626SN/A
415314SN/A    /** Number of logical floating point registers. */
422810SN/A    int numLogicalFloatRegs;
432810SN/A
444626SN/A    /** Number of physical floating point registers. */
454626SN/A    int numPhysicalFloatRegs;
462810SN/A
472810SN/A    /** Total number of physical registers. */
482810SN/A    int numPhysicalRegs;
493374SN/A
502810SN/A    /** DEBUG stuff below. */
515314SN/A    std::vector<int> freeIntRegsScoreboard;
524626SN/A
534626SN/A    std::vector<bool> freeFloatRegsScoreboard;
542810SN/A
554626SN/A  public:
564626SN/A    SimpleFreeList(unsigned _numLogicalIntRegs,
574626SN/A                   unsigned _numPhysicalIntRegs,
585875Ssteve.reinhardt@amd.com                   unsigned _numLogicalFloatRegs,
595875Ssteve.reinhardt@amd.com                   unsigned _numPhysicalFloatRegs);
605875Ssteve.reinhardt@amd.com
615875Ssteve.reinhardt@amd.com    inline PhysRegIndex getIntReg();
625875Ssteve.reinhardt@amd.com
635875Ssteve.reinhardt@amd.com    inline PhysRegIndex getFloatReg();
645875Ssteve.reinhardt@amd.com
654871SN/A    inline void addReg(PhysRegIndex freed_reg);
664871SN/A
674666SN/A    inline void addIntReg(PhysRegIndex freed_reg);
684626SN/A
695875Ssteve.reinhardt@amd.com    inline void addFloatReg(PhysRegIndex freed_reg);
705318SN/A
715318SN/A    bool hasFreeIntRegs()
724626SN/A    { return !freeIntRegs.empty(); }
735318SN/A
745875Ssteve.reinhardt@amd.com    bool hasFreeFloatRegs()
754871SN/A    { return !freeFloatRegs.empty(); }
765875Ssteve.reinhardt@amd.com
774626SN/A    int numFreeIntRegs()
784626SN/A    { return freeIntRegs.size(); }
794626SN/A
804903SN/A    int numFreeFloatRegs()
814903SN/A    { return freeFloatRegs.size(); }
824903SN/A};
835314SN/A
844903SN/Ainline PhysRegIndex
854903SN/ASimpleFreeList::getIntReg()
864903SN/A{
874903SN/A    DPRINTF(Rename, "FreeList: Trying to get free integer register.\n");
884903SN/A    if (freeIntRegs.empty()) {
894903SN/A        panic("No free integer registers!");
904903SN/A    }
914903SN/A
925318SN/A    PhysRegIndex free_reg = freeIntRegs.front();
935875Ssteve.reinhardt@amd.com
944903SN/A    freeIntRegs.pop();
954908SN/A
964920SN/A    // DEBUG
975314SN/A    assert(freeIntRegsScoreboard[free_reg]);
985314SN/A    freeIntRegsScoreboard[free_reg] = 0;
994903SN/A
1004903SN/A    return(free_reg);
1012810SN/A}
1022810SN/A
1032810SN/Ainline PhysRegIndex
1042810SN/ASimpleFreeList::getFloatReg()
1052810SN/A{
1062810SN/A    DPRINTF(Rename, "FreeList: Trying to get free float register.\n");
1072810SN/A    if (freeFloatRegs.empty()) {
1084626SN/A        panic("No free integer registers!");
1094626SN/A    }
1104626SN/A
1114666SN/A    PhysRegIndex free_reg = freeFloatRegs.front();
1124871SN/A
1134666SN/A    freeFloatRegs.pop();
1144666SN/A
1154666SN/A    // DEBUG
1164666SN/A    assert(freeFloatRegsScoreboard[free_reg]);
1174626SN/A    freeFloatRegsScoreboard[free_reg] = 0;
1182810SN/A
1194626SN/A    return(free_reg);
1204626SN/A}
1214626SN/A
1224626SN/Ainline void
1233374SN/ASimpleFreeList::addReg(PhysRegIndex freed_reg)
1242810SN/A{
1254626SN/A    DPRINTF(Rename, "Freelist: Freeing register %i.\n", freed_reg);
1265730SSteve.Reinhardt@amd.com    //Might want to add in a check for whether or not this register is
1275730SSteve.Reinhardt@amd.com    //already in there.  A bit vector or something similar would be useful.
1284903SN/A    if (freed_reg < numPhysicalIntRegs) {
1294626SN/A        freeIntRegs.push(freed_reg);
1305314SN/A
1314665SN/A        // DEBUG
1324626SN/A        assert(freeIntRegsScoreboard[freed_reg] == false);
1334626SN/A        freeIntRegsScoreboard[freed_reg] = 1;
1344626SN/A    } else if (freed_reg < numPhysicalRegs) {
1354908SN/A        freeFloatRegs.push(freed_reg);
1364908SN/A
1374665SN/A        // DEBUG
1384670SN/A        assert(freeFloatRegsScoreboard[freed_reg] == false);
1394665SN/A        freeFloatRegsScoreboard[freed_reg] = 1;
1402810SN/A    }
1414626SN/A}
1422810SN/A
1432810SN/Ainline void
1442810SN/ASimpleFreeList::addIntReg(PhysRegIndex freed_reg)
1454668SN/A{
1464668SN/A    DPRINTF(Rename, "Freelist: Freeing int register %i.\n", freed_reg);
1474668SN/A
1484668SN/A    // DEBUG
1494668SN/A    assert(!freeIntRegsScoreboard[freed_reg]);
1502810SN/A    freeIntRegsScoreboard[freed_reg] = 1;
1512810SN/A
1522810SN/A    freeIntRegs.push(freed_reg);
1532810SN/A}
1542810SN/A
1554626SN/Ainline void
1562810SN/ASimpleFreeList::addFloatReg(PhysRegIndex freed_reg)
1572810SN/A{
1582810SN/A    DPRINTF(Rename, "Freelist: Freeing float register %i.\n", freed_reg);
1592810SN/A
1602810SN/A    // DEBUG
1612810SN/A    assert(!freeFloatRegsScoreboard[freed_reg]);
1622810SN/A    freeFloatRegsScoreboard[freed_reg] = 1;
1633374SN/A
1644903SN/A    freeFloatRegs.push(freed_reg);
1652810SN/A}
1664903SN/A
1674665SN/A#endif // __CPU_BETA_CPU_FREE_LIST_HH__
1682810SN/A