From ff3d16ca1f7d83ce7932868d2bf1cb3e526562ea Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 23 May 2006 16:51:16 -0400 Subject: Move kernel stats out of CPU and into XC. arch/alpha/ev5.cc: Move kernel stats out of CPU and into XC. Also be sure to check if the kernel stats exist prior to using them. --HG-- extra : convert_revision : 565cd7026410fd7d8586f953d9b328c2e67a9473 --- cpu/base.cc | 23 ----- cpu/base.hh | 10 +-- cpu/checker/exec_context.hh | 44 +++++++-- cpu/cpu_exec_context.cc | 9 +- cpu/cpu_exec_context.hh | 7 ++ cpu/exec_context.hh | 7 ++ cpu/o3/alpha_cpu.hh | 11 +-- cpu/o3/alpha_cpu_impl.hh | 62 +++++++++---- cpu/ozone/cpu.hh | 28 ++---- cpu/ozone/cpu_impl.hh | 211 +++++++------------------------------------- cpu/simple/cpu.cc | 2 +- cpu/thread_state.hh | 39 +++++++- 12 files changed, 192 insertions(+), 261 deletions(-) (limited to 'cpu') diff --git a/cpu/base.cc b/cpu/base.cc index 74b679d5d..de03b9eab 100644 --- a/cpu/base.cc +++ b/cpu/base.cc @@ -45,10 +45,6 @@ #include "base/trace.hh" -#if FULL_SYSTEM -#include "kern/kernel_stats.hh" -#endif - using namespace std; vector BaseCPU::cpuList; @@ -153,8 +149,6 @@ BaseCPU::BaseCPU(Params *p) profileEvent = NULL; if (params->profile) profileEvent = new ProfileEvent(this, params->profile); - - kernelStats = new Kernel::Statistics(system); #endif } @@ -175,10 +169,6 @@ BaseCPU::enableFunctionTrace() BaseCPU::~BaseCPU() { -#if FULL_SYSTEM - if (kernelStats) - delete kernelStats; -#endif } void @@ -219,8 +209,6 @@ BaseCPU::regStats() execContexts[0]->regStats(name()); #if FULL_SYSTEM - if (kernelStats) - kernelStats->regStats(name() + ".kern"); #endif } @@ -348,12 +336,6 @@ BaseCPU::serialize(std::ostream &os) { SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); SERIALIZE_SCALAR(intstatus); - -#if FULL_SYSTEM - if (kernelStats) - kernelStats->serialize(os); -#endif - } void @@ -361,11 +343,6 @@ BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); UNSERIALIZE_SCALAR(intstatus); - -#if FULL_SYSTEM - if (kernelStats) - kernelStats->unserialize(cp, section); -#endif } #endif // FULL_SYSTEM diff --git a/cpu/base.hh b/cpu/base.hh index 20166d7ee..dd776859d 100644 --- a/cpu/base.hh +++ b/cpu/base.hh @@ -38,14 +38,10 @@ #include "sim/sim_object.hh" #include "arch/isa_traits.hh" -#if FULL_SYSTEM -class System; -namespace Kernel { class Statistics; } -#endif - class BranchPred; class CheckerCPU; class ExecContext; +class System; class BaseCPU : public SimObject { @@ -237,10 +233,6 @@ class BaseCPU : public SimObject public: // Number of CPU cycles simulated Stats::Scalar<> numCycles; - -#if FULL_SYSTEM - Kernel::Statistics *kernelStats; -#endif }; #endif // __CPU_BASE_HH__ diff --git a/cpu/checker/exec_context.hh b/cpu/checker/exec_context.hh index 4843d1cf0..38784867d 100644 --- a/cpu/checker/exec_context.hh +++ b/cpu/checker/exec_context.hh @@ -1,3 +1,31 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #ifndef __CPU_CHECKER_EXEC_CONTEXT_HH__ #define __CPU_CHECKER_EXEC_CONTEXT_HH__ @@ -6,6 +34,9 @@ #include "cpu/exec_context.hh" class EndQuiesceEvent; +namespace Kernel { + class Statistics; +}; template class CheckerExecContext : public ExecContext @@ -13,7 +44,8 @@ class CheckerExecContext : public ExecContext public: CheckerExecContext(XC *actual_xc, CheckerCPU *checker_cpu) - : actualXC(actual_xc), checkerXC(checker_cpu->cpuXC), checkerCPU(checker_cpu) + : actualXC(actual_xc), checkerXC(checker_cpu->cpuXC), + checkerCPU(checker_cpu) { } private: @@ -43,6 +75,8 @@ class CheckerExecContext : public ExecContext AlphaITB *getITBPtr() { return actualXC->getITBPtr(); } AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); } + + Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); } #else Process *getProcessPtr() { return actualXC->getProcessPtr(); } #endif @@ -50,8 +84,10 @@ class CheckerExecContext : public ExecContext Status status() const { return actualXC->status(); } void setStatus(Status new_status) - { actualXC->setStatus(new_status); - checkerXC->setStatus(new_status); } + { + actualXC->setStatus(new_status); + checkerXC->setStatus(new_status); + } /// Set the status to Active. Optional delay indicates number of /// cycles to wait before beginning execution. @@ -216,8 +252,6 @@ class CheckerExecContext : public ExecContext actualXC->setSyscallReturn(return_value); } -// void syscall() { actualXC->syscall(); } - Counter readFuncExeInst() { return actualXC->readFuncExeInst(); } #endif }; diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc index 24de6d450..78ce058e8 100644 --- a/cpu/cpu_exec_context.cc +++ b/cpu/cpu_exec_context.cc @@ -188,7 +188,8 @@ CPUExecContext::serialize(ostream &os) if (quiesceEvent->scheduled()) quiesceEndTick = quiesceEvent->when(); SERIALIZE_SCALAR(quiesceEndTick); - + if (kernelStats) + kernelStats->serialize(os); #endif } @@ -207,6 +208,8 @@ CPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(quiesceEndTick); if (quiesceEndTick) quiesceEvent->schedule(quiesceEndTick); + if (kernelStats) + kernelStats->unserialize(cp, section); #endif } @@ -275,6 +278,10 @@ CPUExecContext::halt() void CPUExecContext::regStats(const string &name) { +#if FULL_SYSTEM + kernelStats = new Kernel::Statistics(system); + kernelStats->regStats(name + ".kern"); +#endif } void diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh index cac006925..3d1428933 100644 --- a/cpu/cpu_exec_context.hh +++ b/cpu/cpu_exec_context.hh @@ -53,6 +53,10 @@ class FunctionProfile; class ProfileNode; class MemoryController; +namespace Kernel { + class Statistics; +}; + #else // !FULL_SYSTEM #include "sim/process.hh" @@ -147,6 +151,9 @@ class CPUExecContext void profileSample(); + Kernel::Statistics *getKernelStats() { return kernelStats; } + + Kernel::Statistics *kernelStats; #else Process *process; diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 7bd7d5682..e1f1016e5 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -48,6 +48,9 @@ class FunctionalMemory; class PhysicalMemory; class Process; class System; +namespace Kernel { + class Statistics; +}; class ExecContext { @@ -98,6 +101,8 @@ class ExecContext virtual AlphaITB *getITBPtr() = 0; virtual AlphaDTB * getDTBPtr() = 0; + + virtual Kernel::Statistics *getKernelStats() = 0; #else virtual Process *getProcessPtr() = 0; #endif @@ -243,6 +248,8 @@ class ProxyExecContext : public ExecContext AlphaITB *getITBPtr() { return actualXC->getITBPtr(); } AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); } + + Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); } #else Process *getProcessPtr() { return actualXC->getProcessPtr(); } #endif diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index 78ad5f7d8..5c89e3462 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -35,6 +35,9 @@ #include "sim/byteswap.hh" class EndQuiesceEvent; +namespace Kernel { + class Statistics; +}; template class AlphaFullCPU : public FullO3CPU @@ -60,11 +63,6 @@ class AlphaFullCPU : public FullO3CPU O3ThreadState *thread; - Tick lastActivate; - Tick lastSuspend; - - EndQuiesceEvent *quiesceEvent; - virtual BaseCPU *getCpuPtr() { return cpu; } virtual void setCpuId(int id) { cpu->cpu_id = id; } @@ -81,6 +79,9 @@ class AlphaFullCPU : public FullO3CPU virtual AlphaITB *getITBPtr() { return cpu->itb; } virtual AlphaDTB * getDTBPtr() { return cpu->dtb; } + + virtual Kernel::Statistics *getKernelStats() + { return thread->kernelStats; } #else virtual Process *getProcessPtr() { return thread->process; } #endif diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 58b2b3548..91cd3d9e6 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -31,7 +31,6 @@ #include "base/statistics.hh" #include "base/timebuf.hh" #include "cpu/checker/exec_context.hh" -#include "cpu/quiesce_event.hh" #include "mem/mem_interface.hh" #include "sim/sim_events.hh" #include "sim/stats.hh" @@ -44,6 +43,8 @@ #if FULL_SYSTEM #include "arch/alpha/osfpal.hh" #include "arch/isa_traits.hh" +#include "cpu/quiesce_event.hh" +#include "kern/kernel_stats.hh" #endif using namespace TheISA; @@ -101,11 +102,12 @@ AlphaFullCPU::AlphaFullCPU(Params *params) alpha_xc_proxy->cpu = this; alpha_xc_proxy->thread = this->thread[i]; - alpha_xc_proxy->quiesceEvent = +#if FULL_SYSTEM + this->thread[i]->quiesceEvent = new EndQuiesceEvent(xc_proxy); - alpha_xc_proxy->lastActivate = 0; - alpha_xc_proxy->lastSuspend = 0; - + this->thread[i]->lastActivate = 0; + this->thread[i]->lastSuspend = 0; +#endif this->thread[i]->xcProxy = xc_proxy; this->execContexts.push_back(xc_proxy); @@ -181,6 +183,9 @@ AlphaFullCPU::AlphaXC::takeOverFrom(ExecContext *old_context) if (thread->quiesceEvent) { thread->quiesceEvent->xc = this; } + + // Transfer kernel stats from one CPU to the other. + thread->kernelStats = old_context->getKernelStats(); // storeCondFailures = 0; cpu->lockFlag = false; #endif @@ -200,7 +205,9 @@ AlphaFullCPU::AlphaXC::activate(int delay) if (thread->status() == ExecContext::Active) return; - lastActivate = curTick; +#if FULL_SYSTEM + thread->lastActivate = curTick; +#endif if (thread->status() == ExecContext::Unallocated) { cpu->activateWhenReady(thread->tid); @@ -222,8 +229,10 @@ AlphaFullCPU::AlphaXC::suspend() if (thread->status() == ExecContext::Suspended) return; - lastActivate = curTick; - lastSuspend = curTick; +#if FULL_SYSTEM + thread->lastActivate = curTick; + thread->lastSuspend = curTick; +#endif /* #if FULL_SYSTEM // Don't change the status from active if there are pending interrupts @@ -266,38 +275,55 @@ AlphaFullCPU::AlphaXC::halt() template void AlphaFullCPU::AlphaXC::regStats(const std::string &name) -{} +{ +#if FULL_SYSTEM + thread->kernelStats = new Kernel::Statistics(cpu->system); + thread->kernelStats->regStats(name + ".kern"); +#endif +} template void AlphaFullCPU::AlphaXC::serialize(std::ostream &os) -{} +{ +#if FULL_SYSTEM + if (thread->kernelStats) + thread->kernelStats->serialize(os); +#endif + +} template void AlphaFullCPU::AlphaXC::unserialize(Checkpoint *cp, const std::string §ion) -{} +{ +#if FULL_SYSTEM + if (thread->kernelStats) + thread->kernelStats->unserialize(cp, section); +#endif + +} #if FULL_SYSTEM template EndQuiesceEvent * AlphaFullCPU::AlphaXC::getQuiesceEvent() { - return quiesceEvent; + return thread->quiesceEvent; } template Tick AlphaFullCPU::AlphaXC::readLastActivate() { - return lastActivate; + return thread->lastActivate; } template Tick AlphaFullCPU::AlphaXC::readLastSuspend() { - return lastSuspend; + return thread->lastSuspend; } template @@ -595,7 +621,7 @@ AlphaFullCPU::hwrei(unsigned tid) // Need to clear the lock flag upon returning from an interrupt. this->lockFlag = false; - this->kernelStats->hwrei(); + this->thread[tid]->kernelStats->hwrei(); this->checkInterrupts = true; @@ -607,9 +633,9 @@ template bool AlphaFullCPU::simPalCheck(int palFunc, unsigned tid) { - if (this->kernelStats) - this->kernelStats->callpal(palFunc, - this->execContexts[tid]); + if (this->thread[tid]->kernelStats) + this->thread[tid]->kernelStats->callpal(palFunc, + this->execContexts[tid]); switch (palFunc) { case PAL::halt: diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh index 7e12e75e5..5af2b02b2 100644 --- a/cpu/ozone/cpu.hh +++ b/cpu/ozone/cpu.hh @@ -57,6 +57,10 @@ class Sampler; class RemoteGDB; class GDBListener; +namespace Kernel { + class Statistics; +}; + #else class Process; @@ -116,6 +120,8 @@ class OzoneCPU : public BaseCPU AlphaITB *getITBPtr() { return cpu->itb; } AlphaDTB * getDTBPtr() { return cpu->dtb; } + + Kernel::Statistics *getKernelStats() { return thread->kernelStats; } #else Process *getProcessPtr() { return thread->process; } #endif @@ -238,14 +244,7 @@ class OzoneCPU : public BaseCPU private: OzoneThreadState thread; -/* - // Squash event for when the XC needs to squash all inflight instructions. - struct XCSquashEvent : public Event - { - void process(); - const char *description(); - }; -*/ + public: // main simulation loop (one cycle) void tick(); @@ -288,7 +287,6 @@ class OzoneCPU : public BaseCPU void trace_data(T data); public: - // enum Status { Running, Idle, @@ -325,8 +323,6 @@ class OzoneCPU : public BaseCPU int readCpuId() { return cpuId; } -// FunctionalMemory *getMemPtr() { return mem; } - int cpuId; void switchOut(Sampler *sampler); @@ -369,8 +365,6 @@ class OzoneCPU : public BaseCPU Status status() const { return _status; } void setStatus(Status new_status) { _status = new_status; } - // Not sure what an activate() call on the CPU's proxy XC would mean... - virtual void activateContext(int thread_num, int delay); virtual void suspendContext(int thread_num); virtual void deallocateContext(int thread_num); @@ -384,7 +378,6 @@ class OzoneCPU : public BaseCPU public: Counter numInst; Counter startNumInst; -// Stats::Scalar<> numInsts; virtual Counter totalInstructions() const { @@ -392,9 +385,6 @@ class OzoneCPU : public BaseCPU } private: - // number of simulated memory references -// Stats::Scalar<> numMemRefs; - // number of simulated loads Counter numLoad; Counter startNumLoad; @@ -472,7 +462,6 @@ class OzoneCPU : public BaseCPU template Fault read(MemReqPtr &req, T &data) { -// panic("CPU READ NOT IMPLEMENTED W/NEW MEMORY\n"); #if 0 #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { @@ -483,7 +472,6 @@ class OzoneCPU : public BaseCPU #endif Fault error; if (req->flags & LOCKED) { -// lockAddr = req->paddr; lockAddrList.insert(req->paddr); lockFlag = true; } @@ -558,7 +546,7 @@ class OzoneCPU : public BaseCPU if (req->flags & UNCACHEABLE) { req->result = 2; } else { - if (this->lockFlag/* && this->lockAddr == req->paddr*/) { + if (this->lockFlag) { if (lockAddrList.find(req->paddr) != lockAddrList.end()) { req->result = 1; diff --git a/cpu/ozone/cpu_impl.hh b/cpu/ozone/cpu_impl.hh index 031b4b145..5675da3a8 100644 --- a/cpu/ozone/cpu_impl.hh +++ b/cpu/ozone/cpu_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 The Regents of The University of Michigan + * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include +//#include +//#include #include "arch/isa_traits.hh" // For MachInst #include "base/trace.hh" @@ -39,7 +39,7 @@ #include "cpu/ozone/cpu.hh" #include "cpu/quiesce_event.hh" #include "cpu/static_inst.hh" -#include "mem/base_mem.hh" +//#include "mem/base_mem.hh" #include "mem/mem_interface.hh" #include "sim/sim_object.hh" #include "sim/stats.hh" @@ -50,7 +50,7 @@ #include "arch/alpha/tlb.hh" #include "arch/vtophys.hh" #include "base/callback.hh" -#include "base/remote_gdb.hh" +//#include "base/remote_gdb.hh" #include "cpu/profile.hh" #include "kern/kernel_stats.hh" #include "mem/functional/memory_control.hh" @@ -94,80 +94,26 @@ OzoneCPU::TickEvent::description() { return "OzoneCPU tick event"; } -/* -template -OzoneCPU::ICacheCompletionEvent::ICacheCompletionEvent(OzoneCPU *_cpu) - : Event(&mainEventQueue), - cpu(_cpu) -{ -} - -template -void -OzoneCPU::ICacheCompletionEvent::process() -{ - cpu->processICacheCompletion(); -} - -template -const char * -OzoneCPU::ICacheCompletionEvent::description() -{ - return "OzoneCPU I-cache completion event"; -} - -template -OzoneCPU::DCacheCompletionEvent:: -DCacheCompletionEvent(OzoneCPU *_cpu, - DynInstPtr &_inst, - DCacheCompEventIt &_dcceIt) - : Event(&mainEventQueue), - cpu(_cpu), - inst(_inst), - dcceIt(_dcceIt) -{ - this->setFlags(Event::AutoDelete); -} - -template -void -OzoneCPU::DCacheCompletionEvent::process() -{ - inst->setCompleted(); - - // Maybe remove the EA from the list of addrs? - cpu->eaList.clearAddr(inst->seqNum, inst->getEA()); - cpu->dCacheCompList.erase(this->dcceIt); -} -template -const char * -OzoneCPU::DCacheCompletionEvent::description() -{ - return "OzoneCPU D-cache completion event"; -} -*/ template OzoneCPU::OzoneCPU(Params *p) #if FULL_SYSTEM - : BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width), mem(p->mem), + : BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width), + mem(p->mem), #else : BaseCPU(p), thread(this, 0, p->workload[0], 0), tickEvent(this, p->width), mem(p->workload[0]->getMemory()), #endif comm(5, 5) { - if (p->checker) { - BaseCPU *temp_checker = p->checker; - checker = dynamic_cast *>(temp_checker); - } else { - checker = NULL; - } frontEnd = new FrontEnd(p); backEnd = new BackEnd(p); _status = Idle; - if (checker) { + + if (p->checker) { + BaseCPU *temp_checker = p->checker; + checker = dynamic_cast *>(temp_checker); checker->setMemory(mem); #if FULL_SYSTEM checker->setSystem(p->system); @@ -176,19 +122,18 @@ OzoneCPU::OzoneCPU(Params *p) thread.xcProxy = checkerXC; xcProxy = checkerXC; } else { + checker = NULL; thread.xcProxy = &ozoneXC; xcProxy = &ozoneXC; } - thread.inSyscall = false; - ozoneXC.cpu = this; ozoneXC.thread = &thread; + thread.inSyscall = false; + thread.setStatus(ExecContext::Suspended); #if FULL_SYSTEM -// xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); - /***** All thread state stuff *****/ thread.cpu = this; thread.tid = 0; @@ -217,31 +162,15 @@ OzoneCPU::OzoneCPU(Params *p) thread.profileNode = &dummyNode; thread.profilePC = 3; #else -// xc = new ExecContext(this, /* thread_num */ 0, p->workload[0], /* asid */ 0); thread.cpu = this; thread.tid = 0; thread.process = p->workload[0]; -// thread.mem = thread.process->getMemory(); thread.asid = 0; #endif // !FULL_SYSTEM -/* - icacheInterface = p->icache_interface; - dcacheInterface = p->dcache_interface; - - cacheMemReq = new MemReq(); - cacheMemReq->xc = xc; - cacheMemReq->asid = 0; - cacheMemReq->data = new uint8_t[64]; -*/ + numInst = 0; startNumInst = 0; -/* numLoad = 0; - startNumLoad = 0; - lastIcacheStall = 0; - lastDcacheStall = 0; - issueWidth = p->issueWidth; -*/ execContexts.push_back(xcProxy); frontEnd->setCPU(this); @@ -286,47 +215,7 @@ template OzoneCPU::~OzoneCPU() { } -/* -template -void -OzoneCPU::copyFromXC() -{ - for (int i = 0; i < TheISA::TotalNumRegs; ++i) { - if (i < TheISA::NumIntRegs) { - renameTable[i]->setIntResult(xc->readIntReg(i)); - } else if (i < TheISA::NumFloatRegs) { - renameTable[i]->setDoubleResult(xc->readFloatRegDouble(i)); - } - } - - DPRINTF(OzoneCPU, "Func Exe inst is: %i\n", xc->func_exe_inst); - backEnd->funcExeInst = xc->func_exe_inst; -// PC = xc->readPC(); -// nextPC = xc->regs.npc; -} - -template -void -OzoneCPU::copyToXC() -{ - for (int i = 0; i < TheISA::TotalNumRegs; ++i) { - if (i < TheISA::NumIntRegs) { - xc->setIntReg(i, renameTable[i]->readIntResult()); - } else if (i < TheISA::NumFloatRegs) { - xc->setFloatRegDouble(i, renameTable[i]->readDoubleResult()); - } - } - - this->xc->regs.miscRegs.fpcr = this->regFile.miscRegs[tid].fpcr; - this->xc->regs.miscRegs.uniq = this->regFile.miscRegs[tid].uniq; - this->xc->regs.miscRegs.lock_flag = this->regFile.miscRegs[tid].lock_flag; - this->xc->regs.miscRegs.lock_addr = this->regFile.miscRegs[tid].lock_addr; - xc->func_exe_inst = backEnd->funcExeInst; - xc->regs.pc = PC; - xc->regs.npc = nextPC; -} -*/ template void OzoneCPU::switchOut(Sampler *_sampler) @@ -394,7 +283,6 @@ OzoneCPU::activateContext(int thread_num, int delay) { // Eventually change this in SMT. assert(thread_num == 0); -// assert(xcProxy); assert(_status == Idle); notIdleFraction++; @@ -410,8 +298,8 @@ OzoneCPU::suspendContext(int thread_num) { // Eventually change this in SMT. assert(thread_num == 0); -// assert(xcProxy); - // @todo: Figure out how to initially set the status properly so this is running. + // @todo: Figure out how to initially set the status properly so + // this is running. // assert(_status == Running); notIdleFraction--; unscheduleTickEvent(); @@ -486,14 +374,7 @@ void OzoneCPU::init() { BaseCPU::init(); -/* - copyFromXC(); - // ALso copy over PC/nextPC. This isn't normally copied in "copyFromXC()" - // so that the XC doesn't mess up the PC when returning from a syscall. - PC = xc->readPC(); - nextPC = xc->regs.npc; -*/ // Mark this as in syscall so it won't need to squash thread.inSyscall = true; #if FULL_SYSTEM @@ -514,8 +395,6 @@ template void OzoneCPU::serialize(std::ostream &os) { - // At this point, all DCacheCompEvents should be processed. - BaseCPU::serialize(os); SERIALIZE_ENUM(_status); nameOut(os, csprintf("%s.xc", name())); @@ -631,31 +510,7 @@ OzoneCPU::dbg_vtophys(Addr addr) return vtophys(xcProxy, addr); } #endif // FULL_SYSTEM -/* -template -void -OzoneCPU::processICacheCompletion() -{ - switch (status()) { - case IcacheMiss: - DPRINTF(OzoneCPU, "OzoneCPU: Finished Icache miss.\n"); - - icacheStallCycles += curTick - lastIcacheStall; - _status = IcacheMissComplete; - cacheBlkValid = true; -// scheduleTickEvent(1); - break; - case SwitchedOut: - // If this CPU has been switched out due to sampling/warm-up, - // ignore any further status changes (e.g., due to cache - // misses outstanding at the time of the switch). - return; - default: - panic("OzoneCPU::processICacheCompletion: bad state"); - break; - } -} -*/ + #if FULL_SYSTEM template void @@ -663,7 +518,6 @@ OzoneCPU::post_interrupt(int int_num, int index) { BaseCPU::post_interrupt(int_num, index); -// if (thread._status == ExecContext::Suspended) { if (_status == Idle) { DPRINTF(IPI,"Suspended Processor awoke\n"); // thread.activate(); @@ -690,9 +544,6 @@ OzoneCPU::tick() frontEnd->tick(); backEnd->tick(); - // Do this here? For now the front end will control the PC. -// PC = nextPC; - // check for instruction-count-based events comInstEventQueue[0]->serviceEvents(numInst); @@ -742,11 +593,13 @@ OzoneCPU::setSyscallReturn(SyscallReturn return_value, int tid) if (return_value.successful()) { // no error thread.renameTable[SyscallSuccessReg]->setIntResult(0); - thread.renameTable[ReturnValueReg]->setIntResult(return_value.value()); + thread.renameTable[ReturnValueReg]->setIntResult( + return_value.value()); } else { // got an error, return details thread.renameTable[SyscallSuccessReg]->setIntResult((IntReg) -1); - thread.renameTable[ReturnValueReg]->setIntResult(-return_value.value()); + thread.renameTable[ReturnValueReg]->setIntResult( + -return_value.value()); } } #else @@ -756,15 +609,10 @@ OzoneCPU::hwrei() { // Need to move this to ISA code // May also need to make this per thread -/* - if (!inPalMode()) - return new UnimplementedOpcodeFault; - thread.setNextPC(thread.readMiscReg(AlphaISA::IPR_EXC_ADDR)); -*/ lockFlag = false; lockAddrList.clear(); - kernelStats->hwrei(); + thread.kernelStats->hwrei(); checkInterrupts = true; @@ -835,7 +683,7 @@ OzoneCPU::simPalCheck(int palFunc) { // Need to move this to ISA code // May also need to make this per thread - this->kernelStats->callpal(palFunc, xcProxy); + thread.kernelStats->callpal(palFunc, xcProxy); switch (palFunc) { case PAL::halt: @@ -874,7 +722,6 @@ template void OzoneCPU::OzoneXC::setStatus(Status new_status) { -// cpu->_status = new_status; thread->_status = new_status; } @@ -932,6 +779,7 @@ OzoneCPU::OzoneXC::takeOverFrom(ExecContext *old_context) setStatus(old_context->status()); copyArchRegs(old_context); setCpuId(old_context->readCpuId()); + #if !FULL_SYSTEM setFuncExeInst(old_context->readFuncExeInst()); #else @@ -944,6 +792,8 @@ OzoneCPU::OzoneXC::takeOverFrom(ExecContext *old_context) if (thread->quiesceEvent) { thread->quiesceEvent->xc = this; } + + thread->kernelStats = old_context->getKernelStats(); // storeCondFailures = 0; cpu->lockFlag = false; #endif @@ -954,7 +804,12 @@ OzoneCPU::OzoneXC::takeOverFrom(ExecContext *old_context) template void OzoneCPU::OzoneXC::regStats(const std::string &name) -{ } +{ +#if FULL_SYSTEM + thread->kernelStats = new Kernel::Statistics(cpu->system); + thread->kernelStats->regStats(name + ".kern"); +#endif +} template void diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 07f9d0dad..c03945ffa 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -782,7 +782,7 @@ SimpleCPU::tick() #if FULL_SYSTEM if (system->kernelBinning->fnbin) { - assert(kernelStats); + assert(cpuXC->getKernelStats()); system->kernelBinning->execute(xcProxy, inst); } diff --git a/cpu/thread_state.hh b/cpu/thread_state.hh index e8381b9d3..e09cb12fd 100644 --- a/cpu/thread_state.hh +++ b/cpu/thread_state.hh @@ -1,3 +1,30 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __CPU_THREAD_STATE_HH__ #define __CPU_THREAD_STATE_HH__ @@ -8,11 +35,20 @@ class EndQuiesceEvent; class FunctionProfile; class ProfileNode; +namespace Kernel { + class Statistics; +}; #else -class Process; class FunctionalMemory; +class Process; #endif +/** + * Struct for holding general thread state that is needed across CPU + * models. This includes things such as pointers to the process, + * memory, quiesce events, and certain stats. This can be expanded + * to hold more thread-specific stats within it. + */ struct ThreadState { #if FULL_SYSTEM ThreadState(int _cpuId, int _tid, FunctionalMemory *_mem) @@ -55,6 +91,7 @@ struct ThreadState { EndQuiesceEvent *quiesceEvent; + Kernel::Statistics *kernelStats; #else Process *process; -- cgit v1.2.3 From 6c386396faef6f48f2d01911e59d09b192bf3c45 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 23 May 2006 16:57:14 -0400 Subject: Code cleanup. cpu/base_dyn_inst.hh: Code cleanup --HG-- extra : convert_revision : 501c03f8e4346ffbcb545ddeee30c1f8ded9baa7 --- cpu/base_dyn_inst.hh | 5 +- cpu/ozone/dyn_inst.hh | 52 +-------------------- cpu/ozone/dyn_inst_impl.hh | 7 +-- cpu/ozone/front_end.hh | 34 +++++++++++--- cpu/ozone/front_end_impl.hh | 66 ++++++++++++--------------- cpu/ozone/lw_back_end.hh | 103 +++++++++++------------------------------- cpu/ozone/lw_back_end_impl.hh | 67 ++++++++++++++++----------- cpu/ozone/lw_lsq.hh | 27 ++--------- cpu/ozone/lw_lsq_impl.hh | 41 ++++------------- cpu/ozone/rename_table.hh | 28 ++++++++++++ cpu/ozone/thread_state.hh | 38 ++++++++++++---- 11 files changed, 195 insertions(+), 273 deletions(-) (limited to 'cpu') diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh index cd754dc3c..05ffa6fa4 100644 --- a/cpu/base_dyn_inst.hh +++ b/cpu/base_dyn_inst.hh @@ -447,13 +447,10 @@ class BaseDynInst : public FastAlloc, public RefCounted instResult.integer = val; } - //Push to .cc file. /** Records that one of the source registers is ready. */ void markSrcRegReady(); - /** Marks a specific register as ready. - * @todo: Move this to .cc file. - */ + /** Marks a specific register as ready. */ void markSrcRegReady(RegIndex src_idx); /** Returns if a source register is ready. */ diff --git a/cpu/ozone/dyn_inst.hh b/cpu/ozone/dyn_inst.hh index f251c28ea..5d48bb361 100644 --- a/cpu/ozone/dyn_inst.hh +++ b/cpu/ozone/dyn_inst.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 The Regents of The University of Michigan + * Copyright (c) 2005-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,8 +52,6 @@ class OzoneDynInst : public BaseDynInst // Typedef for DynInstPtr. This is really just a RefCountingPtr. typedef typename Impl::DynInstPtr DynInstPtr; -// typedef typename Impl::BranchPred::BPredInfo BPredInfo; - typedef TheISA::ExtMachInst ExtMachInst; typedef TheISA::MachInst MachInst; typedef TheISA::MiscReg MiscReg; @@ -107,12 +105,6 @@ class OzoneDynInst : public BaseDynInst // up. In the future, you only really need a counter. bool memDepReady() { return srcMemInsts.empty(); } -// void setBPredInfo(const BPredInfo &bp_info) { bpInfo = bp_info; } - -// BPredInfo &getBPredInfo() { return bpInfo; } - -// OzoneXC *thread; - private: void initInstPtrs(); @@ -133,20 +125,12 @@ class OzoneDynInst : public BaseDynInst */ DynInstPtr prevDestInst[MaxInstSrcRegs]; -// BPredInfo bpInfo; - public: Fault initiateAcc(); Fault completeAcc(); -/* - template - Fault read(Addr addr, T &data, unsigned flags); - template - Fault write(T data, Addr addr, unsigned flags, uint64_t *res); -*/ // The register accessor methods provide the index of the // instruction's operand (e.g., 0 or 1), not the architectural // register index, to simplify the implementation of register @@ -244,38 +228,4 @@ class OzoneDynInst : public BaseDynInst bool iqItValid; }; -/* -template -template -inline Fault -OzoneDynInst::read(Addr addr, T &data, unsigned flags) -{ - Fault fault = this->cpu->read(addr, data, flags, this); - - if (this->traceData) { - this->traceData->setAddr(addr); - this->traceData->setData(data); - } - - return fault; -} - -template -template -inline Fault -OzoneDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res) -{ - Fault fault = this->cpu->write(data, addr, flags, res, this); - - this->storeSize = sizeof(T); - this->storeData = data; - - if (this->traceData) { - this->traceData->setAddr(addr); - this->traceData->setData(data); - } - - return fault; -} -*/ #endif // __CPU_OZONE_DYN_INST_HH__ diff --git a/cpu/ozone/dyn_inst_impl.hh b/cpu/ozone/dyn_inst_impl.hh index a7e4460a1..f891ec515 100644 --- a/cpu/ozone/dyn_inst_impl.hh +++ b/cpu/ozone/dyn_inst_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 The Regents of The University of Michigan + * Copyright (c) 2005-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -266,12 +266,7 @@ OzoneDynInst::hwrei() this->setNextPC(this->thread->readMiscReg(AlphaISA::IPR_EXC_ADDR)); this->cpu->hwrei(); -/* - this->cpu->kernelStats->hwrei(); - this->cpu->checkInterrupts = true; - this->cpu->lockFlag = false; -*/ // FIXME: XXX check for interrupts? XXX return NoFault; } diff --git a/cpu/ozone/front_end.hh b/cpu/ozone/front_end.hh index 326f7d2c9..dd382491f 100644 --- a/cpu/ozone/front_end.hh +++ b/cpu/ozone/front_end.hh @@ -1,14 +1,39 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __CPU_OZONE_FRONT_END_HH__ #define __CPU_OZONE_FRONT_END_HH__ #include -//#include "cpu/ozone/cpu.hh" #include "cpu/inst_seq.hh" #include "cpu/o3/bpred_unit.hh" #include "cpu/ozone/rename_table.hh" -//#include "cpu/ozone/thread_state.hh" #include "mem/mem_req.hh" #include "sim/eventq.hh" #include "sim/stats.hh" @@ -132,11 +157,6 @@ class FrontEnd typedef typename Impl::BranchPred BranchPred; - // Typedef for semi-opaque type that holds any information the branch - // predictor needs to update itself. Only two fields are used outside of - // branch predictor, nextPC and isTaken. -// typedef typename BranchPred::BPredInfo BPredInfo; - BranchPred branchPred; class ICacheCompletionEvent : public Event diff --git a/cpu/ozone/front_end_impl.hh b/cpu/ozone/front_end_impl.hh index cd57aeef4..15adae9b4 100644 --- a/cpu/ozone/front_end_impl.hh +++ b/cpu/ozone/front_end_impl.hh @@ -1,3 +1,30 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "arch/faults.hh" #include "arch/isa_traits.hh" @@ -26,14 +53,6 @@ FrontEnd::FrontEnd(Params *params) status = Idle; - // Setup branch predictor. - - // Setup Memory Request -/* - memReq = new MemReq(); - memReq->asid = 0; - memReq->data = new uint8_t[64]; -*/ memReq = NULL; // Size of cache block. cacheBlkSize = icacheInterface ? icacheInterface->getBlockSize() : 64; @@ -77,7 +96,6 @@ void FrontEnd::setXC(ExecContext *xc_ptr) { xc = xc_ptr; -// memReq->xc = xc; } template @@ -321,7 +339,6 @@ FrontEnd::tick() break; } - // if (generalizeFetch) { processInst(inst); if (status == SerializeBlocked) { @@ -333,11 +350,6 @@ FrontEnd::tick() instBuffer.push_back(inst); ++instBufferSize; ++num_inst; - // } else { - // fetch(num_inst); - // decode(num_inst); - // rename(num_inst); - // } #if FULL_SYSTEM if (inst->isQuiesce()) { @@ -402,10 +414,6 @@ FrontEnd::fetchCacheLine() // Translate the instruction request. fault = cpu->translateInstReq(memReq); - // In the case of faults, the fetch stage may need to stall and wait - // on what caused the fetch (ITB or Icache miss). -// assert(fault == NoFault); - // Now do the timing access to see whether or not the instruction // exists within the cache. if (icacheInterface && fault == NoFault) { @@ -466,7 +474,6 @@ FrontEnd::processInst(DynInstPtr &inst) Addr inst_PC = inst->readPC(); -// BPredInfo bp_info = branchPred.lookup(inst_PC); if (!inst->isControl()) { inst->setPredTarg(inst->readNextPC()); } else { @@ -482,7 +489,6 @@ FrontEnd::processInst(DynInstPtr &inst) "%#x\n", inst->seqNum, inst_PC, next_PC); // inst->setNextPC(next_PC); -// inst->setBPredInfo(bp_info); // Not sure where I should set this PC = next_PC; @@ -535,7 +541,7 @@ void FrontEnd::handleFault(Fault &fault) { DPRINTF(FE, "Fault at fetch, telling commit\n"); -// backEnd->fetchFault(fault); + // We're blocked on the back end until it handles this fault. status = TrapPending; @@ -586,9 +592,6 @@ FrontEnd::squash(const InstSeqNum &squash_num, const Addr &next_PC, instBuffer.pop_back(); --instBufferSize; - // Fix up branch predictor if necessary. -// branchPred.undo(inst->getBPredInfo()); - freeRegs+= inst->numDestRegs(); } @@ -607,7 +610,6 @@ FrontEnd::squash(const InstSeqNum &squash_num, const Addr &next_PC, // Clear the icache miss if it's outstanding. if (status == IcacheMissStall && icacheInterface) { DPRINTF(FE, "Squashing outstanding Icache miss.\n"); -// icacheInterface->squash(0); memReq = NULL; } @@ -693,17 +695,9 @@ template bool FrontEnd::updateStatus() { -// bool rename_block = freeRegs <= 0; bool serialize_block = !backEnd->robEmpty() || instBufferSize; bool be_block = cpu->decoupledFrontEnd ? false : backEnd->isBlocked(); bool ret_val = false; -/* - // Should already be handled through addFreeRegs function - if (status == RenameBlocked && !rename_block) { - status = Running; - ret_val = true; - } -*/ if (status == SerializeBlocked && !serialize_block) { status = SerializeComplete; @@ -753,10 +747,6 @@ FrontEnd::getInstFromCacheline() // PC of inst is not in this cache block if (PC >= (cacheBlkPC + cacheBlkSize) || PC < cacheBlkPC || !cacheBlkValid) { -// DPRINTF(OoOCPU, "OoOCPU: PC is not in this cache block\n"); -// DPRINTF(OoOCPU, "OoOCPU: PC: %#x, cacheBlkPC: %#x, cacheBlkValid: %i", -// PC, cacheBlkPC, cacheBlkValid); -// panic("Instruction not in cache line or cache line invalid!"); return NULL; } diff --git a/cpu/ozone/lw_back_end.hh b/cpu/ozone/lw_back_end.hh index 770b66ad5..1c03ffb73 100644 --- a/cpu/ozone/lw_back_end.hh +++ b/cpu/ozone/lw_back_end.hh @@ -1,3 +1,30 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __CPU_OZONE_LW_BACK_END_HH__ #define __CPU_OZONE_LW_BACK_END_HH__ @@ -238,10 +265,6 @@ class LWBackEnd Counter funcExeInst; private: -// typedef typename Impl::InstQueue InstQueue; - -// InstQueue IQ; - typedef typename Impl::LdstQueue LdstQueue; LdstQueue LSQ; @@ -342,8 +365,6 @@ class LWBackEnd bool exactFullStall; -// bool fetchRedirect[Impl::MaxThreads]; - // number of cycles stalled for D-cache misses /* Stats::Scalar<> dcacheStallCycles; Counter lastDcacheStall; @@ -438,43 +459,6 @@ template Fault LWBackEnd::read(MemReqPtr &req, T &data, int load_idx) { -/* memReq->reset(addr, sizeof(T), flags); - - // translate to physical address - Fault fault = cpu->translateDataReadReq(memReq); - - // if we have a cache, do cache access too - if (fault == NoFault && dcacheInterface) { - memReq->cmd = Read; - memReq->completionEvent = NULL; - memReq->time = curTick; - memReq->flags &= ~INST_READ; - MemAccessResult result = dcacheInterface->access(memReq); - - // Ugly hack to get an event scheduled *only* if the access is - // a miss. We really should add first-class support for this - // at some point. - if (result != MA_HIT && dcacheInterface->doEvents()) { - // Fix this hack for keeping funcExeInst correct with loads that - // are executed twice. - --funcExeInst; - - memReq->completionEvent = &cacheCompletionEvent; - lastDcacheStall = curTick; -// unscheduleTickEvent(); -// status = DcacheMissStall; - DPRINTF(OzoneCPU, "Dcache miss stall!\n"); - } else { - // do functional access - fault = thread->mem->read(memReq, data); - - } - } -*/ -/* - if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) - recordEvent("Uncached Read"); -*/ return LSQ.read(req, data, load_idx); } @@ -483,39 +467,6 @@ template Fault LWBackEnd::write(MemReqPtr &req, T &data, int store_idx) { -/* - memReq->reset(addr, sizeof(T), flags); - - // translate to physical address - Fault fault = cpu->translateDataWriteReq(memReq); - - if (fault == NoFault && dcacheInterface) { - memReq->cmd = Write; - memcpy(memReq->data,(uint8_t *)&data,memReq->size); - memReq->completionEvent = NULL; - memReq->time = curTick; - memReq->flags &= ~INST_READ; - MemAccessResult result = dcacheInterface->access(memReq); - - // Ugly hack to get an event scheduled *only* if the access is - // a miss. We really should add first-class support for this - // at some point. - if (result != MA_HIT && dcacheInterface->doEvents()) { - memReq->completionEvent = &cacheCompletionEvent; - lastDcacheStall = curTick; -// unscheduleTickEvent(); -// status = DcacheMissStall; - DPRINTF(OzoneCPU, "Dcache miss stall!\n"); - } - } - - if (res && (fault == NoFault)) - *res = memReq->result; - */ -/* - if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) - recordEvent("Uncached Write"); -*/ return LSQ.write(req, data, store_idx); } diff --git a/cpu/ozone/lw_back_end_impl.hh b/cpu/ozone/lw_back_end_impl.hh index db0872e52..881d6e6b1 100644 --- a/cpu/ozone/lw_back_end_impl.hh +++ b/cpu/ozone/lw_back_end_impl.hh @@ -1,7 +1,34 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ -#include "encumbered/cpu/full/op_class.hh" #include "cpu/checker/cpu.hh" #include "cpu/ozone/lw_back_end.hh" +#include "encumbered/cpu/full/op_class.hh" template void @@ -194,7 +221,6 @@ LWBackEnd::LWBackEnd(Params *params) switchedOut = false; switchPending = false; -// IQ.setBE(this); LSQ.setBE(this); // Setup IQ and LSQ with their parameters here. @@ -202,8 +228,6 @@ LWBackEnd::LWBackEnd(Params *params) instsToExecute = i2e.getWire(-1); -// IQ.setIssueExecQueue(&i2e); - dispatchWidth = params->dispatchWidth ? params->dispatchWidth : width; issueWidth = params->issueWidth ? params->issueWidth : width; wbWidth = params->wbWidth ? params->wbWidth : width; @@ -538,8 +562,6 @@ LWBackEnd::regStats() .desc("ROB Occupancy per cycle") .flags(total | cdf) ; - -// IQ.regStats(); } template @@ -652,17 +674,7 @@ LWBackEnd::tick() squashFromTrap(); } else if (xcSquash) { squashFromXC(); - } /*else if (fetchHasFault && robEmpty() && frontEnd->isEmpty() && !LSQ.hasStoresToWB()) { - DPRINTF(BE, "ROB and front end empty, handling fetch fault\n"); - Fault fetch_fault = frontEnd->getFault(); - if (fetch_fault == NoFault) { - DPRINTF(BE, "Fetch no longer has a fault, cancelling out.\n"); - fetchHasFault = false; - } else { - handleFault(fetch_fault); - fetchHasFault = false; - } - }*/ + } #endif if (dispatchStatus != Blocked) { @@ -773,7 +785,8 @@ LWBackEnd::dispatchInsts() inst->iqItValid = true; waitingInsts++; } else { - DPRINTF(BE, "Instruction [sn:%lli] ready, addding to exeList.\n", + DPRINTF(BE, "Instruction [sn:%lli] ready, addding to " + "exeList.\n", inst->seqNum); exeList.push(inst); } @@ -784,7 +797,8 @@ LWBackEnd::dispatchInsts() inst->setExecuted(); inst->setCanCommit(); } else { - DPRINTF(BE, "Instruction [sn:%lli] ready, addding to exeList.\n", + DPRINTF(BE, "Instruction [sn:%lli] ready, addding to " + "exeList.\n", inst->seqNum); exeList.push(inst); } @@ -993,7 +1007,7 @@ LWBackEnd::instToCommit(DynInstPtr &inst) writeback_count[0]++; } - +#if 0 template void LWBackEnd::writebackInsts() @@ -1040,7 +1054,7 @@ LWBackEnd::writebackInsts() consumer_inst[0]+= consumer_insts; writeback_count[0]+= inst_num; } - +#endif template bool LWBackEnd::commitInst(int inst_num) @@ -1219,15 +1233,15 @@ LWBackEnd::commitInst(int inst_num) --numInsts; ++thread->funcExeInst; - // Maybe move this to where the fault is handled; if the fault is handled, - // don't try to set this myself as the fault will set it. If not, then - // I set thread->PC = thread->nextPC and thread->nextPC = thread->nextPC + 4. + // Maybe move this to where the fault is handled; if the fault is + // handled, don't try to set this myself as the fault will set it. + // If not, then I set thread->PC = thread->nextPC and + // thread->nextPC = thread->nextPC + 4. thread->setPC(thread->readNextPC()); thread->setNextPC(thread->readNextPC() + sizeof(TheISA::MachInst)); updateComInstStats(inst); // Write the done sequence number here. -// LSQ.commitLoads(inst->seqNum); toIEW->doneSeqNum = inst->seqNum; lastCommitCycle = curTick; @@ -1357,7 +1371,8 @@ LWBackEnd::squash(const InstSeqNum &sn) } while (memBarrier && memBarrier->seqNum > sn) { - DPRINTF(BE, "[sn:%lli] Memory barrier squashed (or previously squashed)\n", memBarrier->seqNum); + DPRINTF(BE, "[sn:%lli] Memory barrier squashed (or previously " + "squashed)\n", memBarrier->seqNum); memBarrier->clearMemDependents(); if (memBarrier->memDepReady()) { DPRINTF(BE, "No previous barrier\n"); diff --git a/cpu/ozone/lw_lsq.hh b/cpu/ozone/lw_lsq.hh index 042610324..6fe343b42 100644 --- a/cpu/ozone/lw_lsq.hh +++ b/cpu/ozone/lw_lsq.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2004-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -138,7 +138,6 @@ class OzoneLWLSQ { /** Executes a load instruction. */ Fault executeLoad(DynInstPtr &inst); -// Fault executeLoad(int lq_idx); /** Executes a store instruction. */ Fault executeStore(DynInstPtr &inst); @@ -304,10 +303,8 @@ class OzoneLWLSQ { Status _status; /** The store queue. */ -// std::vector storeQueue; std::list storeQueue; /** The load queue. */ -// std::vector loadQueue; std::list loadQueue; typedef typename std::list::iterator SQIt; @@ -365,7 +362,6 @@ class OzoneLWLSQ { */ InstSeqNum stallingStoreIsn; /** The index of the above store. */ -// int stallingLoadIdx; LQIt stallingLoad; /** Whether or not a load is blocked due to the memory system. It is @@ -398,8 +394,6 @@ class OzoneLWLSQ { template Fault write(MemReqPtr &req, T &data, int store_idx); - /** Returns the index of the head load instruction. */ -// int getLoadHead() { return loadHead; } /** Returns the sequence number of the head load instruction. */ InstSeqNum getLoadHeadSeqNum() { @@ -411,8 +405,6 @@ class OzoneLWLSQ { } - /** Returns the index of the head store instruction. */ -// int getStoreHead() { return storeHead; } /** Returns the sequence number of the head store instruction. */ InstSeqNum getStoreHeadSeqNum() { @@ -604,12 +596,7 @@ OzoneLWLSQ::read(MemReqPtr &req, T &data, int load_idx) DPRINTF(OzoneLSQ, "D-cache: PC:%#x reading from paddr:%#x " "vaddr:%#x flags:%i\n", inst->readPC(), req->paddr, req->vaddr, req->flags); -/* - Addr debug_addr = ULL(0xfffffc0000be81a8); - if (req->vaddr == debug_addr) { - debug_break(); - } -*/ + assert(!req->completionEvent); req->completionEvent = new typename BackEnd::LdWritebackEvent(inst, be); @@ -631,9 +618,6 @@ OzoneLWLSQ::read(MemReqPtr &req, T &data, int load_idx) _status = DcacheMissStall; } else { -// DPRINTF(Activity, "Activity: ld accessing mem hit [sn:%lli]\n", -// inst->seqNum); - DPRINTF(OzoneLSQ, "D-cache hit!\n"); } } else { @@ -664,12 +648,7 @@ OzoneLWLSQ::write(MemReqPtr &req, T &data, int store_idx) assert(!req->data); req->data = new uint8_t[64]; memcpy(req->data, (uint8_t *)&(*sq_it).data, req->size); -/* - Addr debug_addr = ULL(0xfffffc0000be81a8); - if (req->vaddr == debug_addr) { - debug_break(); - } -*/ + // This function only writes the data to the store queue, so no fault // can happen here. return NoFault; diff --git a/cpu/ozone/lw_lsq_impl.hh b/cpu/ozone/lw_lsq_impl.hh index fdf6bff07..2f85a0396 100644 --- a/cpu/ozone/lw_lsq_impl.hh +++ b/cpu/ozone/lw_lsq_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2004-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -104,12 +104,6 @@ OzoneLWLSQ::init(Params *params, unsigned maxLQEntries, SQIndices.push(i); } - // May want to initialize these entries to NULL - -// loadHead = loadTail = 0; - -// storeHead = storeWBIdx = storeTail = 0; - usedPorts = 0; cachePorts = params->cachePorts; @@ -197,8 +191,6 @@ OzoneLWLSQ::insert(DynInstPtr &inst) } else { insertStore(inst); } - -// inst->setInLSQ(); } template @@ -569,12 +561,9 @@ OzoneLWLSQ::writebackStores() } if (result != MA_HIT && dcacheInterface->doEvents()) { -// Event *wb = NULL; store_event->miss = true; typename BackEnd::LdWritebackEvent *wb = NULL; if (req->flags & LOCKED) { - // Stx_C does not generate a system port transaction. -// req->result=1; wb = new typename BackEnd::LdWritebackEvent(inst, be); store_event->wbEvent = wb; @@ -585,8 +574,6 @@ OzoneLWLSQ::writebackStores() // DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", // inst->seqNum); - // Will stores need their own kind of writeback events? - // Do stores even need writeback events? be->addDcacheMiss(inst); lastDcacheStall = curTick; @@ -604,20 +591,16 @@ OzoneLWLSQ::writebackStores() // inst->seqNum); if (req->flags & LOCKED) { - // Stx_C does not generate a system port transaction. -/* if (req->flags & UNCACHEABLE) { - req->result = 2; - } else { - req->result = 1; - } -*/ + // Stx_C does not generate a system port + // transaction in the 21264, but that might be + // hard to accomplish in this model. + typename BackEnd::LdWritebackEvent *wb = new typename BackEnd::LdWritebackEvent(inst, be); store_event->wbEvent = wb; } sq_it--; -// completeStore(inst->sqIdx); } } else { panic("Must HAVE DCACHE!!!!!\n"); @@ -780,7 +763,7 @@ OzoneLWLSQ::completeStore(int store_idx) SQIndices.push(inst->sqIdx); storeQueue.erase(sq_it); --stores; -// assert(!inst->isCompleted()); + inst->setCompleted(); if (cpu->checker) { cpu->checker->tick(inst); @@ -791,7 +774,6 @@ template void OzoneLWLSQ::switchOut() { -// assert(loads == 0); assert(storesToWB == 0); switchedOut = true; SQIt sq_it = --(storeQueue.end()); @@ -804,8 +786,6 @@ OzoneLWLSQ::switchOut() if ((*sq_it).size == 0 && !(*sq_it).completed) { sq_it--; -// completeStore(inst->sqIdx); - continue; } @@ -817,7 +797,8 @@ OzoneLWLSQ::switchOut() continue; } else if ((*sq_it).req->flags & LOCKED) { sq_it--; - assert(!(*sq_it).canWB || ((*sq_it).canWB && (*sq_it).req->flags & LOCKED)); + assert(!(*sq_it).canWB || + ((*sq_it).canWB && (*sq_it).req->flags & LOCKED)); continue; } @@ -886,12 +867,6 @@ OzoneLWLSQ::takeOverFrom(ExecContext *old_xc) SQIndices.push(i); } - // May want to initialize these entries to NULL - -// loadHead = loadTail = 0; - -// storeHead = storeWBIdx = storeTail = 0; - usedPorts = 0; loadFaultInst = storeFaultInst = memDepViolator = NULL; diff --git a/cpu/ozone/rename_table.hh b/cpu/ozone/rename_table.hh index afbf6ff32..6ee23b21b 100644 --- a/cpu/ozone/rename_table.hh +++ b/cpu/ozone/rename_table.hh @@ -1,3 +1,31 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #ifndef __CPU_OZONE_RENAME_TABLE_HH__ #define __CPU_OZONE_RENAME_TABLE_HH__ diff --git a/cpu/ozone/thread_state.hh b/cpu/ozone/thread_state.hh index 269fc6459..c86c3a720 100644 --- a/cpu/ozone/thread_state.hh +++ b/cpu/ozone/thread_state.hh @@ -1,3 +1,30 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef __CPU_OZONE_THREAD_STATE_HH__ #define __CPU_OZONE_THREAD_STATE_HH__ @@ -62,19 +89,14 @@ struct OzoneThreadState : public ThreadState { void setStatus(Status new_status) { _status = new_status; } - RenameTable renameTable; // Should I include backend and frontend - // tables here? For the ozone CPU, maybe, for the new full CPU, probably - // not...you wouldn't want threads just accessing the backend/frontend - // rename tables. - Addr PC; // What should these be set to? Probably the committed ones. + RenameTable renameTable; + Addr PC; Addr nextPC; - // Current instruction? + // Current instruction TheISA::MachInst inst; TheISA::RegFile regs; - // Front end? Back end? -// MemReqPtr memReq; typename Impl::FullCPU *cpu; -- cgit v1.2.3 From c9ad4a15d6b1460ea2b9c1515739f56f81ea9b57 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 23 May 2006 16:59:13 -0400 Subject: Cleanup checker. cpu/checker/cpu.cc: Cleanup checker, give more useful warning messages. Also fix bug cpu/checker/cpu.hh: Cleanup checker, use forward declaration instead of include. --HG-- extra : convert_revision : 8f231199a0a75788218320cdbcc7f70441e5d574 --- cpu/checker/cpu.cc | 321 ++++++++++++++++++----------------------------------- cpu/checker/cpu.hh | 16 +-- 2 files changed, 111 insertions(+), 226 deletions(-) (limited to 'cpu') diff --git a/cpu/checker/cpu.cc b/cpu/checker/cpu.cc index f76f1e063..08ab5d5c8 100644 --- a/cpu/checker/cpu.cc +++ b/cpu/checker/cpu.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,41 +26,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#include -#include -//#include -#include -#include #include -//#include #include -//#include "base/cprintf.hh" -//#include "base/inifile.hh" -//#include "base/loader/symtab.hh" -#include "base/misc.hh" -//#include "base/pollevent.hh" -//#include "base/range.hh" #include "base/refcnt.hh" -//#include "base/stats/events.hh" #include "cpu/base.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/checker/cpu.hh" #include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" -//#include "cpu/exetrace.hh" -//#include "cpu/profile.hh" -#include "cpu/sampler/sampler.hh" -//#include "cpu/smt.hh" #include "cpu/static_inst.hh" -//#include "kern/kernel_stats.hh" -#include "mem/base_mem.hh" -#include "mem/mem_interface.hh" #include "sim/byteswap.hh" -#include "sim/builder.hh" -//#include "sim/debug.hh" -//#include "sim/host.hh" -//#include "sim/sim_events.hh" #include "sim/sim_object.hh" #include "sim/stats.hh" @@ -72,15 +48,8 @@ #include "cpu/ozone/simple_impl.hh" #if FULL_SYSTEM -#include "base/remote_gdb.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" #include "sim/system.hh" -#include "arch/tlb.hh" -#include "arch/stacktrace.hh" #include "arch/vtophys.hh" -#else // !FULL_SYSTEM -#include "mem/functional/functional.hh" #endif // FULL_SYSTEM using namespace std; @@ -90,17 +59,6 @@ using namespace AlphaISA; void CheckerCPU::init() { -/* - BaseCPU::init(); -#if FULL_SYSTEM - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; - - // initialize CPU, including PC - TheISA::initCPU(xc, xc->readCpuId()); - } -#endif -*/ } CheckerCPU::CheckerCPU(Params *p) @@ -151,6 +109,8 @@ CheckerCPU::setMemory(FunctionalMemory *mem) xcProxy = cpuXC->getProxy(); execContexts.push_back(xcProxy); memReq->xc = xcProxy; + delete cpuXC->kernelStats; + cpuXC->kernelStats = NULL; } #endif } @@ -168,6 +128,8 @@ CheckerCPU::setSystem(System *system) xcProxy = cpuXC->getProxy(); execContexts.push_back(xcProxy); memReq->xc = xcProxy; + delete cpuXC->kernelStats; + cpuXC->kernelStats = NULL; } } #endif @@ -197,82 +159,15 @@ CheckerCPU::unserialize(Checkpoint *cp, const string §ion) Fault CheckerCPU::copySrcTranslate(Addr src) { - static bool no_warn = true; - int blk_size = 64; - // Only support block sizes of 64 atm. - assert(blk_size == 64); - int offset = src & (blk_size - 1); - - // Make sure block doesn't span page - if (no_warn && - (src & PageMask) != ((src + blk_size) & PageMask) && - (src >> 40) != 0xfffffc) { - warn("Copied block source spans pages %x.", src); - no_warn = false; - } - - memReq->reset(src & ~(blk_size - 1), blk_size); - - // translate to physical address - Fault fault = cpuXC->translateDataReadReq(memReq); - - if (fault == NoFault) { - cpuXC->copySrcAddr = src; - cpuXC->copySrcPhysAddr = memReq->paddr + offset; - } else { - assert(!fault->isAlignmentFault()); - - cpuXC->copySrcAddr = 0; - cpuXC->copySrcPhysAddr = 0; - } - return fault; + panic("Unimplemented!"); } Fault CheckerCPU::copy(Addr dest) { - static bool no_warn = true; - int blk_size = 64; - // Only support block sizes of 64 atm. - assert(blk_size == 64); - uint8_t data[blk_size]; - //assert(cpuXC->copySrcAddr); - int offset = dest & (blk_size - 1); - - // Make sure block doesn't span page - if (no_warn && - (dest & PageMask) != ((dest + blk_size) & PageMask) && - (dest >> 40) != 0xfffffc) { - no_warn = false; - warn("Copied block destination spans pages %x. ", dest); - } - - memReq->reset(dest & ~(blk_size -1), blk_size); - // translate to physical address - Fault fault = cpuXC->translateDataWriteReq(memReq); - - if (fault == NoFault) { - Addr dest_addr = memReq->paddr + offset; - // Need to read straight from memory since we have more than 8 bytes. - memReq->paddr = cpuXC->copySrcPhysAddr; - cpuXC->mem->read(memReq, data); - memReq->paddr = dest_addr; - cpuXC->mem->write(memReq, data); - memReq->cmd = Copy; - memReq->completionEvent = NULL; - memReq->paddr = cpuXC->copySrcPhysAddr; - memReq->dest = dest_addr; - memReq->size = 64; - memReq->time = curTick; - memReq->flags &= ~INST_READ; - } - else - assert(!fault->isAlignmentFault()); - - return fault; + panic("Unimplemented!"); } -// precise architected memory state accessor macros template Fault CheckerCPU::read(Addr addr, T &data, unsigned flags) @@ -280,17 +175,15 @@ CheckerCPU::read(Addr addr, T &data, unsigned flags) memReq->reset(addr, sizeof(T), flags); // translate to physical address - // Should I probe the DTB? Or should I just take the physical address - // and assume correct translation? translateDataReadReq(memReq); - // if we have a cache, do cache access too memReq->cmd = Read; memReq->completionEvent = NULL; memReq->time = curTick; memReq->flags &= ~INST_READ; if (!(memReq->flags & UNCACHEABLE)) { + // Access memory to see if we have the same data cpuXC->read(memReq, data); } else { // Assume the data is correct if it's an uncached access @@ -350,29 +243,34 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) // translate to physical address cpuXC->translateDataWriteReq(memReq); - if ((!(unverifiedReq->flags & LOCKED) || - ((unverifiedReq->flags & LOCKED) && - unverifiedReq->result == 1)) && - !(unverifiedReq->flags & UNCACHEABLE)) { - // do functional access -// cpuXC->read(memReq, data); - - memReq->cmd = Write; -// memcpy(memReq->data,(uint8_t *)&data,memReq->size); - T inst_data; - memcpy(&inst_data, unverifiedReq->data, sizeof(T)); + // Can compare the write data and result only if it's cacheable, + // not a store conditional, or is a store conditional that + // succeeded. + // @todo: Verify that actual memory matches up with these values. + // Right now it only verifies that the instruction data is the + // same as what was in the request that got sent to memory; there + // is no verification that it is the same as what is in memory. + // This is because the LSQ would have to be snooped in the CPU to + // verify this data. + if (unverifiedReq && + !(unverifiedReq->flags & UNCACHEABLE) && + (!(unverifiedReq->flags & LOCKED) || + ((unverifiedReq->flags & LOCKED) && + unverifiedReq->result == 1))) { +#if 0 + memReq->cmd = Read; memReq->completionEvent = NULL; memReq->time = curTick; memReq->flags &= ~INST_READ; + cpuXC->read(memReq, inst_data); +#endif + T inst_data; + memcpy(&inst_data, unverifiedReq->data, sizeof(T)); - // Hard to verify this as the data writes back after the - // instruction commits. May only be able to check that the - // value produced from execute() matches the value produced - // from the instruction's first execution. if (data != inst_data) { - warn("Store value does not match value in memory! " + warn("%lli: Store value does not match value in memory! " "Instruction: %#x, memory: %#x", - inst_data, data); + curTick, inst_data, data); handleError(); } } @@ -436,19 +334,6 @@ CheckerCPU::dbg_vtophys(Addr addr) } #endif // FULL_SYSTEM -#if FULL_SYSTEM -void -CheckerCPU::post_interrupt(int int_num, int index) -{ - BaseCPU::post_interrupt(int_num, index); - - if (cpuXC->status() == ExecContext::Suspended) { - DPRINTF(IPI,"Suspended Processor awoke\n"); - cpuXC->activate(); - } -} -#endif // FULL_SYSTEM - bool CheckerCPU::translateInstReq(MemReqPtr &req) { @@ -466,15 +351,16 @@ CheckerCPU::translateDataReadReq(MemReqPtr &req) cpuXC->translateDataReadReq(req); if (req->vaddr != unverifiedReq->vaddr) { - warn("Request virtual addresses do not match! Inst: %#x, checker:" - " %#x", - unverifiedReq->vaddr, req->vaddr); + warn("%lli: Request virtual addresses do not match! Inst: %#x, " + "checker: %#x", + curTick, unverifiedReq->vaddr, req->vaddr); + handleError(); } req->paddr = unverifiedReq->paddr; if (checkFlags(req)) { - warn("Request flags do not match! Inst: %#x, checker: %#x", - unverifiedReq->flags, req->flags); + warn("%lli: Request flags do not match! Inst: %#x, checker: %#x", + curTick, unverifiedReq->flags, req->flags); handleError(); } } @@ -485,15 +371,16 @@ CheckerCPU::translateDataWriteReq(MemReqPtr &req) cpuXC->translateDataWriteReq(req); if (req->vaddr != unverifiedReq->vaddr) { - warn("Request virtual addresses do not match! Inst: %#x, checker:" - " %#x", - unverifiedReq->vaddr, req->vaddr); + warn("%lli: Request virtual addresses do not match! Inst: %#x, " + "checker: %#x", + curTick, unverifiedReq->vaddr, req->vaddr); + handleError(); } req->paddr = unverifiedReq->paddr; if (checkFlags(req)) { - warn("Request flags do not match! Inst: %#x, checker: %#x", - unverifiedReq->flags, req->flags); + warn("%lli: Request flags do not match! Inst: %#x, checker: %#x", + curTick, unverifiedReq->flags, req->flags); handleError(); } } @@ -512,13 +399,17 @@ CheckerCPU::checkFlags(MemReqPtr &req) } } -/* start simulation, program loaded, processor precise state initialized */ template void Checker::tick(DynInstPtr &completed_inst) { DynInstPtr inst; + // Either check this instruction, or add it to a list of + // instructions waiting to be checked. Instructions must be + // checked in program order, so if a store has committed yet not + // completed, there may be some instructions that are waiting + // behind it that have completed and must be checked. if (!instList.empty()) { if (youngestSN < completed_inst->seqNum) { DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n", @@ -547,16 +438,17 @@ Checker::tick(DynInstPtr &completed_inst) inst = completed_inst; youngestSN = completed_inst->seqNum; } else { -// panic("SN already seen yet the list is empty!"); return; } } } + // Try to check all instructions that are completed, ending if we + // run out of instructions to check or if an instruction is not + // yet completed. while (1) { DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n", inst->seqNum, inst->readPC()); -// verifyInst = completed_inst; unverifiedResult.integer = inst->readIntResult(); unverifiedReq = inst->req; numCycles++; @@ -569,15 +461,9 @@ Checker::tick(DynInstPtr &completed_inst) cpuXC->setFloatRegDouble(ZeroReg, 0.0); #endif // TARGET_ALPHA - // Try to fetch an instruction - - // set up memory request for instruction fetch -#if FULL_SYSTEM -#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 -#else -#define IFETCH_FLAGS(pc) 0 -#endif - + // Check if any recent PC changes match up with anything we + // expect to happen. This is mostly to check if traps or + // PC-based events have occurred in both the checker and CPU. if (changedPC) { DPRINTF(Checker, "Changed PC recently to %#x\n", cpuXC->readPC()); @@ -585,9 +471,9 @@ Checker::tick(DynInstPtr &completed_inst) if (newPC == cpuXC->readPC()) { DPRINTF(Checker, "Changed PC matches expected PC\n"); } else { - warn("Changed PC does not match expected PC, changed: %#x, " - "expected: %#x", - cpuXC->readPC(), newPC); + warn("%lli: Changed PC does not match expected PC, " + "changed: %#x, expected: %#x", + curTick, cpuXC->readPC(), newPC); handleError(); } willChangePC = false; @@ -600,6 +486,15 @@ Checker::tick(DynInstPtr &completed_inst) changedNextPC = false; } + // Try to fetch the instruction + +#if FULL_SYSTEM +#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 +#else +#define IFETCH_FLAGS(pc) 0 +#endif + + // set up memory request for instruction fetch memReq->cmd = Read; memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t), IFETCH_FLAGS(cpuXC->readPC())); @@ -608,8 +503,13 @@ Checker::tick(DynInstPtr &completed_inst) if (!succeeded) { if (inst->getFault() == NoFault) { - warn("Instruction PC %#x was not found in the ITB!", - cpuXC->readPC()); + // In this case the instruction was not a dummy + // instruction carrying an ITB fault. In the single + // threaded case the ITB should still be able to + // translate this instruction; in the SMT case it's + // possible that its ITB entry was kicked out. + warn("%lli: Instruction PC %#x was not found in the ITB!", + curTick, cpuXC->readPC()); handleError(); // go to the next instruction @@ -618,20 +518,18 @@ Checker::tick(DynInstPtr &completed_inst) return; } else { + // The instruction is carrying an ITB fault. Handle + // the fault and see if our results match the CPU on + // the next tick(). fault = inst->getFault(); } } if (fault == NoFault) { -// fault = cpuXC->mem->read(memReq, machInst); cpuXC->mem->read(memReq, machInst); - // If we've got a valid instruction (i.e., no fault on instruction - // fetch), then execute it. - - // keep an instruction count + // keep an instruction count numInst++; -// numInsts++; // decode the instruction machInst = gtoh(machInst); @@ -639,7 +537,8 @@ Checker::tick(DynInstPtr &completed_inst) // Checks both the machine instruction and the PC. validateInst(inst); - curStaticInst = StaticInst::decode(makeExtMI(machInst, cpuXC->readPC())); + curStaticInst = StaticInst::decode(makeExtMI(machInst, + cpuXC->readPC())); #if FULL_SYSTEM cpuXC->setInst(machInst); @@ -660,10 +559,6 @@ Checker::tick(DynInstPtr &completed_inst) // Checks to make sure instrution results are correct. validateExecution(inst); -// if (curStaticInst->isMemRef()) { -// numMemRefs++; -// } - if (curStaticInst->isLoad()) { ++numLoad; } @@ -693,6 +588,9 @@ Checker::tick(DynInstPtr &completed_inst) } #if FULL_SYSTEM + // @todo: Determine if these should happen only if the + // instruction hasn't faulted. In the SimpleCPU case this may + // not be true, but in the O3 or Ozone case this may be true. Addr oldpc; int count = 0; do { @@ -707,10 +605,12 @@ Checker::tick(DynInstPtr &completed_inst) } #endif - // Checks PC, next PC. Optionally can check all registers. (Or just those + // @todo: Optionally can check all registers. (Or just those // that have been modified). validateState(); + // Continue verifying instructions if there's another completed + // instruction waiting to be verified. if (instList.empty()) { break; } else if (instList.front()->isCompleted()) { @@ -726,7 +626,6 @@ template void Checker::switchOut(Sampler *s) { - sampler = s; instList.clear(); } @@ -734,15 +633,6 @@ template void Checker::takeOverFrom(BaseCPU *oldCPU) { -// BaseCPU::takeOverFrom(oldCPU); - - // if any of this CPU's ExecContexts are active, mark the CPU as - // running and schedule its tick event. -/* - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; - } -*/ } template @@ -750,20 +640,22 @@ void Checker::validateInst(DynInstPtr &inst) { if (inst->readPC() != cpuXC->readPC()) { - warn("PCs do not match! Inst: %#x, checker: %#x", - inst->readPC(), cpuXC->readPC()); + warn("%lli: PCs do not match! Inst: %#x, checker: %#x", + curTick, inst->readPC(), cpuXC->readPC()); if (changedPC) { - warn("Changed PCs recently, may not be an error"); + warn("%lli: Changed PCs recently, may not be an error", + curTick); } else { handleError(); } } - if (static_cast(inst->staticInst->machInst) != - machInst) { - warn("Binary instructions do not match! Inst: %#x, checker: %#x", - static_cast(inst->staticInst->machInst), - machInst); + MachInst mi = static_cast(inst->staticInst->machInst); + + if (mi != machInst) { + warn("%lli: Binary instructions do not match! Inst: %#x, " + "checker: %#x", + curTick, mi, machInst); handleError(); } } @@ -773,10 +665,11 @@ void Checker::validateExecution(DynInstPtr &inst) { if (inst->numDestRegs()) { + // @todo: Support more destination registers. if (inst->isUnverifiable()) { - // @todo: Support more destination registers. - // Grab the result from the instruction and write it to the - // register. + // Unverifiable instructions assume they were executed + // properly by the CPU. Grab the result from the + // instruction and write it to the register. RegIndex idx = inst->destRegIdx(0); if (idx < TheISA::FP_Base_DepTag) { cpuXC->setIntReg(idx, inst->readIntResult()); @@ -786,16 +679,17 @@ Checker::validateExecution(DynInstPtr &inst) cpuXC->setMiscReg(idx, inst->readIntResult()); } } else if (result.integer != inst->readIntResult()) { - warn("Instruction results do not match! (May not be integer results) " - "Inst: %#x, checker: %#x", - inst->readIntResult(), result.integer); + warn("%lli: Instruction results do not match! (Results may not " + "actually be integers) Inst: %#x, checker: %#x", + curTick, inst->readIntResult(), result.integer); handleError(); } } if (inst->readNextPC() != cpuXC->readNextPC()) { - warn("Instruction next PCs do not match! Inst: %#x, checker: %#x", - inst->readNextPC(), cpuXC->readNextPC()); + warn("%lli: Instruction next PCs do not match! Inst: %#x, " + "checker: %#x", + curTick, inst->readNextPC(), cpuXC->readNextPC()); handleError(); } @@ -810,9 +704,10 @@ Checker::validateExecution(DynInstPtr &inst) if (inst->xcBase()->readMiscReg(misc_reg_idx) != cpuXC->readMiscReg(misc_reg_idx)) { - warn("Misc reg idx %i (side effect) does not match! Inst: %#x, " - "checker: %#x", - misc_reg_idx, inst->xcBase()->readMiscReg(misc_reg_idx), + warn("%lli: Misc reg idx %i (side effect) does not match! " + "Inst: %#x, checker: %#x", + curTick, misc_reg_idx, + inst->xcBase()->readMiscReg(misc_reg_idx), cpuXC->readMiscReg(misc_reg_idx)); handleError(); } diff --git a/cpu/checker/cpu.hh b/cpu/checker/cpu.hh index 678e888df..37fe59d95 100644 --- a/cpu/checker/cpu.hh +++ b/cpu/checker/cpu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,7 +39,6 @@ #include "cpu/base_dyn_inst.hh" #include "cpu/cpu_exec_context.hh" #include "cpu/pc_event.hh" -#include "cpu/sampler/sampler.hh" #include "cpu/static_inst.hh" #include "sim/eventq.hh" @@ -63,6 +62,7 @@ class BaseDynInst; class ExecContext; class MemInterface; class Checkpoint; +class Sampler; class CheckerCPU : public BaseCPU { @@ -86,8 +86,6 @@ class CheckerCPU : public BaseCPU }; public: - void post_interrupt(int int_num, int index); - CheckerCPU(Params *p); virtual ~CheckerCPU(); @@ -111,8 +109,6 @@ class CheckerCPU : public BaseCPU #if FULL_SYSTEM Addr dbg_vtophys(Addr addr); - - bool interval_stats; #endif union Result { @@ -129,11 +125,6 @@ class CheckerCPU : public BaseCPU // Refcounted pointer to the one memory request. MemReqPtr memReq; - // Pointer to the sampler that is telling us to switchover. - // Used to signal the completion of the pipe drain and schedule - // the next switchover - Sampler *sampler; - StaticInstPtr curStaticInst; // number of simulated instructions @@ -284,6 +275,7 @@ class CheckerCPU : public BaseCPU bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } #else // Assume that the normal CPU's call to syscall was successful. + // The checker's state would have already been updated by the syscall. void syscall() { } #endif @@ -307,8 +299,6 @@ class CheckerCPU : public BaseCPU bool exitOnError; InstSeqNum youngestSN; -// std::map storeBuff; -// typedef std::map::iterator map_it; }; template -- cgit v1.2.3 From 358cf1b11765024309fe986262bb3a3d16c8a720 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 23 May 2006 17:03:43 -0400 Subject: Rework how instructions are scheduled and executed. The "execute" portion of IEW is really just the last cycle of execution, at which point execute() gets called. Execution begins inside the IQ, when it schedules FUs for specific instructions. As a result, the Execute stage should just pull all completing instructions out of the IQ stage and execute them. Limiting the number of writebacks outstanding must still be done. cpu/o3/iew_impl.hh: Rework how instructions are scheduled and executed. There shouldn't be a specific "width" from issue to execute because issue does the scheduling of the functional units (really the beginning of the execution). cpu/o3/inst_queue.hh: cpu/o3/inst_queue_impl.hh: Rework how instructions are scheduled and executed. --HG-- extra : convert_revision : bbf1a8a4c0a2f2a938bdd78d74493048fd3b4b55 --- cpu/o3/iew_impl.hh | 5 +++-- cpu/o3/inst_queue.hh | 4 ++++ cpu/o3/inst_queue_impl.hh | 22 +++++++++++++++++----- 3 files changed, 24 insertions(+), 7 deletions(-) (limited to 'cpu') diff --git a/cpu/o3/iew_impl.hh b/cpu/o3/iew_impl.hh index 59f4055a6..c22850131 100644 --- a/cpu/o3/iew_impl.hh +++ b/cpu/o3/iew_impl.hh @@ -1232,13 +1232,14 @@ DefaultIEW::executeInsts() #endif // Execute/writeback any instructions that are available. + int insts_to_execute = fromIssue->size; int inst_num = 0; - for ( ; inst_num < issueWidth && fromIssue->insts[inst_num]; + for (; inst_num < insts_to_execute; ++inst_num) { DPRINTF(IEW, "Execute: Executing instructions from IQ.\n"); - DynInstPtr inst = fromIssue->insts[inst_num]; + DynInstPtr inst = instQueue.getInstToExecute(); DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n", inst->readPC(), inst->threadNumber,inst->seqNum); diff --git a/cpu/o3/inst_queue.hh b/cpu/o3/inst_queue.hh index 6bdf4ddc2..518de73d9 100644 --- a/cpu/o3/inst_queue.hh +++ b/cpu/o3/inst_queue.hh @@ -171,6 +171,8 @@ class InstructionQueue */ void insertBarrier(DynInstPtr &barr_inst); + DynInstPtr getInstToExecute(); + /** * Records the instruction as the producer of a register without * adding it to the rest of the IQ. @@ -272,6 +274,8 @@ class InstructionQueue /** List of all the instructions in the IQ (some of which may be issued). */ std::list instList[Impl::MaxThreads]; + std::list instsToExecute; + /** * Struct for comparing entries to be added to the priority queue. This * gives reverse ordering to the instructions in terms of sequence diff --git a/cpu/o3/inst_queue_impl.hh b/cpu/o3/inst_queue_impl.hh index ed57ac257..412d59768 100644 --- a/cpu/o3/inst_queue_impl.hh +++ b/cpu/o3/inst_queue_impl.hh @@ -588,6 +588,16 @@ InstructionQueue::insertBarrier(DynInstPtr &barr_inst) insertNonSpec(barr_inst); } +template +typename Impl::DynInstPtr +InstructionQueue::getInstToExecute() +{ + assert(!instsToExecute.empty()); + DynInstPtr inst = instsToExecute.front(); + instsToExecute.pop_front(); + return inst; +} + template void InstructionQueue::addToOrderList(OpClass op_class) @@ -662,9 +672,11 @@ InstructionQueue::processFUCompletion(DynInstPtr &inst, int fu_idx) // @todo: This could break if there's multiple multi-cycle ops // finishing on this cycle. Maybe implement something like // instToCommit in iew_impl.hh. - int &size = issueToExecuteQueue->access(0)->size; + issueToExecuteQueue->access(0)->size++; + instsToExecute.push_back(inst); +// int &size = issueToExecuteQueue->access(0)->size; - issueToExecuteQueue->access(0)->insts[size++] = inst; +// issueToExecuteQueue->access(0)->insts[size++] = inst; } // @todo: Figure out a better way to remove the squashed items from the @@ -690,9 +702,8 @@ InstructionQueue::scheduleReadyInsts() ListOrderIt order_it = listOrder.begin(); ListOrderIt order_end_it = listOrder.end(); int total_issued = 0; - int exec_queue_slot = i2e_info->size; - while (exec_queue_slot < totalWidth && total_issued < totalWidth && + while (total_issued < totalWidth && order_it != order_end_it) { OpClass op_class = (*order_it).queueType; @@ -733,8 +744,9 @@ InstructionQueue::scheduleReadyInsts() if (idx == -2 || idx != -1) { if (op_latency == 1) { - i2e_info->insts[exec_queue_slot++] = issuing_inst; +// i2e_info->insts[exec_queue_slot++] = issuing_inst; i2e_info->size++; + instsToExecute.push_back(issuing_inst); // Add the FU onto the list of FU's to be freed next // cycle if we used one. -- cgit v1.2.3