2c2
< * Copyright (c) 2004-2005 The Regents of The University of Michigan
---
> * Copyright (c) 2004-2006 The Regents of The University of Michigan
27,28d26
< *
< * Authors: Kevin Lim
38d35
< #include "sim/root.hh"
39a37,38
> #include "cpu/activity.hh"
> #include "cpu/checker/cpu.hh"
45a45,47
> #include "sim/root.hh"
> #include "sim/stat_control.hh"
>
46a49
> using namespace TheISA;
48,49c51,52
< BaseFullCPU::BaseFullCPU(Params &params)
< : BaseCPU(&params), cpu_id(0)
---
> BaseFullCPU::BaseFullCPU(Params *params)
> : BaseCPU(params), cpu_id(0)
52a56,61
> void
> BaseFullCPU::regStats()
> {
> BaseCPU::regStats();
> }
>
73d81
< //Call constructor to all the pipeline stages here
75,76c83
< FullO3CPU<Impl>::FullO3CPU(Params &params)
< #if FULL_SYSTEM
---
> FullO3CPU<Impl>::FullO3CPU(Params *params)
78,80d84
< #else
< : BaseFullCPU(params),
< #endif // FULL_SYSTEM
81a86
> removeInstsThisCycle(false),
88c93
< regFile(params.numPhysIntRegs, params.numPhysFloatRegs),
---
> regFile(params->numPhysIntRegs, params->numPhysFloatRegs),
90,91c95,97
< freeList(TheISA::NumIntRegs, params.numPhysIntRegs,
< TheISA::NumFloatRegs, params.numPhysFloatRegs),
---
> freeList(params->numberOfThreads,//number of activeThreads
> TheISA::NumIntRegs, params->numPhysIntRegs,
> TheISA::NumFloatRegs, params->numPhysFloatRegs),
93,97c99,101
< renameMap(TheISA::NumIntRegs, params.numPhysIntRegs,
< TheISA::NumFloatRegs, params.numPhysFloatRegs,
< TheISA::NumMiscRegs,
< TheISA::ZeroReg,
< TheISA::ZeroReg + TheISA::NumIntRegs),
---
> rob(params->numROBEntries, params->squashWidth,
> params->smtROBPolicy, params->smtROBThreshold,
> params->numberOfThreads),
99c103,107
< rob(params.numROBEntries, params.squashWidth),
---
> scoreboard(params->numberOfThreads,//number of activeThreads
> TheISA::NumIntRegs, params->numPhysIntRegs,
> TheISA::NumFloatRegs, params->numPhysFloatRegs,
> TheISA::NumMiscRegs * number_of_threads,
> TheISA::ZeroReg),
101d108
< // What to pass to these time buffers?
102a110,111
> // @todo: Make these time buffer sizes parameters or derived
> // from latencies
107a117
> activityRec(NumStages, 10, params->activity),
109,110d118
< cpuXC(NULL),
<
114c122
< system(params.system),
---
> system(params->system),
117,122d124
< itb(params.itb),
< dtb(params.dtb),
< mem(params.mem),
< #else
< // Hardcoded for a single thread!!
< mem(params.workload[0]->getMemory()),
124,129c126,129
<
< icacheInterface(params.icacheInterface),
< dcacheInterface(params.dcacheInterface),
< deferRegistration(params.defReg),
< numInsts(0),
< funcExeInst(0)
---
> mem(params->mem),
> switchCount(0),
> deferRegistration(params->deferRegistration),
> numThreads(number_of_threads)
133,137c133,136
< #if !FULL_SYSTEM
< thread.resize(this->number_of_threads);
< #endif
<
< for (int i = 0; i < this->number_of_threads; ++i) {
---
> if (params->checker) {
> BaseCPU *temp_checker = params->checker;
> checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
> checker->setMemory(mem);
139,154c138,141
< assert(i == 0);
< thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem);
< system->execContexts[i] = thread[i]->getProxy();
<
< 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
---
> checker->setSystem(params->system);
> #endif
> } else {
> checker = NULL;
157,159c144,147
< // 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];
---
> #if !FULL_SYSTEM
> thread.resize(number_of_threads);
> tids.resize(number_of_threads);
> #endif
161,163c149,151
< // 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.
---
> // 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.
164a153,159
> // 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);
>
174a170
> commit.setFetchQueue(&fetchQueue);
182a179,196
> 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);
>
184,185c198,199
< rename.setRenameMap(&renameMap);
< iew.setRenameMap(&renameMap);
---
> PhysRegIndex lreg_idx = 0;
> PhysRegIndex freg_idx = params->numPhysIntRegs; //Index to 1 after int regs
187c201,243
< // Setup the free list for whichever stages need it.
---
> 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);
> }
189d244
< renameMap.setFreeList(&freeList);
190a246,251
> // Setup the page table for whichever stages need it.
> #if !FULL_SYSTEM
> // fetch.setPageTable(pTable);
> // iew.setPageTable(pTable);
> #endif
>
192a254,257
>
> lastRunningCycle = curTick;
>
> contextSwitch = false;
203a269,270
> BaseFullCPU::regStats();
>
204a272,320
> 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;
>
213,215c329,333
< //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.
---
> ++numCycles;
>
> // activity = false;
>
> //Tick each of the stages
226c344,348
< // Now advance the time buffers, unless the stage is stalled.
---
> #if !FULL_SYSTEM
> doContextSwitch();
> #endif
>
> // Now advance the time buffers
234,235c356,377
< if (_status == Running && !tickEvent.scheduled())
< tickEvent.schedule(curTick + 1);
---
> 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
>
242,244c384,386
< if(!deferRegistration)
< {
< this->registerExecContexts();
---
> if (!deferRegistration) {
> registerExecContexts();
> }
246,247c388,393
< // Need to do a copy of the xc->regs into the CPU's regfile so
< // that it can start properly.
---
> // 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++) {
249,250c395
< ExecContext *src_xc = system->execContexts[0];
< TheISA::initCPU(src_xc, src_xc->readCpuId());
---
> ExecContext *src_xc = execContexts[tid];
252c397
< ExecContext *src_xc = thread[0]->getProxy();
---
> ExecContext *src_xc = thread[tid]->getXCProxy();
254,257c399,401
< // First loop through the integer registers.
< for (int i = 0; i < TheISA::NumIntRegs; ++i)
< {
< regFile.intRegFile[i] = src_xc->readIntReg(i);
---
> // Threads start in the Suspended State
> if (src_xc->status() != ExecContext::Suspended) {
> continue;
260,274c404,406
< // 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();
---
> #if FULL_SYSTEM
> TheISA::initCPU(src_xc, src_xc->readCpuId());
> #endif
275a408,419
>
> // 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);
280c424
< FullO3CPU<Impl>::activateContext(int thread_num, int delay)
---
> FullO3CPU<Impl>::insertThread(unsigned tid)
281a426,575
> 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)
> {
282a577,578
> list<unsigned>::iterator isActive = find(
> activeThreads.begin(), activeThreads.end(), tid);
283a580,590
> 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);
>
285a593,597
> // Be sure to signal that there's some activity so the CPU doesn't
> // deschedule itself.
> activityRec.activity();
> fetch.wakeFromQuiesce();
>
291c603
< FullO3CPU<Impl>::suspendContext(int thread_num)
---
> FullO3CPU<Impl>::suspendContext(int tid)
293c605,618
< panic("suspendContext unimplemented!");
---
> 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);
> }
> */
298c623
< FullO3CPU<Impl>::deallocateContext(int thread_num)
---
> FullO3CPU<Impl>::deallocateContext(int tid)
300c625,638
< panic("deallocateContext unimplemented!");
---
> 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);
> }
> */
305c643
< FullO3CPU<Impl>::haltContext(int thread_num)
---
> FullO3CPU<Impl>::haltContext(int tid)
307c645,658
< panic("haltContext unimplemented!");
---
> 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);
> }
> */
312c663
< FullO3CPU<Impl>::switchOut()
---
> FullO3CPU<Impl>::switchOut(Sampler *_sampler)
314c665,676
< panic("FullO3CPU does not have a switch out function.\n");
---
> 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();
318a681,704
> 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
320a707,717
> // 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();
>
322a720,725
> fetch.takeOverFrom();
> decode.takeOverFrom();
> rename.takeOverFrom();
> iew.takeOverFrom();
> commit.takeOverFrom();
>
325,326c728,745
< // Set all status's to active, schedule the
< // CPU's tick event.
---
> // @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
333a753,754
> if (!tickEvent.scheduled())
> tickEvent.schedule(curTick);
337,344d757
< InstSeqNum
< FullO3CPU<Impl>::getAndIncrementInstSeq()
< {
< // Hopefully this works right.
< return globalSeqNum++;
< }
<
< template <class Impl>
416c829
< FullO3CPU<Impl>::readPC()
---
> FullO3CPU<Impl>::readArchIntReg(int reg_idx, unsigned tid)
418c831,833
< return regFile.readPC();
---
> PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
>
> return regFile.readIntReg(phys_reg);
421a837,866
> 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.readFloatReg(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.readFloatReg(phys_reg, 64);
> }
>
> 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.readFloatRegBits(phys_reg);
> }
>
> template <class Impl>
423c868
< FullO3CPU<Impl>::setNextPC(uint64_t val)
---
> FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, unsigned tid)
425c870,872
< regFile.setNextPC(val);
---
> PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
>
> regFile.setIntReg(phys_reg, val);
430c877
< FullO3CPU<Impl>::setPC(Addr new_PC)
---
> FullO3CPU<Impl>::setArchFloatRegSingle(int reg_idx, float val, unsigned tid)
432c879,881
< regFile.setPC(new_PC);
---
> PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
>
> regFile.setFloatReg(phys_reg, val);
437c886
< FullO3CPU<Impl>::addInst(DynInstPtr &inst)
---
> FullO3CPU<Impl>::setArchFloatRegDouble(int reg_idx, double val, unsigned tid)
439c888,890
< instList.push_back(inst);
---
> PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
>
> regFile.setFloatReg(phys_reg, val, 64);
444c895
< FullO3CPU<Impl>::instDone()
---
> FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid)
446,447c897
< // Keep an instruction count.
< numInsts++;
---
> PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
449,450c899
< // Check for instruction-count-based events.
< comInstEventQueue[0]->serviceEvents(numInsts);
---
> regFile.setFloatRegBits(phys_reg, val);
453a903,909
> uint64_t
> FullO3CPU<Impl>::readPC(unsigned tid)
> {
> return commit.readPC(tid);
> }
>
> template <class Impl>
455c911
< FullO3CPU<Impl>::removeBackInst(DynInstPtr &inst)
---
> FullO3CPU<Impl>::setPC(Addr new_PC,unsigned tid)
457c913,914
< DynInstPtr inst_to_delete;
---
> commit.setPC(new_PC, tid);
> }
459,463c916,921
< // Walk through the instruction list, removing any instructions
< // that were inserted after the given instruction, inst.
< while (instList.back() != inst)
< {
< assert(!instList.empty());
---
> template <class Impl>
> uint64_t
> FullO3CPU<Impl>::readNextPC(unsigned tid)
> {
> return commit.readNextPC(tid);
> }
465,466c923,928
< // Obtain the pointer to the instruction.
< inst_to_delete = instList.back();
---
> template <class Impl>
> void
> FullO3CPU<Impl>::setNextPC(uint64_t val,unsigned tid)
> {
> commit.setNextPC(val, tid);
> }
468,469c930,934
< DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
< inst_to_delete->seqNum, inst_to_delete->readPC());
---
> template <class Impl>
> typename FullO3CPU<Impl>::ListIt
> FullO3CPU<Impl>::addInst(DynInstPtr &inst)
> {
> instList.push_back(inst);
471,472c936,937
< // Remove the instruction from the list.
< instList.pop_back();
---
> return --(instList.end());
> }
474,476c939,950
< // Mark it as squashed.
< inst_to_delete->setSquashed();
< }
---
> 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);
480a955,963
> FullO3CPU<Impl>::addToRemoveList(DynInstPtr &inst)
> {
> removeInstsThisCycle = true;
>
> removeList.push(inst->getInstListIt());
> }
>
> template <class Impl>
> void
483c966,968
< DynInstPtr inst_to_remove;
---
> DPRINTF(FullCPU, "FullCPU: Removing committed instruction [tid:%i] PC %#x "
> "[sn:%lli]\n",
> inst->threadNumber, inst->readPC(), inst->seqNum);
485,486c970
< // The front instruction should be the same one being asked to be removed.
< assert(instList.front() == inst);
---
> removeInstsThisCycle = true;
489,493c973
< inst_to_remove = inst;
< instList.pop_front();
<
< DPRINTF(FullCPU, "FullCPU: Removing committed instruction %#x, PC %#x\n",
< inst_to_remove, inst_to_remove->readPC());
---
> removeList.push(inst->getInstListIt());
498c978
< FullO3CPU<Impl>::removeInstsNotInROB()
---
> FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid)
500,501c980,981
< DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
< "list.\n");
---
> DPRINTF(FullCPU, "FullCPU: Thread %i: Deleting instructions from instruction"
> " list.\n", tid);
503c983
< DynInstPtr rob_tail = rob.readTailInst();
---
> ListIt end_it;
505c985,1018
< removeBackInst(rob_tail);
---
> 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);
> }
510c1023,1024
< FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num)
---
> FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num,
> unsigned tid)
511a1026,1033
> assert(!instList.empty());
>
> removeInstsThisCycle = true;
>
> ListIt inst_iter = instList.end();
>
> inst_iter--;
>
513c1035,1036
< "list.\n");
---
> "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
> tid, seq_num, (*inst_iter)->seqNum);
515c1038
< DynInstPtr inst_to_delete;
---
> while ((*inst_iter)->seqNum > seq_num) {
517,518c1040
< while (instList.back()->seqNum > seq_num) {
< assert(!instList.empty());
---
> bool break_loop = (inst_iter == instList.begin());
520,521c1042
< // Obtain the pointer to the instruction.
< inst_to_delete = instList.back();
---
> squashInstIt(inst_iter, tid);
523,524c1044
< DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
< inst_to_delete->seqNum, inst_to_delete->readPC());
---
> inst_iter--;
526,528c1046,1049
< // Remove the instruction from the list.
< instList.back() = NULL;
< instList.pop_back();
---
> if (break_loop)
> break;
> }
> }
529a1051,1061
> 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());
>
531,532c1063
< inst_to_delete->setSquashed();
< }
---
> (*instIt)->setSquashed();
533a1065,1069
> // @todo: Formulate a consistent method for deleting
> // instructions from the instruction list
> // Remove the instruction from the list.
> removeList.push(instIt);
> }
537a1074,1092
> 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
542c1097
<
---
> */
548d1102
< typename list<DynInstPtr>::iterator inst_list_it = instList.begin();
550,554c1104,1113
< 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());
---
> 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());
559c1118
<
---
> /*
565a1125,1133
> */
> template <class Impl>
> void
> FullO3CPU<Impl>::wakeCPU()
> {
> if (activityRec.active() || tickEvent.scheduled()) {
> DPRINTF(Activity, "CPU already running.\n");
> return;
> }
566a1135,1191
> 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);
> }
> }
>