CPU: Merge the predecoder and decoder.

These classes are always used together, and merging them will give the ISAs
more flexibility in how they cache things and manage the process.

--HG--
rename : src/arch/x86/predecoder_tables.cc => src/arch/x86/decoder_tables.cc
This commit is contained in:
Gabe Black
2012-05-26 13:44:46 -07:00
parent eae1e97fb0
commit 0cba96ba6a
43 changed files with 1121 additions and 1548 deletions

View File

@@ -64,11 +64,6 @@ class CheckerCPU;
class ThreadContext;
class System;
namespace TheISA
{
class Predecoder;
}
class CPUProgressEvent : public Event
{
protected:
@@ -257,7 +252,6 @@ class BaseCPU : public MemObject
protected:
std::vector<ThreadContext *> threadContexts;
std::vector<TheISA::Predecoder *> predecoders;
Trace::InstTracer * tracer;

View File

@@ -47,7 +47,6 @@
#include <map>
#include <queue>
#include "arch/predecoder.hh"
#include "arch/types.hh"
#include "base/statistics.hh"
#include "cpu/base.hh"
@@ -156,9 +155,6 @@ class CheckerCPU : public BaseCPU
// keep them all in a std::queue
std::queue<Result> result;
// current instruction
TheISA::MachInst machInst;
// Pointer to the one memory request.
RequestPtr memReq;
@@ -401,8 +397,7 @@ class Checker : public CheckerCPU
public:
Checker(Params *p)
: CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL),
predecoder(NULL)
: CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
{ }
void switchOut();
@@ -434,7 +429,6 @@ class Checker : public CheckerCPU
bool updateThisCycle;
DynInstPtr unverifiedInst;
TheISA::Predecoder predecoder;
std::list<DynInstPtr> instList;
typedef typename std::list<DynInstPtr>::iterator InstListIt;

View File

@@ -69,7 +69,7 @@ Checker<Impl>::advancePC(Fault fault)
if (fault != NoFault) {
curMacroStaticInst = StaticInst::nullStaticInstPtr;
fault->invoke(tc, curStaticInst);
predecoder.reset();
thread->decoder.reset();
} else {
if (curStaticInst) {
if (curStaticInst->isLastMicroop())
@@ -113,7 +113,7 @@ Checker<Impl>::handlePendingInt()
"a non-interuptable instruction!", curTick());
}
boundaryInst = NULL;
predecoder.reset();
thread->decoder.reset();
curMacroStaticInst = StaticInst::nullStaticInstPtr;
}
@@ -239,6 +239,8 @@ Checker<Impl>::verify(DynInstPtr &completed_inst)
Addr fetch_PC = thread->instAddr();
fetch_PC = (fetch_PC & PCMask) + fetchOffset;
MachInst machInst;
// If not in the middle of a macro instruction
if (!curMacroStaticInst) {
// set up memory request for instruction fetch
@@ -304,24 +306,18 @@ Checker<Impl>::verify(DynInstPtr &completed_inst)
StaticInstPtr instPtr = NULL;
//Predecode, ie bundle up an ExtMachInst
predecoder.setTC(thread->getTC());
thread->decoder.setTC(thread->getTC());
//If more fetch data is needed, pass it in.
Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
predecoder.moreBytes(pcState, fetchPC, machInst);
thread->decoder.moreBytes(pcState, fetchPC, machInst);
//If an instruction is ready, decode it.
//Otherwise, we'll have to fetch beyond the
//MachInst at the current pc.
if (predecoder.extMachInstReady()) {
if (thread->decoder.instReady()) {
fetchDone = true;
ExtMachInst newMachInst =
predecoder.getExtMachInst(pcState);
instPtr = thread->decoder.decode(pcState);
thread->pcState(pcState);
instPtr = thread->decoder.decode(newMachInst,
pcState.instAddr());
#if THE_ISA != X86_ISA
machInst = newMachInst;
#endif
} else {
fetchDone = false;
fetchOffset += sizeof(TheISA::MachInst);
@@ -344,8 +340,8 @@ Checker<Impl>::verify(DynInstPtr &completed_inst)
}
}
}
// reset predecoder on Checker
predecoder.reset();
// reset decoder on Checker
thread->decoder.reset();
// Check Checker and CPU get same instruction, and record
// any faults the CPU may have had.
@@ -477,17 +473,9 @@ Checker<Impl>::validateInst(DynInstPtr &inst)
}
}
MachInst mi;
#if THE_ISA != X86_ISA
mi = static_cast<MachInst>(inst->staticInst->machInst);
#endif
if (mi != machInst) {
panic("%lli: Binary instructions do not match! Inst: %#x, "
"checker: %#x",
curTick(), mi, machInst);
handleError(inst);
if (curStaticInst != inst->staticInst) {
warn("%lli: StaticInstPtrs don't match. (%s, %s).\n", curTick(),
curStaticInst->getName(), inst->staticInst->getName());
}
}

View File

@@ -1773,9 +1773,9 @@ InOrderCPU::getDTBPtr()
}
TheISA::Decoder *
InOrderCPU::getDecoderPtr()
InOrderCPU::getDecoderPtr(unsigned tid)
{
return &resPool->getInstUnit()->decoder;
return resPool->getInstUnit()->decoder[tid];
}
Fault

View File

@@ -342,7 +342,7 @@ class InOrderCPU : public BaseCPU
TheISA::TLB *getITBPtr();
TheISA::TLB *getDTBPtr();
TheISA::Decoder *getDecoderPtr();
TheISA::Decoder *getDecoderPtr(unsigned tid);
/** Accessor Type for the SkedCache */
typedef uint32_t SkedID;

View File

@@ -34,7 +34,6 @@
#include "arch/isa_traits.hh"
#include "arch/locked_mem.hh"
#include "arch/predecoder.hh"
#include "arch/utility.hh"
#include "config/the_isa.hh"
#include "cpu/inorder/resources/cache_unit.hh"

View File

@@ -36,7 +36,6 @@
#include <string>
#include <vector>
#include "arch/predecoder.hh"
#include "arch/tlb.hh"
#include "base/hashmap.hh"
#include "config/the_isa.hh"

View File

@@ -34,7 +34,6 @@
#include "arch/isa_traits.hh"
#include "arch/locked_mem.hh"
#include "arch/predecoder.hh"
#include "arch/utility.hh"
#include "config/the_isa.hh"
#include "cpu/inorder/resources/cache_unit.hh"
@@ -60,7 +59,7 @@ FetchUnit::FetchUnit(string res_name, int res_id, int res_width,
instSize(sizeof(TheISA::MachInst)), fetchBuffSize(params->fetchBuffSize)
{
for (int tid = 0; tid < MaxThreads; tid++)
predecoder[tid] = new Predecoder(NULL);
decoder[tid] = new Decoder(NULL);
}
FetchUnit::~FetchUnit()
@@ -92,7 +91,6 @@ void
FetchUnit::createMachInst(std::list<FetchBlock*>::iterator fetch_it,
DynInstPtr inst)
{
ExtMachInst ext_inst;
Addr block_addr = cacheBlockAlign(inst->getMemAddr());
Addr fetch_addr = inst->getMemAddr();
unsigned fetch_offset = (fetch_addr - block_addr) / instSize;
@@ -111,13 +109,11 @@ FetchUnit::createMachInst(std::list<FetchBlock*>::iterator fetch_it,
MachInst mach_inst =
TheISA::gtoh(fetchInsts[fetch_offset]);
predecoder[tid]->setTC(cpu->thread[tid]->getTC());
predecoder[tid]->moreBytes(instPC, inst->instAddr(), mach_inst);
assert(predecoder[tid]->extMachInstReady());
ext_inst = predecoder[tid]->getExtMachInst(instPC);
decoder[tid]->setTC(cpu->thread[tid]->getTC());
decoder[tid]->moreBytes(instPC, inst->instAddr(), mach_inst);
assert(decoder[tid]->instReady());
inst->setStaticInst(decoder[tid]->decode(instPC));
inst->pcState(instPC);
inst->setStaticInst(decoder.decode(ext_inst, instPC.instAddr()));
}
void
@@ -582,7 +578,7 @@ void
FetchUnit::trap(Fault fault, ThreadID tid, DynInstPtr inst)
{
//@todo: per thread?
predecoder[tid]->reset();
decoder[tid]->reset();
//@todo: squash using dummy inst seq num
squash(NULL, NumStages - 1, 0, tid);

View File

@@ -37,7 +37,6 @@
#include <vector>
#include "arch/decoder.hh"
#include "arch/predecoder.hh"
#include "arch/tlb.hh"
#include "config/the_isa.hh"
#include "cpu/inorder/resources/cache_unit.hh"
@@ -89,7 +88,7 @@ class FetchUnit : public CacheUnit
void trap(Fault fault, ThreadID tid, DynInstPtr inst);
TheISA::Decoder decoder;
TheISA::Decoder *decoder[ThePipeline::MaxThreads];
private:
void squashCacheRequest(CacheReqPtr req_ptr);
@@ -129,8 +128,6 @@ class FetchUnit : public CacheUnit
int fetchBuffSize;
TheISA::Predecoder *predecoder[ThePipeline::MaxThreads];
/** Valid Cache Blocks*/
std::list<FetchBlock*> fetchBuffer;

View File

@@ -83,7 +83,11 @@ class InOrderThreadContext : public ThreadContext
*/
CheckerCPU *getCheckerCpuPtr() { return NULL; }
TheISA::Decoder *getDecoderPtr() { return cpu->getDecoderPtr(); }
TheISA::Decoder *
getDecoderPtr()
{
return cpu->getDecoderPtr(thread->contextId());
}
System *getSystemPtr() { return cpu->system; }

View File

@@ -43,7 +43,6 @@
#include <iomanip>
#include "arch/sparc/decoder.hh"
#include "arch/sparc/predecoder.hh"
#include "arch/sparc/registers.hh"
#include "arch/sparc/utility.hh"
#include "arch/tlb.hh"
@@ -146,7 +145,6 @@ Trace::LegionTraceRecord::dump()
{
ostream &outs = Trace::output();
static TheISA::Predecoder predecoder(NULL);
// Compare
bool compared = false;
bool diffPC = false;
@@ -423,15 +421,14 @@ Trace::LegionTraceRecord::dump()
<< staticInst->disassemble(m5Pc, debugSymbolTable)
<< endl;
predecoder.setTC(thread);
predecoder.moreBytes(m5Pc, m5Pc, shared_data->instruction);
TheISA::Decoder *decoder = thread->getDecoderPtr();
decoder->setTC(thread);
decoder->moreBytes(m5Pc, m5Pc, shared_data->instruction);
assert(predecoder.extMachInstReady());
assert(decoder->instReady());
PCState tempPC = pc;
StaticInstPtr legionInst =
thread->getDecoderPtr()->decode(
predecoder.getExtMachInst(tempPC), lgnPc);
StaticInstPtr legionInst = decoder->decode(tempPC);
outs << setfill(' ') << setw(15)
<< " Legion Inst: "
<< "0x" << setw(8) << setfill('0') << hex

View File

@@ -45,7 +45,6 @@
#define __CPU_O3_FETCH_HH__
#include "arch/decoder.hh"
#include "arch/predecoder.hh"
#include "arch/utility.hh"
#include "base/statistics.hh"
#include "config/the_isa.hh"
@@ -340,7 +339,7 @@ class DefaultFetch
}
/** The decoder. */
TheISA::Decoder decoder;
TheISA::Decoder *decoder[Impl::MaxThreads];
private:
DynInstPtr buildInst(ThreadID tid, StaticInstPtr staticInst,
@@ -398,9 +397,6 @@ class DefaultFetch
/** BPredUnit. */
BPredUnit branchPred;
/** Predecoder. */
TheISA::Predecoder predecoder;
TheISA::PCState pc[Impl::MaxThreads];
Addr fetchOffset[Impl::MaxThreads];

View File

@@ -73,7 +73,6 @@ template<class Impl>
DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
: cpu(_cpu),
branchPred(params),
predecoder(NULL),
numInst(0),
decodeToFetchDelay(params->decodeToFetchDelay),
renameToFetchDelay(params->renameToFetchDelay),
@@ -132,6 +131,9 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
// Get the size of an instruction.
instSize = sizeof(TheISA::MachInst);
for (int i = 0; i < Impl::MaxThreads; i++)
decoder[i] = new TheISA::Decoder(NULL);
}
template <class Impl>
@@ -660,7 +662,7 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req)
DPRINTF(Fetch, "[tid:%i]: Translation faulted, building noop.\n", tid);
// We will use a nop in ordier to carry the fault.
DynInstPtr instruction = buildInst(tid,
decoder.decode(TheISA::NoopMachInst, fetchPC.instAddr()),
decoder[tid]->decode(TheISA::NoopMachInst, fetchPC.instAddr()),
NULL, fetchPC, fetchPC, false);
instruction->setPredTarg(fetchPC);
@@ -693,7 +695,7 @@ DefaultFetch<Impl>::doSquash(const TheISA::PCState &newPC,
macroop[tid] = squashInst->macroop;
else
macroop[tid] = NULL;
predecoder.reset();
decoder[tid]->reset();
// Clear the icache miss if it's outstanding.
if (fetchStatus[tid] == IcacheWaitResponse) {
@@ -1193,8 +1195,9 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// We need to process more memory if we aren't going to get a
// StaticInst from the rom, the current macroop, or what's already
// in the predecoder.
bool needMem = !inRom && !curMacroop && !predecoder.extMachInstReady();
// in the decoder.
bool needMem = !inRom && !curMacroop &&
!decoder[tid]->instReady();
fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
Addr block_PC = icacheBlockAlignPC(fetchAddr);
@@ -1222,10 +1225,10 @@ DefaultFetch<Impl>::fetch(bool &status_change)
}
MachInst inst = TheISA::gtoh(cacheInsts[blkOffset]);
predecoder.setTC(cpu->thread[tid]->getTC());
predecoder.moreBytes(thisPC, fetchAddr, inst);
decoder[tid]->setTC(cpu->thread[tid]->getTC());
decoder[tid]->moreBytes(thisPC, fetchAddr, inst);
if (predecoder.needMoreBytes()) {
if (decoder[tid]->needMoreBytes()) {
blkOffset++;
fetchAddr += instSize;
pcOffset += instSize;
@@ -1236,11 +1239,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// the memory we've processed so far.
do {
if (!(curMacroop || inRom)) {
if (predecoder.extMachInstReady()) {
ExtMachInst extMachInst =
predecoder.getExtMachInst(thisPC);
staticInst =
decoder.decode(extMachInst, thisPC.instAddr());
if (decoder[tid]->instReady()) {
staticInst = decoder[tid]->decode(thisPC);
// Increment stat of fetched instructions.
++fetchedInsts;
@@ -1311,7 +1311,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
status_change = true;
break;
}
} while ((curMacroop || predecoder.extMachInstReady()) &&
} while ((curMacroop || decoder[tid]->instReady()) &&
numInst < fetchWidth);
}

View File

@@ -85,7 +85,11 @@ class O3ThreadContext : public ThreadContext
CheckerCPU *getCheckerCpuPtr() { return NULL; }
TheISA::Decoder *getDecoderPtr() { return &cpu->fetch.decoder; }
TheISA::Decoder *
getDecoderPtr()
{
return cpu->fetch.decoder[thread->threadId()];
}
/** Returns a pointer to this CPU. */
virtual BaseCPU *getCpuPtr() { return cpu; }

View File

@@ -465,12 +465,12 @@ AtomicSimpleCPU::tick()
dcache_access = false; // assume no dcache access
if (needToFetch) {
// This is commented out because the predecoder would act like
// This is commented out because the decoder would act like
// a tiny cache otherwise. It wouldn't be flushed when needed
// like the I cache. It should be flushed, and when that works
// this code should be uncommented.
//Fetch more instruction memory if necessary
//if(predecoder.needMoreBytes())
//if(decoder.needMoreBytes())
//{
icache_access = true;
Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq);

View File

@@ -85,7 +85,7 @@ using namespace std;
using namespace TheISA;
BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
: BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
: BaseCPU(p), traceData(NULL), thread(NULL)
{
if (FullSystem)
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
@@ -332,7 +332,7 @@ BaseSimpleCPU::checkForInterrupts()
fetchOffset = 0;
interrupts->updateIntrInfo(tc);
interrupt->invoke(tc);
predecoder.reset();
thread->decoder.reset();
}
}
}
@@ -378,23 +378,24 @@ BaseSimpleCPU::preExecute()
//We're not in the middle of a macro instruction
StaticInstPtr instPtr = NULL;
TheISA::Decoder *decoder = &(thread->decoder);
//Predecode, ie bundle up an ExtMachInst
//This should go away once the constructor can be set up properly
predecoder.setTC(thread->getTC());
decoder->setTC(thread->getTC());
//If more fetch data is needed, pass it in.
Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
//if(predecoder.needMoreBytes())
predecoder.moreBytes(pcState, fetchPC, inst);
//if(decoder->needMoreBytes())
decoder->moreBytes(pcState, fetchPC, inst);
//else
// predecoder.process();
// decoder->process();
//If an instruction is ready, decode it. Otherwise, we'll have to
//Decode an instruction if one is ready. Otherwise, we'll have to
//fetch beyond the MachInst at the current pc.
if (predecoder.extMachInstReady()) {
instPtr = decoder->decode(pcState);
if (instPtr) {
stayAtPC = false;
ExtMachInst machInst = predecoder.getExtMachInst(pcState);
thread->pcState(pcState);
instPtr = thread->decoder.decode(machInst, pcState.instAddr());
} else {
stayAtPC = true;
fetchOffset += sizeof(MachInst);
@@ -505,7 +506,7 @@ BaseSimpleCPU::advancePC(Fault fault)
if (fault != NoFault) {
curMacroStaticInst = StaticInst::nullStaticInstPtr;
fault->invoke(tc, curStaticInst);
predecoder.reset();
thread->decoder.reset();
} else {
if (curStaticInst) {
if (curStaticInst->isLastMicroop())

View File

@@ -45,8 +45,6 @@
#ifndef __CPU_SIMPLE_BASE_HH__
#define __CPU_SIMPLE_BASE_HH__
#include "arch/decoder.hh"
#include "arch/predecoder.hh"
#include "base/statistics.hh"
#include "config/the_isa.hh"
#include "cpu/base.hh"
@@ -71,7 +69,6 @@ namespace TheISA
{
class DTB;
class ITB;
class Predecoder;
}
namespace Trace {
@@ -154,9 +151,6 @@ class BaseSimpleCPU : public BaseCPU
// current instruction
TheISA::MachInst inst;
// The predecoder
TheISA::Predecoder predecoder;
StaticInstPtr curStaticInst;
StaticInstPtr curMacroStaticInst;

View File

@@ -63,7 +63,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
Process *_process, TheISA::TLB *_itb,
TheISA::TLB *_dtb)
: ThreadState(_cpu, _thread_num, _process), system(_sys), itb(_itb),
dtb(_dtb)
dtb(_dtb), decoder(NULL)
{
clearArchRegs();
tc = new ProxyThreadContext<SimpleThread>(this);
@@ -71,7 +71,8 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
TheISA::TLB *_itb, TheISA::TLB *_dtb,
bool use_kernel_stats)
: ThreadState(_cpu, _thread_num, NULL), system(_sys), itb(_itb), dtb(_dtb)
: ThreadState(_cpu, _thread_num, NULL), system(_sys), itb(_itb), dtb(_dtb),
decoder(NULL)
{
tc = new ProxyThreadContext<SimpleThread>(this);
@@ -98,7 +99,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
}
SimpleThread::SimpleThread()
: ThreadState(NULL, -1, NULL)
: ThreadState(NULL, -1, NULL), decoder(NULL)
{
tc = new ProxyThreadContext<SimpleThread>(this);
}