Make the predecoder an object with it's own switched header file. Start adding predecoding functionality to x86.
src/arch/SConscript:
src/arch/alpha/utility.hh:
src/arch/mips/utility.hh:
src/arch/sparc/utility.hh:
src/cpu/base.hh:
src/cpu/o3/fetch.hh:
src/cpu/o3/fetch_impl.hh:
src/cpu/simple/atomic.cc:
src/cpu/simple/base.cc:
src/cpu/simple/base.hh:
src/cpu/static_inst.hh:
src/arch/alpha/predecoder.hh:
src/arch/mips/predecoder.hh:
src/arch/sparc/predecoder.hh:
Make the predecoder an object with it's own switched header file.
--HG--
extra : convert_revision : 77206e29089130e86b97164c30022a062699ba86
This commit is contained in:
@@ -500,17 +500,28 @@ AtomicSimpleCPU::tick()
|
||||
Fault fault = setupFetchRequest(ifetch_req);
|
||||
|
||||
if (fault == NoFault) {
|
||||
ifetch_pkt->reinitFromRequest();
|
||||
|
||||
Tick icache_latency = icachePort.sendAtomic(ifetch_pkt);
|
||||
// ifetch_req is initialized to read the instruction directly
|
||||
// into the CPU object's inst field.
|
||||
|
||||
Tick icache_latency = 0;
|
||||
bool icache_access = false;
|
||||
dcache_access = false; // assume no dcache access
|
||||
|
||||
//Fetch more instruction memory if necessary
|
||||
if(predecoder.needMoreBytes())
|
||||
{
|
||||
icache_access = true;
|
||||
ifetch_pkt->reinitFromRequest();
|
||||
|
||||
icache_latency = icachePort.sendAtomic(ifetch_pkt);
|
||||
// ifetch_req is initialized to read the instruction directly
|
||||
// into the CPU object's inst field.
|
||||
}
|
||||
|
||||
preExecute();
|
||||
|
||||
fault = curStaticInst->execute(this, traceData);
|
||||
postExecute();
|
||||
if(curStaticInst)
|
||||
{
|
||||
fault = curStaticInst->execute(this, traceData);
|
||||
postExecute();
|
||||
}
|
||||
|
||||
// @todo remove me after debugging with legion done
|
||||
if (curStaticInst && (!curStaticInst->isMicroOp() ||
|
||||
@@ -518,7 +529,8 @@ AtomicSimpleCPU::tick()
|
||||
instCnt++;
|
||||
|
||||
if (simulate_stalls) {
|
||||
Tick icache_stall = icache_latency - cycles(1);
|
||||
Tick icache_stall =
|
||||
icache_access ? icache_latency - cycles(1) : 0;
|
||||
Tick dcache_stall =
|
||||
dcache_access ? dcache_latency - cycles(1) : 0;
|
||||
Tick stall_cycles = (icache_stall + dcache_stall) / cycles(1);
|
||||
@@ -529,8 +541,8 @@ AtomicSimpleCPU::tick()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
advancePC(fault);
|
||||
if(predecoder.needMoreBytes())
|
||||
advancePC(fault);
|
||||
}
|
||||
|
||||
if (_status != Idle)
|
||||
|
||||
@@ -70,7 +70,7 @@ using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
BaseSimpleCPU::BaseSimpleCPU(Params *p)
|
||||
: BaseCPU(p), thread(NULL)
|
||||
: BaseCPU(p), thread(NULL), predecoder(NULL)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
|
||||
@@ -370,11 +370,16 @@ BaseSimpleCPU::preExecute()
|
||||
StaticInstPtr instPtr = NULL;
|
||||
|
||||
//Predecode, ie bundle up an ExtMachInst
|
||||
unsigned int result =
|
||||
predecode(extMachInst, thread->readPC(), inst, thread->getTC());
|
||||
//This should go away once the constructor can be set up properly
|
||||
predecoder.setTC(thread->getTC());
|
||||
//If more fetch data is needed, pass it in.
|
||||
if(predecoder.needMoreBytes())
|
||||
predecoder.moreBytes(thread->readPC(), 0, inst);
|
||||
else
|
||||
predecoder.process();
|
||||
//If an instruction is ready, decode it
|
||||
if (result & ExtMIReady)
|
||||
instPtr = StaticInst::decode(extMachInst);
|
||||
if (predecoder.extMachInstReady())
|
||||
instPtr = StaticInst::decode(predecoder.getExtMachInst());
|
||||
|
||||
//If we decoded an instruction and it's microcoded, start pulling
|
||||
//out micro ops
|
||||
@@ -446,9 +451,9 @@ BaseSimpleCPU::advancePC(Fault fault)
|
||||
fault->invoke(tc);
|
||||
thread->setMicroPC(0);
|
||||
thread->setNextMicroPC(1);
|
||||
} else {
|
||||
} else if (predecoder.needMoreBytes()) {
|
||||
//If we're at the last micro op for this instruction
|
||||
if (curStaticInst->isLastMicroOp()) {
|
||||
if (curStaticInst && curStaticInst->isLastMicroOp()) {
|
||||
//We should be working with a macro op
|
||||
assert(curMacroStaticInst);
|
||||
//Close out this macro op, and clean up the
|
||||
@@ -467,13 +472,9 @@ BaseSimpleCPU::advancePC(Fault fault)
|
||||
} else {
|
||||
// go to the next instruction
|
||||
thread->setPC(thread->readNextPC());
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
thread->setNextPC(thread->readNextNPC());
|
||||
thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
|
||||
assert(thread->readNextPC() != thread->readNextNPC());
|
||||
#else
|
||||
thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#ifndef __CPU_SIMPLE_BASE_HH__
|
||||
#define __CPU_SIMPLE_BASE_HH__
|
||||
|
||||
#include "arch/predecoder.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "cpu/base.hh"
|
||||
@@ -63,6 +64,10 @@ class Process;
|
||||
class RemoteGDB;
|
||||
class GDBListener;
|
||||
|
||||
namespace TheISA
|
||||
{
|
||||
class Predecoder;
|
||||
}
|
||||
class ThreadContext;
|
||||
class Checkpoint;
|
||||
|
||||
@@ -123,8 +128,8 @@ class BaseSimpleCPU : public BaseCPU
|
||||
// current instruction
|
||||
TheISA::MachInst inst;
|
||||
|
||||
// current extended machine instruction
|
||||
TheISA::ExtMachInst extMachInst;
|
||||
// The predecoder
|
||||
TheISA::Predecoder predecoder;
|
||||
|
||||
// Static data storage
|
||||
TheISA::LargestRead dataReg;
|
||||
|
||||
Reference in New Issue
Block a user