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:
@@ -34,11 +34,11 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "sim/eventq.hh"
|
||||
#include "mem/mem_object.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/interrupts.hh"
|
||||
@@ -50,6 +50,11 @@ class ThreadContext;
|
||||
class System;
|
||||
class Port;
|
||||
|
||||
namespace TheISA
|
||||
{
|
||||
class Predecoder;
|
||||
}
|
||||
|
||||
class CPUProgressEvent : public Event
|
||||
{
|
||||
protected:
|
||||
@@ -125,6 +130,7 @@ class BaseCPU : public MemObject
|
||||
|
||||
protected:
|
||||
std::vector<ThreadContext *> threadContexts;
|
||||
std::vector<TheISA::Predecoder *> predecoders;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define __CPU_O3_FETCH_HH__
|
||||
|
||||
#include "arch/utility.hh"
|
||||
#include "arch/predecoder.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "base/timebuf.hh"
|
||||
#include "cpu/pc_event.hh"
|
||||
@@ -338,6 +339,9 @@ class DefaultFetch
|
||||
/** BPredUnit. */
|
||||
BPredUnit branchPred;
|
||||
|
||||
/** Predecoder. */
|
||||
TheISA::Predecoder predecoder;
|
||||
|
||||
/** Per-thread fetch PC. */
|
||||
Addr PC[Impl::MaxThreads];
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ DefaultFetch<Impl>::IcachePort::recvRetry()
|
||||
template<class Impl>
|
||||
DefaultFetch<Impl>::DefaultFetch(Params *params)
|
||||
: branchPred(params),
|
||||
predecoder(NULL),
|
||||
decodeToFetchDelay(params->decodeToFetchDelay),
|
||||
renameToFetchDelay(params->renameToFetchDelay),
|
||||
iewToFetchDelay(params->iewToFetchDelay),
|
||||
@@ -1117,9 +1118,10 @@ DefaultFetch<Impl>::fetch(bool &status_change)
|
||||
inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
|
||||
(&cacheData[tid][offset]));
|
||||
|
||||
//unsigned int result =
|
||||
TheISA::predecode(ext_inst, fetch_PC, inst,
|
||||
cpu->thread[tid]->getTC());
|
||||
predecoder.setTC(cpu->thread[tid]->getTC());
|
||||
predecoder.moreBytes(fetch_PC, 0, inst);
|
||||
|
||||
ext_inst = predecoder.getExtMachInst();
|
||||
|
||||
// Create a new DynInst from the instruction fetched.
|
||||
DynInstPtr instruction = new DynInst(ext_inst,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "arch/utility.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/hashmap.hh"
|
||||
|
||||
Reference in New Issue
Block a user