cpu.cc revision 2455
12SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu#include "config/full_system.hh"
302665Ssaidi@eecs.umich.edu
312SN/A#if FULL_SYSTEM
322SN/A#include "sim/system.hh"
332623SN/A#else
342623SN/A#include "sim/process.hh"
352SN/A#endif
364182Sgblack@eecs.umich.edu#include "sim/root.hh"
371354SN/A
381858SN/A#include "cpu/cpu_exec_context.hh"
391717SN/A#include "cpu/exec_context.hh"
402683Sktlim@umich.edu#include "cpu/o3/alpha_dyn_inst.hh"
411354SN/A#include "cpu/o3/alpha_impl.hh"
421354SN/A#include "cpu/o3/cpu.hh"
432387SN/A
442387SN/Ausing namespace std;
452387SN/A
4656SN/ABaseFullCPU::BaseFullCPU(Params &params)
475348Ssaidi@eecs.umich.edu    : BaseCPU(&params), cpu_id(0)
482SN/A{
492SN/A}
501858SN/A
512SN/Atemplate <class Impl>
523453Sgblack@eecs.umich.eduFullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
533453Sgblack@eecs.umich.edu    : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
543453Sgblack@eecs.umich.edu{
553453Sgblack@eecs.umich.edu}
563453Sgblack@eecs.umich.edu
572462SN/Atemplate <class Impl>
582SN/Avoid
59715SN/AFullO3CPU<Impl>::TickEvent::process()
60715SN/A{
61715SN/A    cpu->tick();
62715SN/A}
632SN/A
642SN/Atemplate <class Impl>
653960Sgblack@eecs.umich.educonst char *
663960Sgblack@eecs.umich.eduFullO3CPU<Impl>::TickEvent::description()
673960Sgblack@eecs.umich.edu{
684182Sgblack@eecs.umich.edu    return "FullO3CPU tick event";
694182Sgblack@eecs.umich.edu}
704182Sgblack@eecs.umich.edu
714182Sgblack@eecs.umich.edu//Call constructor to all the pipeline stages here
722680Sktlim@umich.edutemplate <class Impl>
73237SN/AFullO3CPU<Impl>::FullO3CPU(Params &params)
742SN/A#if FULL_SYSTEM
752SN/A    : BaseFullCPU(params),
762SN/A#else
772SN/A    : BaseFullCPU(params),
782SN/A#endif // FULL_SYSTEM
795529Snate@binkert.org      tickEvent(this),
805529Snate@binkert.org      fetch(params),
812420SN/A      decode(params),
822623SN/A      rename(params),
832SN/A      iew(params),
842107SN/A      commit(params),
852159SN/A
862455SN/A      regFile(params.numPhysIntRegs, params.numPhysFloatRegs),
872455SN/A
882386SN/A      freeList(TheISA::NumIntRegs, params.numPhysIntRegs,
892623SN/A               TheISA::NumFloatRegs, params.numPhysFloatRegs),
902SN/A
911371SN/A      renameMap(TheISA::NumIntRegs, params.numPhysIntRegs,
925348Ssaidi@eecs.umich.edu                TheISA::NumFloatRegs, params.numPhysFloatRegs,
935348Ssaidi@eecs.umich.edu                TheISA::NumMiscRegs,
945348Ssaidi@eecs.umich.edu                TheISA::ZeroReg,
955348Ssaidi@eecs.umich.edu                TheISA::ZeroReg + TheISA::NumIntRegs),
965348Ssaidi@eecs.umich.edu
975348Ssaidi@eecs.umich.edu      rob(params.numROBEntries, params.squashWidth),
985348Ssaidi@eecs.umich.edu
995348Ssaidi@eecs.umich.edu      // What to pass to these time buffers?
1002SN/A      // For now just have these time buffers be pretty big.
1012SN/A      timeBuffer(5, 5),
1022SN/A      fetchQueue(5, 5),
1032SN/A      decodeQueue(5, 5),
1042SN/A      renameQueue(5, 5),
1052SN/A      iewQueue(5, 5),
1062SN/A
1072SN/A      cpuXC(NULL),
1082SN/A
1092SN/A      globalSeqNum(1),
1102SN/A
1111400SN/A#if FULL_SYSTEM
1125529Snate@binkert.org      system(params.system),
1132623SN/A      memCtrl(system->memctrl),
1142SN/A      physmem(system->physmem),
1151400SN/A      itb(params.itb),
1162683Sktlim@umich.edu      dtb(params.dtb),
1172683Sktlim@umich.edu      mem(params.mem),
1182190SN/A#else
1192683Sktlim@umich.edu      // Hardcoded for a single thread!!
1202683Sktlim@umich.edu      mem(params.workload[0]->getMemory()),
1212683Sktlim@umich.edu#endif // FULL_SYSTEM
1222680Sktlim@umich.edu
1235169Ssaidi@eecs.umich.edu      icacheInterface(params.icacheInterface),
1245169Ssaidi@eecs.umich.edu      dcacheInterface(params.dcacheInterface),
1255169Ssaidi@eecs.umich.edu      deferRegistration(params.defReg),
1265496Ssaidi@eecs.umich.edu      numInsts(0),
1275496Ssaidi@eecs.umich.edu      funcExeInst(0)
1285496Ssaidi@eecs.umich.edu{
1295496Ssaidi@eecs.umich.edu    _status = Idle;
1305496Ssaidi@eecs.umich.edu
1315496Ssaidi@eecs.umich.edu#if !FULL_SYSTEM
1325496Ssaidi@eecs.umich.edu    thread.resize(this->number_of_threads);
1335496Ssaidi@eecs.umich.edu#endif
1345496Ssaidi@eecs.umich.edu
1355496Ssaidi@eecs.umich.edu    for (int i = 0; i < this->number_of_threads; ++i) {
1365496Ssaidi@eecs.umich.edu#if FULL_SYSTEM
1375496Ssaidi@eecs.umich.edu        assert(i == 0);
1385496Ssaidi@eecs.umich.edu        thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem);
1395496Ssaidi@eecs.umich.edu        system->execContexts[i] = thread[i]->getProxy();
1405169Ssaidi@eecs.umich.edu
1412SN/A        execContexts.push_back(system->execContexts[i]);
1421858SN/A#else
1432SN/A        if (i < params.workload.size()) {
1442SN/A            DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, "
1452SN/A                    "process is %#x",
1462SN/A                    i, params.workload[i]->prog_entry, thread[i]);
1472SN/A            thread[i] = new CPUExecContext(this, i, params.workload[i], i);
1482SN/A        }
1494181Sgblack@eecs.umich.edu        assert(params.workload[i]->getMemory() != NULL);
1504181Sgblack@eecs.umich.edu        assert(mem != NULL);
1514182Sgblack@eecs.umich.edu        execContexts.push_back(thread[i]->getProxy());
1524182Sgblack@eecs.umich.edu#endif // !FULL_SYSTEM
1532SN/A    }
1542107SN/A
1553276Sgblack@eecs.umich.edu    // Note that this is a hack so that my code which still uses xc-> will
1561469SN/A    // still work.  I should remove this eventually
1574377Sgblack@eecs.umich.edu    cpuXC = thread[0];
1584377Sgblack@eecs.umich.edu
1594377Sgblack@eecs.umich.edu    // The stages also need their CPU pointer setup.  However this must be
1604377Sgblack@eecs.umich.edu    // done at the upper level CPU because they have pointers to the upper
1614377Sgblack@eecs.umich.edu    // level CPU, and not this FullO3CPU.
1624377Sgblack@eecs.umich.edu
1632623SN/A    // Give each of the stages the time buffer they will use.
1642662Sstever@eecs.umich.edu    fetch.setTimeBuffer(&timeBuffer);
1652623SN/A    decode.setTimeBuffer(&timeBuffer);
1662623SN/A    rename.setTimeBuffer(&timeBuffer);
1672623SN/A    iew.setTimeBuffer(&timeBuffer);
168180SN/A    commit.setTimeBuffer(&timeBuffer);
169393SN/A
170393SN/A    // Also setup each of the stages' queues.
1712SN/A    fetch.setFetchQueue(&fetchQueue);
1722SN/A    decode.setFetchQueue(&fetchQueue);
173334SN/A    decode.setDecodeQueue(&decodeQueue);
174334SN/A    rename.setDecodeQueue(&decodeQueue);
1752SN/A    rename.setRenameQueue(&renameQueue);
1762SN/A    iew.setRenameQueue(&renameQueue);
1772SN/A    iew.setIEWQueue(&iewQueue);
178334SN/A    commit.setIEWQueue(&iewQueue);
179729SN/A    commit.setRenameQueue(&renameQueue);
180707SN/A
1814998Sgblack@eecs.umich.edu    // Setup the rename map for whichever stages need it.
1824998Sgblack@eecs.umich.edu    rename.setRenameMap(&renameMap);
1834998Sgblack@eecs.umich.edu    iew.setRenameMap(&renameMap);
1844998Sgblack@eecs.umich.edu
1854998Sgblack@eecs.umich.edu    // Setup the free list for whichever stages need it.
1864998Sgblack@eecs.umich.edu    rename.setFreeList(&freeList);
1874998Sgblack@eecs.umich.edu    renameMap.setFreeList(&freeList);
1884998Sgblack@eecs.umich.edu
189707SN/A    // Setup the ROB for whichever stages need it.
190707SN/A    commit.setROB(&rob);
191707SN/A}
192707SN/A
1932SN/Atemplate <class Impl>
1944564Sgblack@eecs.umich.eduFullO3CPU<Impl>::~FullO3CPU()
1954564Sgblack@eecs.umich.edu{
1964564Sgblack@eecs.umich.edu}
1972SN/A
198729SN/Atemplate <class Impl>
1992SN/Avoid
200124SN/AFullO3CPU<Impl>::fullCPURegStats()
201124SN/A{
202334SN/A    // Register any of the FullCPU's stats here.
203124SN/A}
2042SN/A
205729SN/Atemplate <class Impl>
206729SN/Avoid
2072SN/AFullO3CPU<Impl>::tick()
2082390SN/A{
209729SN/A    DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n");
2102SN/A
2112SN/A    //Tick each of the stages if they're actually running.
2122390SN/A    //Will want to figure out a way to unschedule itself if they're all
2132390SN/A    //going to be idle for a long time.
2142390SN/A    fetch.tick();
2152390SN/A
2162390SN/A    decode.tick();
217729SN/A
2182SN/A    rename.tick();
2192SN/A
2202390SN/A    iew.tick();
2212390SN/A
2222390SN/A    commit.tick();
2232390SN/A
224217SN/A    // Now advance the time buffers, unless the stage is stalled.
225237SN/A    timeBuffer.advance();
2262SN/A
2271371SN/A    fetchQueue.advance();
2281371SN/A    decodeQueue.advance();
2292623SN/A    renameQueue.advance();
2305543Ssaidi@eecs.umich.edu    iewQueue.advance();
2313918Ssaidi@eecs.umich.edu
2321371SN/A    if (_status == Running && !tickEvent.scheduled())
233581SN/A        tickEvent.schedule(curTick + 1);
2342SN/A}
2352SN/A
2362SN/Atemplate <class Impl>
2372SN/Avoid
238753SN/AFullO3CPU<Impl>::init()
2392SN/A{
2402SN/A    if(!deferRegistration)
2412SN/A    {
242594SN/A        this->registerExecContexts();
2434661Sksewell@umich.edu
244595SN/A        // Need to do a copy of the xc->regs into the CPU's regfile so
245594SN/A        // that it can start properly.
246595SN/A#if FULL_SYSTEM
247705SN/A        ExecContext *src_xc = system->execContexts[0];
248726SN/A        TheISA::initCPU(src_xc, src_xc->readCpuId());
249726SN/A#else
250726SN/A        ExecContext *src_xc = thread[0]->getProxy();
251726SN/A#endif
252726SN/A        // First loop through the integer registers.
253726SN/A        for (int i = 0; i < TheISA::NumIntRegs; ++i)
254726SN/A        {
255726SN/A            regFile.intRegFile[i] = src_xc->readIntReg(i);
256726SN/A        }
257726SN/A
258705SN/A        // Then loop through the floating point registers.
2593735Sstever@eecs.umich.edu        for (int i = 0; i < TheISA::NumFloatRegs; ++i)
260726SN/A        {
2612683Sktlim@umich.edu            regFile.floatRegFile.setRegBits(i, src_xc->readRegBits(i))
262726SN/A        }
263705SN/A/*
2643735Sstever@eecs.umich.edu        // Then loop through the misc registers.
265726SN/A        regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr;
266726SN/A        regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq;
2672683Sktlim@umich.edu        regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag;
268726SN/A        regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr;
269705SN/A*/
2703735Sstever@eecs.umich.edu        // Then finally set the PC and the next PC.
271726SN/A        regFile.pc = src_xc->readPC();
272726SN/A        regFile.npc = src_xc->readNextPC();
2732683Sktlim@umich.edu    }
274726SN/A}
275705SN/A
2763735Sstever@eecs.umich.edutemplate <class Impl>
2773735Sstever@eecs.umich.eduvoid
278726SN/AFullO3CPU<Impl>::activateContext(int thread_num, int delay)
279726SN/A{
2802683Sktlim@umich.edu    // Needs to set each stage to running as well.
2812455SN/A
2822455SN/A    scheduleTickEvent(delay);
2833735Sstever@eecs.umich.edu
2842455SN/A    _status = Running;
2852455SN/A}
2862683Sktlim@umich.edu
287726SN/Atemplate <class Impl>
288705SN/Avoid
2893735Sstever@eecs.umich.eduFullO3CPU<Impl>::suspendContext(int thread_num)
290726SN/A{
2912683Sktlim@umich.edu    panic("suspendContext unimplemented!");
292726SN/A}
293705SN/A
2943735Sstever@eecs.umich.edutemplate <class Impl>
2953735Sstever@eecs.umich.eduvoid
296726SN/AFullO3CPU<Impl>::deallocateContext(int thread_num)
297726SN/A{
2982683Sktlim@umich.edu    panic("deallocateContext unimplemented!");
299726SN/A}
300705SN/A
3013735Sstever@eecs.umich.edutemplate <class Impl>
302726SN/Avoid
303726SN/AFullO3CPU<Impl>::haltContext(int thread_num)
3042683Sktlim@umich.edu{
305726SN/A    panic("haltContext unimplemented!");
306726SN/A}
3073735Sstever@eecs.umich.edu
3083735Sstever@eecs.umich.edutemplate <class Impl>
309726SN/Avoid
310726SN/AFullO3CPU<Impl>::switchOut()
3112683Sktlim@umich.edu{
3122455SN/A    panic("FullO3CPU does not have a switch out function.\n");
3132455SN/A}
3143735Sstever@eecs.umich.edu
3153735Sstever@eecs.umich.edutemplate <class Impl>
3162455SN/Avoid
3172455SN/AFullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
3182683Sktlim@umich.edu{
319726SN/A    BaseCPU::takeOverFrom(oldCPU);
320705SN/A
3212683Sktlim@umich.edu    assert(!tickEvent.scheduled());
3224950Sgblack@eecs.umich.edu
3232683Sktlim@umich.edu    // Set all status's to active, schedule the
3244950Sgblack@eecs.umich.edu    // CPU's tick event.
3252683Sktlim@umich.edu    for (int i = 0; i < execContexts.size(); ++i) {
3262447SN/A        ExecContext *xc = execContexts[i];
3272683Sktlim@umich.edu        if (xc->status() == ExecContext::Active && _status != Running) {
3284950Sgblack@eecs.umich.edu            _status = Running;
3292683Sktlim@umich.edu            tickEvent.schedule(curTick);
3304950Sgblack@eecs.umich.edu        }
3312683Sktlim@umich.edu    }
332705SN/A}
3334172Ssaidi@eecs.umich.edu
3344172Ssaidi@eecs.umich.edutemplate <class Impl>
3354172Ssaidi@eecs.umich.eduInstSeqNum
3364172Ssaidi@eecs.umich.eduFullO3CPU<Impl>::getAndIncrementInstSeq()
3374172Ssaidi@eecs.umich.edu{
3382159SN/A    // Hopefully this works right.
3392159SN/A    return globalSeqNum++;
3402683Sktlim@umich.edu}
3412159SN/A
342705SN/Atemplate <class Impl>
3434172Ssaidi@eecs.umich.eduuint64_t
3442159SN/AFullO3CPU<Impl>::readIntReg(int reg_idx)
3454172Ssaidi@eecs.umich.edu{
3462159SN/A    return regFile.readIntReg(reg_idx);
3472159SN/A}
3483468Sgblack@eecs.umich.edu
3492159SN/Atemplate <class Impl>
3502683Sktlim@umich.eduFloatReg
3512159SN/AFullO3CPU<Impl>::readFloatReg(int reg_idx, int width)
3522159SN/A{
3534185Ssaidi@eecs.umich.edu    return regFile.readFloatReg(reg_idx, width);
3542159SN/A}
3554172Ssaidi@eecs.umich.edu
3564172Ssaidi@eecs.umich.edutemplate <class Impl>
3572159SN/AFloatReg
358705SN/AFullO3CPU<Impl>::readFloatReg(int reg_idx)
3594185Ssaidi@eecs.umich.edu{
3603792Sgblack@eecs.umich.edu    return regFile.readFloatReg(reg_idx);
3613792Sgblack@eecs.umich.edu}
3623792Sgblack@eecs.umich.edu
3633792Sgblack@eecs.umich.edutemplate <class Impl>
3643792Sgblack@eecs.umich.eduFloatRegBits
3654185Ssaidi@eecs.umich.eduFullO3CPU<Impl>::readFloatRegBits(int reg_idx, int width)
3663792Sgblack@eecs.umich.edu{
3673792Sgblack@eecs.umich.edu    return regFile.readFloatRegBits(reg_idx, width);
3684172Ssaidi@eecs.umich.edu}
3693792Sgblack@eecs.umich.edu
3703792Sgblack@eecs.umich.edutemplate <class Impl>
3714185Ssaidi@eecs.umich.eduFloatRegBits
3723792Sgblack@eecs.umich.eduFullO3CPU<Impl>::readFloatRegBits(int reg_idx)
3733792Sgblack@eecs.umich.edu{
3743792Sgblack@eecs.umich.edu    return regFile.readFloatRegBits(reg_idx);
3754172Ssaidi@eecs.umich.edu}
3763792Sgblack@eecs.umich.edu
3773792Sgblack@eecs.umich.edutemplate <class Impl>
3785358Sgblack@eecs.umich.eduvoid
3795358Sgblack@eecs.umich.eduFullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
3805358Sgblack@eecs.umich.edu{
3815358Sgblack@eecs.umich.edu    regFile.setIntReg(reg_idx, val);
3825358Sgblack@eecs.umich.edu}
3835358Sgblack@eecs.umich.edu
3845358Sgblack@eecs.umich.edutemplate <class Impl>
3855358Sgblack@eecs.umich.eduvoid
3865358Sgblack@eecs.umich.eduFullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val, int width)
3875358Sgblack@eecs.umich.edu{
3885358Sgblack@eecs.umich.edu    regFile.setFloatReg(reg_idx, val, width);
3895358Sgblack@eecs.umich.edu}
3905358Sgblack@eecs.umich.edu
3915358Sgblack@eecs.umich.edutemplate <class Impl>
3925358Sgblack@eecs.umich.eduvoid
3934027Sstever@eecs.umich.eduFullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val)
3944027Sstever@eecs.umich.edu{
3954027Sstever@eecs.umich.edu    regFile.setFloatReg(reg_idx, val);
3964027Sstever@eecs.umich.edu}
3974027Sstever@eecs.umich.edu
3984027Sstever@eecs.umich.edutemplate <class Impl>
3994027Sstever@eecs.umich.eduvoid
4004027Sstever@eecs.umich.eduFullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val, int width)
4014661Sksewell@umich.edu{
4024661Sksewell@umich.edu    regFile.setFloatRegBits(reg_idx, val, width);
4034661Sksewell@umich.edu}
4044661Sksewell@umich.edu
4054661Sksewell@umich.edutemplate <class Impl>
4064661Sksewell@umich.eduvoid
4074661Sksewell@umich.eduFullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
4084661Sksewell@umich.edu{
4094661Sksewell@umich.edu    regFile.setFloatRegBits(reg_idx, val);
4104661Sksewell@umich.edu}
4114661Sksewell@umich.edu
4124661Sksewell@umich.edutemplate <class Impl>
4135250Sksewell@umich.eduuint64_t
4145222Sksewell@umich.eduFullO3CPU<Impl>::readPC()
4151858SN/A{
4162683Sktlim@umich.edu    return regFile.readPC();
4172680Sktlim@umich.edu}
4182683Sktlim@umich.edu
419705SN/Atemplate <class Impl>
4202683Sktlim@umich.eduvoid
421705SN/AFullO3CPU<Impl>::setNextPC(uint64_t val)
422705SN/A{
4232683Sktlim@umich.edu    regFile.setNextPC(val);
4242680Sktlim@umich.edu}
4252SN/A
4262SN/Atemplate <class Impl>
4272623SN/Avoid
428FullO3CPU<Impl>::setPC(Addr new_PC)
429{
430    regFile.setPC(new_PC);
431}
432
433template <class Impl>
434void
435FullO3CPU<Impl>::addInst(DynInstPtr &inst)
436{
437    instList.push_back(inst);
438}
439
440template <class Impl>
441void
442FullO3CPU<Impl>::instDone()
443{
444    // Keep an instruction count.
445    numInsts++;
446
447    // Check for instruction-count-based events.
448    comInstEventQueue[0]->serviceEvents(numInsts);
449}
450
451template <class Impl>
452void
453FullO3CPU<Impl>::removeBackInst(DynInstPtr &inst)
454{
455    DynInstPtr inst_to_delete;
456
457    // Walk through the instruction list, removing any instructions
458    // that were inserted after the given instruction, inst.
459    while (instList.back() != inst)
460    {
461        assert(!instList.empty());
462
463        // Obtain the pointer to the instruction.
464        inst_to_delete = instList.back();
465
466        DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
467                inst_to_delete->seqNum, inst_to_delete->readPC());
468
469        // Remove the instruction from the list.
470        instList.pop_back();
471
472        // Mark it as squashed.
473        inst_to_delete->setSquashed();
474    }
475}
476
477template <class Impl>
478void
479FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
480{
481    DynInstPtr inst_to_remove;
482
483    // The front instruction should be the same one being asked to be removed.
484    assert(instList.front() == inst);
485
486    // Remove the front instruction.
487    inst_to_remove = inst;
488    instList.pop_front();
489
490    DPRINTF(FullCPU, "FullCPU: Removing committed instruction %#x, PC %#x\n",
491            inst_to_remove, inst_to_remove->readPC());
492}
493
494template <class Impl>
495void
496FullO3CPU<Impl>::removeInstsNotInROB()
497{
498    DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
499            "list.\n");
500
501    DynInstPtr rob_tail = rob.readTailInst();
502
503    removeBackInst(rob_tail);
504}
505
506template <class Impl>
507void
508FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num)
509{
510    DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
511            "list.\n");
512
513    DynInstPtr inst_to_delete;
514
515    while (instList.back()->seqNum > seq_num) {
516        assert(!instList.empty());
517
518        // Obtain the pointer to the instruction.
519        inst_to_delete = instList.back();
520
521        DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
522                inst_to_delete->seqNum, inst_to_delete->readPC());
523
524        // Remove the instruction from the list.
525        instList.back() = NULL;
526        instList.pop_back();
527
528        // Mark it as squashed.
529        inst_to_delete->setSquashed();
530    }
531
532}
533
534template <class Impl>
535void
536FullO3CPU<Impl>::removeAllInsts()
537{
538    instList.clear();
539}
540
541template <class Impl>
542void
543FullO3CPU<Impl>::dumpInsts()
544{
545    int num = 0;
546    typename list<DynInstPtr>::iterator inst_list_it = instList.begin();
547
548    while (inst_list_it != instList.end())
549    {
550        cprintf("Instruction:%i\nPC:%#x\nSN:%lli\nIssued:%i\nSquashed:%i\n\n",
551                num, (*inst_list_it)->readPC(), (*inst_list_it)->seqNum,
552                (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed());
553        inst_list_it++;
554        ++num;
555    }
556}
557
558template <class Impl>
559void
560FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst)
561{
562    iew.wakeDependents(inst);
563}
564
565// Forward declaration of FullO3CPU.
566template class FullO3CPU<AlphaSimpleImpl>;
567