cpu.cc revision 2107
12650Ssaidi@eecs.umich.edu/*
22650Ssaidi@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
32650Ssaidi@eecs.umich.edu * All rights reserved.
42650Ssaidi@eecs.umich.edu *
52650Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
62650Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are
72650Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright
82650Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
92650Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
102650Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
112650Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution;
122650Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its
132650Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from
142650Ssaidi@eecs.umich.edu * this software without specific prior written permission.
152650Ssaidi@eecs.umich.edu *
162650Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172650Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182650Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192650Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202650Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212650Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222650Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232650Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242650Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252650Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262650Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272650Ssaidi@eecs.umich.edu */
282650Ssaidi@eecs.umich.edu
293817Ssaidi@eecs.umich.edu#include "config/full_system.hh"
303817Ssaidi@eecs.umich.edu
313817Ssaidi@eecs.umich.edu#if FULL_SYSTEM
323817Ssaidi@eecs.umich.edu#include "sim/system.hh"
333817Ssaidi@eecs.umich.edu#else
342650Ssaidi@eecs.umich.edu#include "sim/process.hh"
353817Ssaidi@eecs.umich.edu#endif
363817Ssaidi@eecs.umich.edu#include "sim/root.hh"
373817Ssaidi@eecs.umich.edu
383817Ssaidi@eecs.umich.edu#include "cpu/o3/alpha_dyn_inst.hh"
393894Shsul@eecs.umich.edu#include "cpu/o3/alpha_impl.hh"
402650Ssaidi@eecs.umich.edu#include "cpu/o3/cpu.hh"
412650Ssaidi@eecs.umich.edu#include "cpu/exec_context.hh"
422650Ssaidi@eecs.umich.edu
432982Sstever@eecs.umich.eduusing namespace std;
443894Shsul@eecs.umich.edu
453894Shsul@eecs.umich.eduBaseFullCPU::BaseFullCPU(Params &params)
463894Shsul@eecs.umich.edu    : BaseCPU(&params), cpu_id(0)
473894Shsul@eecs.umich.edu{
483894Shsul@eecs.umich.edu}
493894Shsul@eecs.umich.edu
502650Ssaidi@eecs.umich.edutemplate <class Impl>
513894Shsul@eecs.umich.eduFullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
523894Shsul@eecs.umich.edu    : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
533894Shsul@eecs.umich.edu{
543894Shsul@eecs.umich.edu}
552650Ssaidi@eecs.umich.edu
563894Shsul@eecs.umich.edutemplate <class Impl>
573894Shsul@eecs.umich.eduvoid
583894Shsul@eecs.umich.eduFullO3CPU<Impl>::TickEvent::process()
593894Shsul@eecs.umich.edu{
603894Shsul@eecs.umich.edu    cpu->tick();
613894Shsul@eecs.umich.edu}
623894Shsul@eecs.umich.edu
633894Shsul@eecs.umich.edutemplate <class Impl>
643894Shsul@eecs.umich.educonst char *
653894Shsul@eecs.umich.eduFullO3CPU<Impl>::TickEvent::description()
663894Shsul@eecs.umich.edu{
672650Ssaidi@eecs.umich.edu    return "FullO3CPU tick event";
683894Shsul@eecs.umich.edu}
693894Shsul@eecs.umich.edu
703894Shsul@eecs.umich.edu//Call constructor to all the pipeline stages here
713894Shsul@eecs.umich.edutemplate <class Impl>
723894Shsul@eecs.umich.eduFullO3CPU<Impl>::FullO3CPU(Params &params)
733894Shsul@eecs.umich.edu#if FULL_SYSTEM
743894Shsul@eecs.umich.edu    : BaseFullCPU(params),
753894Shsul@eecs.umich.edu#else
763894Shsul@eecs.umich.edu    : BaseFullCPU(params),
773894Shsul@eecs.umich.edu#endif // FULL_SYSTEM
783894Shsul@eecs.umich.edu      tickEvent(this),
793894Shsul@eecs.umich.edu      fetch(params),
802650Ssaidi@eecs.umich.edu      decode(params),
813894Shsul@eecs.umich.edu      rename(params),
823897Shsul@eecs.umich.edu      iew(params),
833894Shsul@eecs.umich.edu      commit(params),
843894Shsul@eecs.umich.edu
853894Shsul@eecs.umich.edu      regFile(params.numPhysIntRegs, params.numPhysFloatRegs),
863827Shsul@eecs.umich.edu
873894Shsul@eecs.umich.edu      freeList(TheISA::NumIntRegs, params.numPhysIntRegs,
883894Shsul@eecs.umich.edu               TheISA::NumFloatRegs, params.numPhysFloatRegs),
893894Shsul@eecs.umich.edu
903894Shsul@eecs.umich.edu      renameMap(TheISA::NumIntRegs, params.numPhysIntRegs,
913894Shsul@eecs.umich.edu                TheISA::NumFloatRegs, params.numPhysFloatRegs,
923894Shsul@eecs.umich.edu                TheISA::NumMiscRegs,
932650Ssaidi@eecs.umich.edu                TheISA::ZeroReg,
943894Shsul@eecs.umich.edu                TheISA::ZeroReg + TheISA::NumIntRegs),
953894Shsul@eecs.umich.edu
962650Ssaidi@eecs.umich.edu      rob(params.numROBEntries, params.squashWidth),
973894Shsul@eecs.umich.edu
983894Shsul@eecs.umich.edu      // What to pass to these time buffers?
993894Shsul@eecs.umich.edu      // For now just have these time buffers be pretty big.
1003894Shsul@eecs.umich.edu      timeBuffer(5, 5),
1012650Ssaidi@eecs.umich.edu      fetchQueue(5, 5),
1023894Shsul@eecs.umich.edu      decodeQueue(5, 5),
1033894Shsul@eecs.umich.edu      renameQueue(5, 5),
1043894Shsul@eecs.umich.edu      iewQueue(5, 5),
1053894Shsul@eecs.umich.edu
1063894Shsul@eecs.umich.edu      xc(NULL),
1073894Shsul@eecs.umich.edu
1083894Shsul@eecs.umich.edu      globalSeqNum(1),
1093894Shsul@eecs.umich.edu
1103894Shsul@eecs.umich.edu#if FULL_SYSTEM
1113894Shsul@eecs.umich.edu      system(params.system),
1123894Shsul@eecs.umich.edu      memCtrl(system->memctrl),
1133828Shsul@eecs.umich.edu      physmem(system->physmem),
1143894Shsul@eecs.umich.edu      itb(params.itb),
1153894Shsul@eecs.umich.edu      dtb(params.dtb),
1163894Shsul@eecs.umich.edu      mem(params.mem),
1173894Shsul@eecs.umich.edu#else
1183894Shsul@eecs.umich.edu      // Hardcoded for a single thread!!
1193894Shsul@eecs.umich.edu      mem(params.workload[0]->getMemory()),
1203894Shsul@eecs.umich.edu#endif // FULL_SYSTEM
1213894Shsul@eecs.umich.edu
1223894Shsul@eecs.umich.edu      icacheInterface(params.icacheInterface),
1233894Shsul@eecs.umich.edu      dcacheInterface(params.dcacheInterface),
1243894Shsul@eecs.umich.edu      deferRegistration(params.defReg),
1253894Shsul@eecs.umich.edu      numInsts(0),
1263817Ssaidi@eecs.umich.edu      funcExeInst(0)
1273894Shsul@eecs.umich.edu{
1283894Shsul@eecs.umich.edu    _status = Idle;
1293897Shsul@eecs.umich.edu
1303894Shsul@eecs.umich.edu#if !FULL_SYSTEM
1313894Shsul@eecs.umich.edu    thread.resize(this->number_of_threads);
1323894Shsul@eecs.umich.edu#endif
1333894Shsul@eecs.umich.edu
1343894Shsul@eecs.umich.edu    for (int i = 0; i < this->number_of_threads; ++i) {
1353817Ssaidi@eecs.umich.edu#if FULL_SYSTEM
1363894Shsul@eecs.umich.edu        assert(i == 0);
1373894Shsul@eecs.umich.edu        system->execContexts[i] =
1382650Ssaidi@eecs.umich.edu            new ExecContext(this, i, system, itb, dtb, mem);
1392650Ssaidi@eecs.umich.edu
1402650Ssaidi@eecs.umich.edu        // initialize CPU, including PC
1412650Ssaidi@eecs.umich.edu        TheISA::initCPU(&system->execContexts[i]->regs);
1423817Ssaidi@eecs.umich.edu        execContexts.push_back(system->execContexts[i]);
1432650Ssaidi@eecs.umich.edu#else
1442650Ssaidi@eecs.umich.edu        if (i < params.workload.size()) {
1453894Shsul@eecs.umich.edu            DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, "
1463825Ssaidi@eecs.umich.edu                    "process is %#x",
1473825Ssaidi@eecs.umich.edu                    i, params.workload[i]->prog_entry, thread[i]);
1483825Ssaidi@eecs.umich.edu            thread[i] = new ExecContext(this, i, params.workload[i], i);
1493825Ssaidi@eecs.umich.edu        }
1503825Ssaidi@eecs.umich.edu        assert(params.workload[i]->getMemory() != NULL);
1513825Ssaidi@eecs.umich.edu        assert(mem != NULL);
1523825Ssaidi@eecs.umich.edu        execContexts.push_back(thread[i]);
1533825Ssaidi@eecs.umich.edu#endif // !FULL_SYSTEM
1543825Ssaidi@eecs.umich.edu    }
1553825Ssaidi@eecs.umich.edu
1563825Ssaidi@eecs.umich.edu    // Note that this is a hack so that my code which still uses xc-> will
1573825Ssaidi@eecs.umich.edu    // still work.  I should remove this eventually
1583825Ssaidi@eecs.umich.edu#if FULL_SYSTEM
1593825Ssaidi@eecs.umich.edu    xc = system->execContexts[0];
1603825Ssaidi@eecs.umich.edu#else
1613825Ssaidi@eecs.umich.edu    xc = thread[0];
1623825Ssaidi@eecs.umich.edu#endif
1633825Ssaidi@eecs.umich.edu
1642650Ssaidi@eecs.umich.edu    // The stages also need their CPU pointer setup.  However this must be
1653825Ssaidi@eecs.umich.edu    // done at the upper level CPU because they have pointers to the upper
1663825Ssaidi@eecs.umich.edu    // level CPU, and not this FullO3CPU.
1673825Ssaidi@eecs.umich.edu
1683825Ssaidi@eecs.umich.edu    // Give each of the stages the time buffer they will use.
1692650Ssaidi@eecs.umich.edu    fetch.setTimeBuffer(&timeBuffer);
1703825Ssaidi@eecs.umich.edu    decode.setTimeBuffer(&timeBuffer);
1713825Ssaidi@eecs.umich.edu    rename.setTimeBuffer(&timeBuffer);
1722650Ssaidi@eecs.umich.edu    iew.setTimeBuffer(&timeBuffer);
1732650Ssaidi@eecs.umich.edu    commit.setTimeBuffer(&timeBuffer);
1743817Ssaidi@eecs.umich.edu
1753894Shsul@eecs.umich.edu    // Also setup each of the stages' queues.
1763894Shsul@eecs.umich.edu    fetch.setFetchQueue(&fetchQueue);
1773894Shsul@eecs.umich.edu    decode.setFetchQueue(&fetchQueue);
1783894Shsul@eecs.umich.edu    decode.setDecodeQueue(&decodeQueue);
1793894Shsul@eecs.umich.edu    rename.setDecodeQueue(&decodeQueue);
1803894Shsul@eecs.umich.edu    rename.setRenameQueue(&renameQueue);
1813817Ssaidi@eecs.umich.edu    iew.setRenameQueue(&renameQueue);
1823817Ssaidi@eecs.umich.edu    iew.setIEWQueue(&iewQueue);
1833817Ssaidi@eecs.umich.edu    commit.setIEWQueue(&iewQueue);
1842650Ssaidi@eecs.umich.edu    commit.setRenameQueue(&renameQueue);
1852651Ssaidi@eecs.umich.edu
1862680Sktlim@umich.edu    // Setup the rename map for whichever stages need it.
1872651Ssaidi@eecs.umich.edu    rename.setRenameMap(&renameMap);
1882651Ssaidi@eecs.umich.edu    iew.setRenameMap(&renameMap);
1892651Ssaidi@eecs.umich.edu
1902651Ssaidi@eecs.umich.edu    // Setup the free list for whichever stages need it.
1912651Ssaidi@eecs.umich.edu    rename.setFreeList(&freeList);
1922680Sktlim@umich.edu    renameMap.setFreeList(&freeList);
1932651Ssaidi@eecs.umich.edu
1943888Ssaidi@eecs.umich.edu    // Setup the ROB for whichever stages need it.
1953888Ssaidi@eecs.umich.edu    commit.setROB(&rob);
1963888Ssaidi@eecs.umich.edu}
1973888Ssaidi@eecs.umich.edu
1983890Ssaidi@eecs.umich.edutemplate <class Impl>
1993894Shsul@eecs.umich.eduFullO3CPU<Impl>::~FullO3CPU()
2003888Ssaidi@eecs.umich.edu{
2013888Ssaidi@eecs.umich.edu}
2023888Ssaidi@eecs.umich.edu
2033888Ssaidi@eecs.umich.edutemplate <class Impl>
2043888Ssaidi@eecs.umich.eduvoid
2053894Shsul@eecs.umich.eduFullO3CPU<Impl>::fullCPURegStats()
2063888Ssaidi@eecs.umich.edu{
2073890Ssaidi@eecs.umich.edu    // Register any of the FullCPU's stats here.
2083888Ssaidi@eecs.umich.edu}
2093888Ssaidi@eecs.umich.edu
2102651Ssaidi@eecs.umich.edutemplate <class Impl>
2112651Ssaidi@eecs.umich.eduvoid
2122651Ssaidi@eecs.umich.eduFullO3CPU<Impl>::tick()
2132680Sktlim@umich.edu{
2142651Ssaidi@eecs.umich.edu    DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n");
2153891Ssaidi@eecs.umich.edu
2163891Ssaidi@eecs.umich.edu    //Tick each of the stages if they're actually running.
2173891Ssaidi@eecs.umich.edu    //Will want to figure out a way to unschedule itself if they're all
2183891Ssaidi@eecs.umich.edu    //going to be idle for a long time.
2193891Ssaidi@eecs.umich.edu    fetch.tick();
2203894Shsul@eecs.umich.edu
2213891Ssaidi@eecs.umich.edu    decode.tick();
2223891Ssaidi@eecs.umich.edu
2233891Ssaidi@eecs.umich.edu    rename.tick();
2243891Ssaidi@eecs.umich.edu
2253891Ssaidi@eecs.umich.edu    iew.tick();
2263894Shsul@eecs.umich.edu
2273891Ssaidi@eecs.umich.edu    commit.tick();
2283891Ssaidi@eecs.umich.edu
2293891Ssaidi@eecs.umich.edu    // Now advance the time buffers, unless the stage is stalled.
2303891Ssaidi@eecs.umich.edu    timeBuffer.advance();
2312651Ssaidi@eecs.umich.edu
2322650Ssaidi@eecs.umich.edu    fetchQueue.advance();
233    decodeQueue.advance();
234    renameQueue.advance();
235    iewQueue.advance();
236
237    if (_status == Running && !tickEvent.scheduled())
238        tickEvent.schedule(curTick + 1);
239}
240
241template <class Impl>
242void
243FullO3CPU<Impl>::init()
244{
245    if(!deferRegistration)
246    {
247        this->registerExecContexts();
248
249        // Need to do a copy of the xc->regs into the CPU's regfile so
250        // that it can start properly.
251#if FULL_SYSTEM
252        ExecContext *src_xc = system->execContexts[0];
253#else
254        ExecContext *src_xc = thread[0];
255#endif
256        // First loop through the integer registers.
257        for (int i = 0; i < TheISA::NumIntRegs; ++i)
258        {
259            regFile.intRegFile[i] = src_xc->regs.intRegFile[i];
260        }
261
262        // Then loop through the floating point registers.
263        for (int i = 0; i < TheISA::NumFloatRegs; ++i)
264        {
265            regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i];
266            regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i];
267        }
268
269        // Then loop through the misc registers.
270        regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr;
271        regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq;
272        regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag;
273        regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr;
274
275        // Then finally set the PC and the next PC.
276        regFile.pc = src_xc->regs.pc;
277        regFile.npc = src_xc->regs.npc;
278    }
279}
280
281template <class Impl>
282void
283FullO3CPU<Impl>::activateContext(int thread_num, int delay)
284{
285    // Needs to set each stage to running as well.
286
287    scheduleTickEvent(delay);
288
289    _status = Running;
290}
291
292template <class Impl>
293void
294FullO3CPU<Impl>::suspendContext(int thread_num)
295{
296    panic("suspendContext unimplemented!");
297}
298
299template <class Impl>
300void
301FullO3CPU<Impl>::deallocateContext(int thread_num)
302{
303    panic("deallocateContext unimplemented!");
304}
305
306template <class Impl>
307void
308FullO3CPU<Impl>::haltContext(int thread_num)
309{
310    panic("haltContext unimplemented!");
311}
312
313template <class Impl>
314void
315FullO3CPU<Impl>::switchOut()
316{
317    panic("FullO3CPU does not have a switch out function.\n");
318}
319
320template <class Impl>
321void
322FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
323{
324    BaseCPU::takeOverFrom(oldCPU);
325
326    assert(!tickEvent.scheduled());
327
328    // Set all status's to active, schedule the
329    // CPU's tick event.
330    for (int i = 0; i < execContexts.size(); ++i) {
331        ExecContext *xc = execContexts[i];
332        if (xc->status() == ExecContext::Active && _status != Running) {
333            _status = Running;
334            tickEvent.schedule(curTick);
335        }
336    }
337}
338
339template <class Impl>
340InstSeqNum
341FullO3CPU<Impl>::getAndIncrementInstSeq()
342{
343    // Hopefully this works right.
344    return globalSeqNum++;
345}
346
347template <class Impl>
348uint64_t
349FullO3CPU<Impl>::readIntReg(int reg_idx)
350{
351    return regFile.readIntReg(reg_idx);
352}
353
354template <class Impl>
355float
356FullO3CPU<Impl>::readFloatRegSingle(int reg_idx)
357{
358    return regFile.readFloatRegSingle(reg_idx);
359}
360
361template <class Impl>
362double
363FullO3CPU<Impl>::readFloatRegDouble(int reg_idx)
364{
365    return regFile.readFloatRegDouble(reg_idx);
366}
367
368template <class Impl>
369uint64_t
370FullO3CPU<Impl>::readFloatRegInt(int reg_idx)
371{
372    return regFile.readFloatRegInt(reg_idx);
373}
374
375template <class Impl>
376void
377FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
378{
379    regFile.setIntReg(reg_idx, val);
380}
381
382template <class Impl>
383void
384FullO3CPU<Impl>::setFloatRegSingle(int reg_idx, float val)
385{
386    regFile.setFloatRegSingle(reg_idx, val);
387}
388
389template <class Impl>
390void
391FullO3CPU<Impl>::setFloatRegDouble(int reg_idx, double val)
392{
393    regFile.setFloatRegDouble(reg_idx, val);
394}
395
396template <class Impl>
397void
398FullO3CPU<Impl>::setFloatRegInt(int reg_idx, uint64_t val)
399{
400    regFile.setFloatRegInt(reg_idx, val);
401}
402
403template <class Impl>
404uint64_t
405FullO3CPU<Impl>::readPC()
406{
407    return regFile.readPC();
408}
409
410template <class Impl>
411void
412FullO3CPU<Impl>::setNextPC(uint64_t val)
413{
414    regFile.setNextPC(val);
415}
416
417template <class Impl>
418void
419FullO3CPU<Impl>::setPC(Addr new_PC)
420{
421    regFile.setPC(new_PC);
422}
423
424template <class Impl>
425void
426FullO3CPU<Impl>::addInst(DynInstPtr &inst)
427{
428    instList.push_back(inst);
429}
430
431template <class Impl>
432void
433FullO3CPU<Impl>::instDone()
434{
435    // Keep an instruction count.
436    numInsts++;
437
438    // Check for instruction-count-based events.
439    comInstEventQueue[0]->serviceEvents(numInsts);
440}
441
442template <class Impl>
443void
444FullO3CPU<Impl>::removeBackInst(DynInstPtr &inst)
445{
446    DynInstPtr inst_to_delete;
447
448    // Walk through the instruction list, removing any instructions
449    // that were inserted after the given instruction, inst.
450    while (instList.back() != inst)
451    {
452        assert(!instList.empty());
453
454        // Obtain the pointer to the instruction.
455        inst_to_delete = instList.back();
456
457        DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
458                inst_to_delete->seqNum, inst_to_delete->readPC());
459
460        // Remove the instruction from the list.
461        instList.pop_back();
462
463        // Mark it as squashed.
464        inst_to_delete->setSquashed();
465    }
466}
467
468template <class Impl>
469void
470FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
471{
472    DynInstPtr inst_to_remove;
473
474    // The front instruction should be the same one being asked to be removed.
475    assert(instList.front() == inst);
476
477    // Remove the front instruction.
478    inst_to_remove = inst;
479    instList.pop_front();
480
481    DPRINTF(FullCPU, "FullCPU: Removing committed instruction %#x, PC %#x\n",
482            inst_to_remove, inst_to_remove->readPC());
483}
484
485template <class Impl>
486void
487FullO3CPU<Impl>::removeInstsNotInROB()
488{
489    DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
490            "list.\n");
491
492    DynInstPtr rob_tail = rob.readTailInst();
493
494    removeBackInst(rob_tail);
495}
496
497template <class Impl>
498void
499FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num)
500{
501    DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
502            "list.\n");
503
504    DynInstPtr inst_to_delete;
505
506    while (instList.back()->seqNum > seq_num) {
507        assert(!instList.empty());
508
509        // Obtain the pointer to the instruction.
510        inst_to_delete = instList.back();
511
512        DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
513                inst_to_delete->seqNum, inst_to_delete->readPC());
514
515        // Remove the instruction from the list.
516        instList.back() = NULL;
517        instList.pop_back();
518
519        // Mark it as squashed.
520        inst_to_delete->setSquashed();
521    }
522
523}
524
525template <class Impl>
526void
527FullO3CPU<Impl>::removeAllInsts()
528{
529    instList.clear();
530}
531
532template <class Impl>
533void
534FullO3CPU<Impl>::dumpInsts()
535{
536    int num = 0;
537    typename list<DynInstPtr>::iterator inst_list_it = instList.begin();
538
539    while (inst_list_it != instList.end())
540    {
541        cprintf("Instruction:%i\nPC:%#x\nSN:%lli\nIssued:%i\nSquashed:%i\n\n",
542                num, (*inst_list_it)->readPC(), (*inst_list_it)->seqNum,
543                (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed());
544        inst_list_it++;
545        ++num;
546    }
547}
548
549template <class Impl>
550void
551FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst)
552{
553    iew.wakeDependents(inst);
554}
555
556// Forward declaration of FullO3CPU.
557template class FullO3CPU<AlphaSimpleImpl>;
558