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
35a38
> #include "sim/root.hh"
37,38d39
< #include "cpu/activity.hh"
< #include "cpu/checker/cpu.hh"
45,47d45
< #include "sim/root.hh"
< #include "sim/stat_control.hh"
<
50,51c48,49
< BaseFullCPU::BaseFullCPU(Params *params)
< : BaseCPU(params), cpu_id(0)
---
> BaseFullCPU::BaseFullCPU(Params &params)
> : BaseCPU(&params), cpu_id(0)
55,60d52
< void
< BaseFullCPU::regStats()
< {
< BaseCPU::regStats();
< }
<
80a73
> //Call constructor to all the pipeline stages here
82c75,76
< FullO3CPU<Impl>::FullO3CPU(Params *params)
---
> FullO3CPU<Impl>::FullO3CPU(Params &params)
> #if FULL_SYSTEM
83a78,80
> #else
> : BaseFullCPU(params),
> #endif // FULL_SYSTEM
85d81
< removeInstsThisCycle(false),
92c88
< regFile(params->numPhysIntRegs, params->numPhysFloatRegs),
---
> regFile(params.numPhysIntRegs, params.numPhysFloatRegs),
94,96c90,91
< freeList(params->numberOfThreads,//number of activeThreads
< TheISA::NumIntRegs, params->numPhysIntRegs,
< TheISA::NumFloatRegs, params->numPhysFloatRegs),
---
> freeList(TheISA::NumIntRegs, params.numPhysIntRegs,
> TheISA::NumFloatRegs, params.numPhysFloatRegs),
98,100c93,97
< rob(params->numROBEntries, params->squashWidth,
< params->smtROBPolicy, params->smtROBThreshold,
< params->numberOfThreads),
---
> renameMap(TheISA::NumIntRegs, params.numPhysIntRegs,
> TheISA::NumFloatRegs, params.numPhysFloatRegs,
> TheISA::NumMiscRegs,
> TheISA::ZeroReg,
> TheISA::ZeroReg + TheISA::NumIntRegs),
102,106c99
< scoreboard(params->numberOfThreads,//number of activeThreads
< TheISA::NumIntRegs, params->numPhysIntRegs,
< TheISA::NumFloatRegs, params->numPhysFloatRegs,
< TheISA::NumMiscRegs * number_of_threads,
< TheISA::ZeroReg),
---
> rob(params.numROBEntries, params.squashWidth),
107a101
> // What to pass to these time buffers?
109,110d102
< // @todo: Make these time buffer sizes parameters or derived
< // from latencies
116d107
< activityRec(NumStages, 10, params->activity),
117a109,110
> cpuXC(NULL),
>
121c114
< system(params->system),
---
> system(params.system),
124c117,119
< mem(params->mem),
---
> itb(params.itb),
> dtb(params.dtb),
> mem(params.mem),
126,127c121,122
< // pTable(params->pTable),
< mem(params->workload[0]->getMemory()),
---
> // Hardcoded for a single thread!!
> mem(params.workload[0]->getMemory()),
129,133c124,129
< switchCount(0),
< icacheInterface(params->icacheInterface),
< dcacheInterface(params->dcacheInterface),
< deferRegistration(params->deferRegistration),
< numThreads(number_of_threads)
---
>
> icacheInterface(params.icacheInterface),
> dcacheInterface(params.dcacheInterface),
> deferRegistration(params.defReg),
> numInsts(0),
> funcExeInst(0)
137,147d132
< if (params->checker) {
< BaseCPU *temp_checker = params->checker;
< checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
< checker->setMemory(mem);
< #if FULL_SYSTEM
< checker->setSystem(params->system);
< #endif
< } else {
< checker = NULL;
< }
<
149,150c134
< thread.resize(number_of_threads);
< tids.resize(number_of_threads);
---
> thread.resize(this->number_of_threads);
153,155c137,141
< // The stages also need their CPU pointer setup. However this
< // must be done at the upper level CPU because they have pointers
< // to the upper level CPU, and not this FullO3CPU.
---
> for (int i = 0; i < this->number_of_threads; ++i) {
> #if FULL_SYSTEM
> assert(i == 0);
> thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem);
> system->execContexts[i] = thread[i]->getProxy();
157,162c143,155
< // Set up Pointers to the activeThreads list for each stage
< fetch.setActiveThreads(&activeThreads);
< decode.setActiveThreads(&activeThreads);
< rename.setActiveThreads(&activeThreads);
< iew.setActiveThreads(&activeThreads);
< commit.setActiveThreads(&activeThreads);
---
> execContexts.push_back(system->execContexts[i]);
> #else
> if (i < params.workload.size()) {
> DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, "
> "process is %#x",
> i, params.workload[i]->prog_entry, thread[i]);
> thread[i] = new CPUExecContext(this, i, params.workload[i], i);
> }
> assert(params.workload[i]->getMemory() != NULL);
> assert(mem != NULL);
> execContexts.push_back(thread[i]->getProxy());
> #endif // !FULL_SYSTEM
> }
163a157,164
> // Note that this is a hack so that my code which still uses xc-> will
> // still work. I should remove this eventually
> cpuXC = thread[0];
>
> // The stages also need their CPU pointer setup. However this must be
> // done at the upper level CPU because they have pointers to the upper
> // level CPU, and not this FullO3CPU.
>
174d174
< commit.setFetchQueue(&fetchQueue);
183,200d182
< commit.setFetchStage(&fetch);
< commit.setIEWStage(&iew);
< rename.setIEWStage(&iew);
< rename.setCommitStage(&commit);
<
< #if !FULL_SYSTEM
< int active_threads = params->workload.size();
< #else
< int active_threads = 1;
< #endif
<
< //Make Sure That this a Valid Architeture
< assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs);
< assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
<
< rename.setScoreboard(&scoreboard);
< iew.setScoreboard(&scoreboard);
<
202,203c184,185
< PhysRegIndex lreg_idx = 0;
< PhysRegIndex freg_idx = params->numPhysIntRegs; //Index to 1 after int regs
---
> rename.setRenameMap(&renameMap);
> iew.setRenameMap(&renameMap);
205,247c187
< for (int tid=0; tid < numThreads; tid++) {
< bool bindRegs = (tid <= active_threads - 1);
<
< commitRenameMap[tid].init(TheISA::NumIntRegs,
< params->numPhysIntRegs,
< lreg_idx, //Index for Logical. Regs
<
< TheISA::NumFloatRegs,
< params->numPhysFloatRegs,
< freg_idx, //Index for Float Regs
<
< TheISA::NumMiscRegs,
<
< TheISA::ZeroReg,
< TheISA::ZeroReg,
<
< tid,
< false);
<
< renameMap[tid].init(TheISA::NumIntRegs,
< params->numPhysIntRegs,
< lreg_idx, //Index for Logical. Regs
<
< TheISA::NumFloatRegs,
< params->numPhysFloatRegs,
< freg_idx, //Index for Float Regs
<
< TheISA::NumMiscRegs,
<
< TheISA::ZeroReg,
< TheISA::ZeroReg,
<
< tid,
< bindRegs);
< }
<
< rename.setRenameMap(renameMap);
< commit.setRenameMap(commitRenameMap);
<
< // Give renameMap & rename stage access to the freeList;
< for (int i=0; i < numThreads; i++) {
< renameMap[i].setFreeList(&freeList);
< }
---
> // Setup the free list for whichever stages need it.
248a189
> renameMap.setFreeList(&freeList);
250,255d190
< // Setup the page table for whichever stages need it.
< #if !FULL_SYSTEM
< // fetch.setPageTable(pTable);
< // iew.setPageTable(pTable);
< #endif
<
258,261d192
<
< lastRunningCycle = curTick;
<
< contextSwitch = false;
273,274d203
< BaseFullCPU::regStats();
<
276,324d204
< timesIdled
< .name(name() + ".timesIdled")
< .desc("Number of times that the entire CPU went into an idle state and"
< " unscheduled itself")
< .prereq(timesIdled);
<
< idleCycles
< .name(name() + ".idleCycles")
< .desc("Total number of cycles that the CPU has spent unscheduled due "
< "to idling")
< .prereq(idleCycles);
<
< // Number of Instructions simulated
< // --------------------------------
< // Should probably be in Base CPU but need templated
< // MaxThreads so put in here instead
< committedInsts
< .init(numThreads)
< .name(name() + ".committedInsts")
< .desc("Number of Instructions Simulated");
<
< totalCommittedInsts
< .name(name() + ".committedInsts_total")
< .desc("Number of Instructions Simulated");
<
< cpi
< .name(name() + ".cpi")
< .desc("CPI: Cycles Per Instruction")
< .precision(6);
< cpi = simTicks / committedInsts;
<
< totalCpi
< .name(name() + ".cpi_total")
< .desc("CPI: Total CPI of All Threads")
< .precision(6);
< totalCpi = simTicks / totalCommittedInsts;
<
< ipc
< .name(name() + ".ipc")
< .desc("IPC: Instructions Per Cycle")
< .precision(6);
< ipc = committedInsts / simTicks;
<
< totalIpc
< .name(name() + ".ipc_total")
< .desc("IPC: Total IPC of All Threads")
< .precision(6);
< totalIpc = totalCommittedInsts / simTicks;
<
333,337c213,215
< ++numCycles;
<
< // activity = false;
<
< //Tick each of the stages
---
> //Tick each of the stages if they're actually running.
> //Will want to figure out a way to unschedule itself if they're all
> //going to be idle for a long time.
348,352c226
< #if !FULL_SYSTEM
< doContextSwitch();
< #endif
<
< // Now advance the time buffers
---
> // Now advance the time buffers, unless the stage is stalled.
360,381c234,235
< activityRec.advance();
<
< if (removeInstsThisCycle) {
< cleanUpRemovedInsts();
< }
<
< if (!tickEvent.scheduled()) {
< if (_status == SwitchedOut) {
< // increment stat
< lastRunningCycle = curTick;
< } else if (!activityRec.active()) {
< lastRunningCycle = curTick;
< timesIdled++;
< } else {
< tickEvent.schedule(curTick + cycles(1));
< }
< }
<
< #if !FULL_SYSTEM
< updateThreadPriority();
< #endif
<
---
> if (_status == Running && !tickEvent.scheduled())
> tickEvent.schedule(curTick + 1);
388,390c242,244
< if (!deferRegistration) {
< registerExecContexts();
< }
---
> if(!deferRegistration)
> {
> this->registerExecContexts();
392,397c246,247
< // Set inSyscall so that the CPU doesn't squash when initially
< // setting up registers.
< for (int i = 0; i < number_of_threads; ++i)
< thread[i]->inSyscall = true;
<
< for (int tid=0; tid < number_of_threads; tid++) {
---
> // Need to do a copy of the xc->regs into the CPU's regfile so
> // that it can start properly.
399c249,250
< ExecContext *src_xc = execContexts[tid];
---
> ExecContext *src_xc = system->execContexts[0];
> TheISA::initCPU(src_xc, src_xc->readCpuId());
401c252
< ExecContext *src_xc = thread[tid]->getXCProxy();
---
> ExecContext *src_xc = thread[0]->getProxy();
403,405c254,257
< // Threads start in the Suspended State
< if (src_xc->status() != ExecContext::Suspended) {
< continue;
---
> // First loop through the integer registers.
> for (int i = 0; i < TheISA::NumIntRegs; ++i)
> {
> regFile.intRegFile[i] = src_xc->readIntReg(i);
408,410c260,274
< #if FULL_SYSTEM
< TheISA::initCPU(src_xc, src_xc->readCpuId());
< #endif
---
> // Then loop through the floating point registers.
> for (int i = 0; i < TheISA::NumFloatRegs; ++i)
> {
> regFile.floatRegFile.setRegBits(i, src_xc->readRegBits(i))
> }
> /*
> // Then loop through the misc registers.
> regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr;
> regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq;
> regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag;
> regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr;
> */
> // Then finally set the PC and the next PC.
> regFile.pc = src_xc->readPC();
> regFile.npc = src_xc->readNextPC();
412,423d275
<
< // Clear inSyscall.
< for (int i = 0; i < number_of_threads; ++i)
< thread[i]->inSyscall = false;
<
< // Initialize stages.
< fetch.initStage();
< iew.initStage();
< rename.initStage();
< commit.initStage();
<
< commit.setThreads(thread);
428c280
< FullO3CPU<Impl>::insertThread(unsigned tid)
---
> FullO3CPU<Impl>::activateContext(int thread_num, int delay)
430,579d281
< DPRINTF(FullCPU,"[tid:%i] Initializing thread data");
< // Will change now that the PC and thread state is internal to the CPU
< // and not in the CPUExecContext.
< #if 0
< #if FULL_SYSTEM
< ExecContext *src_xc = system->execContexts[tid];
< #else
< CPUExecContext *src_xc = thread[tid];
< #endif
<
< //Bind Int Regs to Rename Map
< for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
< PhysRegIndex phys_reg = freeList.getIntReg();
<
< renameMap[tid].setEntry(ireg,phys_reg);
< scoreboard.setReg(phys_reg);
< }
<
< //Bind Float Regs to Rename Map
< for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) {
< PhysRegIndex phys_reg = freeList.getFloatReg();
<
< renameMap[tid].setEntry(freg,phys_reg);
< scoreboard.setReg(phys_reg);
< }
<
< //Copy Thread Data Into RegFile
< this->copyFromXC(tid);
<
< //Set PC/NPC
< regFile.pc[tid] = src_xc->readPC();
< regFile.npc[tid] = src_xc->readNextPC();
<
< src_xc->setStatus(ExecContext::Active);
<
< activateContext(tid,1);
<
< //Reset ROB/IQ/LSQ Entries
< commit.rob->resetEntries();
< iew.resetEntries();
< #endif
< }
<
< template <class Impl>
< void
< FullO3CPU<Impl>::removeThread(unsigned tid)
< {
< DPRINTF(FullCPU,"[tid:%i] Removing thread data");
< #if 0
< //Unbind Int Regs from Rename Map
< for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
< PhysRegIndex phys_reg = renameMap[tid].lookup(ireg);
<
< scoreboard.unsetReg(phys_reg);
< freeList.addReg(phys_reg);
< }
<
< //Unbind Float Regs from Rename Map
< for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) {
< PhysRegIndex phys_reg = renameMap[tid].lookup(freg);
<
< scoreboard.unsetReg(phys_reg);
< freeList.addReg(phys_reg);
< }
<
< //Copy Thread Data From RegFile
< /* Fix Me:
< * Do we really need to do this if we are removing a thread
< * in the sense that it's finished (exiting)? If the thread is just
< * being suspended we might...
< */
< // this->copyToXC(tid);
<
< //Squash Throughout Pipeline
< fetch.squash(0,tid);
< decode.squash(tid);
< rename.squash(tid);
<
< assert(iew.ldstQueue.getCount(tid) == 0);
<
< //Reset ROB/IQ/LSQ Entries
< if (activeThreads.size() >= 1) {
< commit.rob->resetEntries();
< iew.resetEntries();
< }
< #endif
< }
<
<
< template <class Impl>
< void
< FullO3CPU<Impl>::activateWhenReady(int tid)
< {
< DPRINTF(FullCPU,"[tid:%i]: Checking if resources are available for incoming"
< "(e.g. PhysRegs/ROB/IQ/LSQ) \n",
< tid);
<
< bool ready = true;
<
< if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) {
< DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
< "Phys. Int. Regs.\n",
< tid);
< ready = false;
< } else if (freeList.numFreeFloatRegs() >= TheISA::NumFloatRegs) {
< DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
< "Phys. Float. Regs.\n",
< tid);
< ready = false;
< } else if (commit.rob->numFreeEntries() >=
< commit.rob->entryAmount(activeThreads.size() + 1)) {
< DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
< "ROB entries.\n",
< tid);
< ready = false;
< } else if (iew.instQueue.numFreeEntries() >=
< iew.instQueue.entryAmount(activeThreads.size() + 1)) {
< DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
< "IQ entries.\n",
< tid);
< ready = false;
< } else if (iew.ldstQueue.numFreeEntries() >=
< iew.ldstQueue.entryAmount(activeThreads.size() + 1)) {
< DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
< "LSQ entries.\n",
< tid);
< ready = false;
< }
<
< if (ready) {
< insertThread(tid);
<
< contextSwitch = false;
<
< cpuWaitList.remove(tid);
< } else {
< suspendContext(tid);
<
< //blocks fetch
< contextSwitch = true;
<
< //do waitlist
< cpuWaitList.push_back(tid);
< }
< }
<
< template <class Impl>
< void
< FullO3CPU<Impl>::activateContext(int tid, int delay)
< {
581,582d282
< list<unsigned>::iterator isActive = find(
< activeThreads.begin(), activeThreads.end(), tid);
584,594d283
< if (isActive == activeThreads.end()) {
< //May Need to Re-code this if the delay variable is the
< //delay needed for thread to activate
< DPRINTF(FullCPU, "Adding Thread %i to active threads list\n",
< tid);
<
< activeThreads.push_back(tid);
< }
<
< assert(_status == Idle || _status == SwitchedOut);
<
597,601d285
< // Be sure to signal that there's some activity so the CPU doesn't
< // deschedule itself.
< activityRec.activity();
< fetch.wakeFromQuiesce();
<
607c291
< FullO3CPU<Impl>::suspendContext(int tid)
---
> FullO3CPU<Impl>::suspendContext(int thread_num)
609,622c293
< DPRINTF(FullCPU,"[tid: %i]: Suspended ...\n", tid);
< unscheduleTickEvent();
< _status = Idle;
< /*
< //Remove From Active List, if Active
< list<unsigned>::iterator isActive = find(
< activeThreads.begin(), activeThreads.end(), tid);
<
< if (isActive != activeThreads.end()) {
< DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
< tid);
< activeThreads.erase(isActive);
< }
< */
---
> panic("suspendContext unimplemented!");
627c298
< FullO3CPU<Impl>::deallocateContext(int tid)
---
> FullO3CPU<Impl>::deallocateContext(int thread_num)
629,642c300
< DPRINTF(FullCPU,"[tid:%i]: Deallocating ...", tid);
< /*
< //Remove From Active List, if Active
< list<unsigned>::iterator isActive = find(
< activeThreads.begin(), activeThreads.end(), tid);
<
< if (isActive != activeThreads.end()) {
< DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
< tid);
< activeThreads.erase(isActive);
<
< removeThread(tid);
< }
< */
---
> panic("deallocateContext unimplemented!");
647c305
< FullO3CPU<Impl>::haltContext(int tid)
---
> FullO3CPU<Impl>::haltContext(int thread_num)
649,662c307
< DPRINTF(FullCPU,"[tid:%i]: Halted ...", tid);
< /*
< //Remove From Active List, if Active
< list<unsigned>::iterator isActive = find(
< activeThreads.begin(), activeThreads.end(), tid);
<
< if (isActive != activeThreads.end()) {
< DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
< tid);
< activeThreads.erase(isActive);
<
< removeThread(tid);
< }
< */
---
> panic("haltContext unimplemented!");
667c312
< FullO3CPU<Impl>::switchOut(Sampler *_sampler)
---
> FullO3CPU<Impl>::switchOut()
669,680c314
< sampler = _sampler;
< switchCount = 0;
< fetch.switchOut();
< decode.switchOut();
< rename.switchOut();
< iew.switchOut();
< commit.switchOut();
<
< // Wake the CPU and record activity so everything can drain out if
< // the CPU is currently idle.
< wakeCPU();
< activityRec.activity();
---
> panic("FullO3CPU does not have a switch out function.\n");
685,708d318
< FullO3CPU<Impl>::signalSwitched()
< {
< if (++switchCount == NumStages) {
< fetch.doSwitchOut();
< rename.doSwitchOut();
< commit.doSwitchOut();
< instList.clear();
< while (!removeList.empty()) {
< removeList.pop();
< }
<
< if (checker)
< checker->switchOut(sampler);
<
< if (tickEvent.scheduled())
< tickEvent.squash();
< sampler->signalSwitched();
< _status = SwitchedOut;
< }
< assert(switchCount <= 5);
< }
<
< template <class Impl>
< void
711,721d320
< // Flush out any old data from the time buffers.
< for (int i = 0; i < 10; ++i) {
< timeBuffer.advance();
< fetchQueue.advance();
< decodeQueue.advance();
< renameQueue.advance();
< iewQueue.advance();
< }
<
< activityRec.reset();
<
724,729d322
< fetch.takeOverFrom();
< decode.takeOverFrom();
< rename.takeOverFrom();
< iew.takeOverFrom();
< commit.takeOverFrom();
<
732,749c325,326
< // @todo: Figure out how to properly select the tid to put onto
< // the active threads list.
< int tid = 0;
<
< list<unsigned>::iterator isActive = find(
< activeThreads.begin(), activeThreads.end(), tid);
<
< if (isActive == activeThreads.end()) {
< //May Need to Re-code this if the delay variable is the delay
< //needed for thread to activate
< DPRINTF(FullCPU, "Adding Thread %i to active threads list\n",
< tid);
<
< activeThreads.push_back(tid);
< }
<
< // Set all statuses to active, schedule the CPU's tick event.
< // @todo: Fix up statuses so this is handled properly
---
> // Set all status's to active, schedule the
> // CPU's tick event.
757,758d333
< if (!tickEvent.scheduled())
< tickEvent.schedule(curTick);
761a337,344
> InstSeqNum
> FullO3CPU<Impl>::getAndIncrementInstSeq()
> {
> // Hopefully this works right.
> return globalSeqNum++;
> }
>
> template <class Impl>
784a368
> {
832c416
< FullO3CPU<Impl>::readArchIntReg(int reg_idx, unsigned tid)
---
> FullO3CPU<Impl>::readPC()
834,836c418
< PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
<
< return regFile.readIntReg(phys_reg);
---
> return regFile.readPC();
840,869d421
< float
< FullO3CPU<Impl>::readArchFloatRegSingle(int reg_idx, unsigned tid)
< {
< int idx = reg_idx + TheISA::FP_Base_DepTag;
< PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
<
< return regFile.readFloatRegSingle(phys_reg);
< }
<
< template <class Impl>
< double
< FullO3CPU<Impl>::readArchFloatRegDouble(int reg_idx, unsigned tid)
< {
< int idx = reg_idx + TheISA::FP_Base_DepTag;
< PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
<
< return regFile.readFloatRegDouble(phys_reg);
< }
<
< template <class Impl>
< uint64_t
< FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, unsigned tid)
< {
< int idx = reg_idx + TheISA::FP_Base_DepTag;
< PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
<
< return regFile.readFloatRegInt(phys_reg);
< }
<
< template <class Impl>
871c423
< FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, unsigned tid)
---
> FullO3CPU<Impl>::setNextPC(uint64_t val)
873,875c425
< PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
<
< regFile.setIntReg(phys_reg, val);
---
> regFile.setNextPC(val);
880c430
< FullO3CPU<Impl>::setArchFloatRegSingle(int reg_idx, float val, unsigned tid)
---
> FullO3CPU<Impl>::setPC(Addr new_PC)
882,884c432
< PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
<
< regFile.setFloatRegSingle(phys_reg, val);
---
> regFile.setPC(new_PC);
889c437
< FullO3CPU<Impl>::setArchFloatRegDouble(int reg_idx, double val, unsigned tid)
---
> FullO3CPU<Impl>::addInst(DynInstPtr &inst)
891,893c439
< PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
<
< regFile.setFloatRegDouble(phys_reg, val);
---
> instList.push_back(inst);
898c444
< FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid)
---
> FullO3CPU<Impl>::instDone()
900c446,447
< PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
---
> // Keep an instruction count.
> numInsts++;
902c449,450
< regFile.setFloatRegInt(phys_reg, val);
---
> // Check for instruction-count-based events.
> comInstEventQueue[0]->serviceEvents(numInsts);
906,912d453
< uint64_t
< FullO3CPU<Impl>::readPC(unsigned tid)
< {
< return commit.readPC(tid);
< }
<
< template <class Impl>
914c455
< FullO3CPU<Impl>::setPC(Addr new_PC,unsigned tid)
---
> FullO3CPU<Impl>::removeBackInst(DynInstPtr &inst)
916,917c457
< commit.setPC(new_PC, tid);
< }
---
> DynInstPtr inst_to_delete;
919,924c459,463
< template <class Impl>
< uint64_t
< FullO3CPU<Impl>::readNextPC(unsigned tid)
< {
< return commit.readNextPC(tid);
< }
---
> // Walk through the instruction list, removing any instructions
> // that were inserted after the given instruction, inst.
> while (instList.back() != inst)
> {
> assert(!instList.empty());
926,931c465,466
< template <class Impl>
< void
< FullO3CPU<Impl>::setNextPC(uint64_t val,unsigned tid)
< {
< commit.setNextPC(val, tid);
< }
---
> // Obtain the pointer to the instruction.
> inst_to_delete = instList.back();
933,937c468,469
< template <class Impl>
< typename FullO3CPU<Impl>::ListIt
< FullO3CPU<Impl>::addInst(DynInstPtr &inst)
< {
< instList.push_back(inst);
---
> DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
> inst_to_delete->seqNum, inst_to_delete->readPC());
939,940c471,472
< return --(instList.end());
< }
---
> // Remove the instruction from the list.
> instList.pop_back();
942,953c474,476
< template <class Impl>
< void
< FullO3CPU<Impl>::instDone(unsigned tid)
< {
< // Keep an instruction count.
< thread[tid]->numInst++;
< thread[tid]->numInsts++;
< committedInsts[tid]++;
< totalCommittedInsts++;
<
< // Check for instruction-count-based events.
< comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
---
> // Mark it as squashed.
> inst_to_delete->setSquashed();
> }
958,966d480
< FullO3CPU<Impl>::addToRemoveList(DynInstPtr &inst)
< {
< removeInstsThisCycle = true;
<
< removeList.push(inst->getInstListIt());
< }
<
< template <class Impl>
< void
969,971c483
< DPRINTF(FullCPU, "FullCPU: Removing committed instruction [tid:%i] PC %#x "
< "[sn:%lli]\n",
< inst->threadNumber, inst->readPC(), inst->seqNum);
---
> DynInstPtr inst_to_remove;
973c485,486
< removeInstsThisCycle = true;
---
> // The front instruction should be the same one being asked to be removed.
> assert(instList.front() == inst);
976c489,493
< removeList.push(inst->getInstListIt());
---
> inst_to_remove = inst;
> instList.pop_front();
>
> DPRINTF(FullCPU, "FullCPU: Removing committed instruction %#x, PC %#x\n",
> inst_to_remove, inst_to_remove->readPC());
981c498
< FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid)
---
> FullO3CPU<Impl>::removeInstsNotInROB()
983,984c500,501
< DPRINTF(FullCPU, "FullCPU: Thread %i: Deleting instructions from instruction"
< " list.\n", tid);
---
> DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
> "list.\n");
986c503
< ListIt end_it;
---
> DynInstPtr rob_tail = rob.readTailInst();
988,1021c505
< bool rob_empty = false;
<
< if (instList.empty()) {
< return;
< } else if (rob.isEmpty(/*tid*/)) {
< DPRINTF(FullCPU, "FullCPU: ROB is empty, squashing all insts.\n");
< end_it = instList.begin();
< rob_empty = true;
< } else {
< end_it = (rob.readTailInst(tid))->getInstListIt();
< DPRINTF(FullCPU, "FullCPU: ROB is not empty, squashing insts not in ROB.\n");
< }
<
< removeInstsThisCycle = true;
<
< ListIt inst_it = instList.end();
<
< inst_it--;
<
< // Walk through the instruction list, removing any instructions
< // that were inserted after the given instruction iterator, end_it.
< while (inst_it != end_it) {
< assert(!instList.empty());
<
< squashInstIt(inst_it, tid);
<
< inst_it--;
< }
<
< // If the ROB was empty, then we actually need to remove the first
< // instruction as well.
< if (rob_empty) {
< squashInstIt(inst_it, tid);
< }
---
> removeBackInst(rob_tail);
1026,1027c510
< FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num,
< unsigned tid)
---
> FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num)
1029,1036d511
< assert(!instList.empty());
<
< removeInstsThisCycle = true;
<
< ListIt inst_iter = instList.end();
<
< inst_iter--;
<
1038,1039c513
< "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
< tid, seq_num, (*inst_iter)->seqNum);
---
> "list.\n");
1041c515
< while ((*inst_iter)->seqNum > seq_num) {
---
> DynInstPtr inst_to_delete;
1043c517,518
< bool break_loop = (inst_iter == instList.begin());
---
> while (instList.back()->seqNum > seq_num) {
> assert(!instList.empty());
1045c520,521
< squashInstIt(inst_iter, tid);
---
> // Obtain the pointer to the instruction.
> inst_to_delete = instList.back();
1047c523,524
< inst_iter--;
---
> DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
> inst_to_delete->seqNum, inst_to_delete->readPC());
1049,1052c526,528
< if (break_loop)
< break;
< }
< }
---
> // Remove the instruction from the list.
> instList.back() = NULL;
> instList.pop_back();
1054,1064d529
< template <class Impl>
< inline void
< FullO3CPU<Impl>::squashInstIt(const ListIt &instIt, const unsigned &tid)
< {
< if ((*instIt)->threadNumber == tid) {
< DPRINTF(FullCPU, "FullCPU: Squashing instruction, "
< "[tid:%i] [sn:%lli] PC %#x\n",
< (*instIt)->threadNumber,
< (*instIt)->seqNum,
< (*instIt)->readPC());
<
1066,1071c531
< (*instIt)->setSquashed();
<
< // @todo: Formulate a consistent method for deleting
< // instructions from the instruction list
< // Remove the instruction from the list.
< removeList.push(instIt);
---
> inst_to_delete->setSquashed();
1072a533
>
1077,1095d537
< FullO3CPU<Impl>::cleanUpRemovedInsts()
< {
< while (!removeList.empty()) {
< DPRINTF(FullCPU, "FullCPU: Removing instruction, "
< "[tid:%i] [sn:%lli] PC %#x\n",
< (*removeList.front())->threadNumber,
< (*removeList.front())->seqNum,
< (*removeList.front())->readPC());
<
< instList.erase(removeList.front());
<
< removeList.pop();
< }
<
< removeInstsThisCycle = false;
< }
< /*
< template <class Impl>
< void
1100c542
< */
---
>
1105a548
> typename list<DynInstPtr>::iterator inst_list_it = instList.begin();
1107,1116c550,554
< ListIt inst_list_it = instList.begin();
<
< cprintf("Dumping Instruction List\n");
<
< while (inst_list_it != instList.end()) {
< cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
< "Squashed:%i\n\n",
< num, (*inst_list_it)->readPC(), (*inst_list_it)->threadNumber,
< (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
< (*inst_list_it)->isSquashed());
---
> while (inst_list_it != instList.end())
> {
> cprintf("Instruction:%i\nPC:%#x\nSN:%lli\nIssued:%i\nSquashed:%i\n\n",
> num, (*inst_list_it)->readPC(), (*inst_list_it)->seqNum,
> (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed());
1121c559
< /*
---
>
1128,1136d565
< */
< template <class Impl>
< void
< FullO3CPU<Impl>::wakeCPU()
< {
< if (activityRec.active() || tickEvent.scheduled()) {
< DPRINTF(Activity, "CPU already running.\n");
< return;
< }
1138,1194d566
< DPRINTF(Activity, "Waking up CPU\n");
<
< idleCycles += (curTick - 1) - lastRunningCycle;
<
< tickEvent.schedule(curTick);
< }
<
< template <class Impl>
< int
< FullO3CPU<Impl>::getFreeTid()
< {
< for (int i=0; i < numThreads; i++) {
< if (!tids[i]) {
< tids[i] = true;
< return i;
< }
< }
<
< return -1;
< }
<
< template <class Impl>
< void
< FullO3CPU<Impl>::doContextSwitch()
< {
< if (contextSwitch) {
<
< //ADD CODE TO DEACTIVE THREAD HERE (???)
<
< for (int tid=0; tid < cpuWaitList.size(); tid++) {
< activateWhenReady(tid);
< }
<
< if (cpuWaitList.size() == 0)
< contextSwitch = true;
< }
< }
<
< template <class Impl>
< void
< FullO3CPU<Impl>::updateThreadPriority()
< {
< if (activeThreads.size() > 1)
< {
< //DEFAULT TO ROUND ROBIN SCHEME
< //e.g. Move highest priority to end of thread list
< list<unsigned>::iterator list_begin = activeThreads.begin();
< list<unsigned>::iterator list_end = activeThreads.end();
<
< unsigned high_thread = *list_begin;
<
< activeThreads.erase(list_begin);
<
< activeThreads.push_back(high_thread);
< }
< }
<