From ce18d900a17cdda2cc041b51c56e6c84fb155331 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 13 Mar 2007 16:13:21 +0000 Subject: Replaced makeExtMI with predecode. Removed the getOpcode function from StaticInst which only made sense for Alpha. Started implementing the x86 predecoder. --HG-- extra : convert_revision : a13ea257c8943ef25e9bc573024a99abacf4a70d --- src/cpu/o3/fetch_impl.hh | 10 +++------- src/cpu/simple/base.cc | 40 +++++++++++++++++++++------------------- src/cpu/simple/base.hh | 6 ++++-- src/cpu/static_inst.hh | 5 +---- 4 files changed, 29 insertions(+), 32 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index ac0149d18..89faeb1ab 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1117,13 +1117,9 @@ DefaultFetch::fetch(bool &status_change) inst = TheISA::gtoh(*reinterpret_cast (&cacheData[tid][offset])); -#if THE_ISA == ALPHA_ISA - ext_inst = TheISA::makeExtMI(inst, fetch_PC); -#elif THE_ISA == SPARC_ISA - ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC()); -#elif THE_ISA == MIPS_ISA - ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC()); -#endif + //unsigned int result = + TheISA::predecode(ext_inst, fetch_PC, inst, + cpu->thread[tid]->getTC()); // Create a new DynInst from the instruction fetched. DynInstPtr instruction = new DynInst(ext_inst, diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index f6c109127..c27be02bf 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -367,18 +367,18 @@ BaseSimpleCPU::preExecute() inst = gtoh(inst); //If we're not in the middle of a macro instruction if (!curMacroStaticInst) { -#if THE_ISA == ALPHA_ISA - StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC())); -#elif THE_ISA == SPARC_ISA - StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); -#elif THE_ISA == X86_ISA - StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); -#elif THE_ISA == MIPS_ISA - //Mips doesn't do anything in it's MakeExtMI function right now, - //so it won't be called. - StaticInstPtr instPtr = StaticInst::decode(inst); -#endif - if (instPtr->isMacroOp()) { + StaticInstPtr instPtr = NULL; + + //Predecode, ie bundle up an ExtMachInst + unsigned int result = + predecode(extMachInst, thread->readPC(), inst, thread->getTC()); + //If an instruction is ready, decode it + if (result & ExtMIReady) + instPtr = StaticInst::decode(extMachInst); + + //If we decoded an instruction and it's microcoded, start pulling + //out micro ops + if (instPtr && instPtr->isMacroOp()) { curMacroStaticInst = instPtr; curStaticInst = curMacroStaticInst-> fetchMicroOp(thread->readMicroPC()); @@ -391,17 +391,19 @@ BaseSimpleCPU::preExecute() fetchMicroOp(thread->readMicroPC()); } + //If we decoded an instruction this "tick", record information about it. + if(curStaticInst) + { + traceData = Trace::getInstRecord(curTick, tc, curStaticInst, + thread->readPC()); - traceData = Trace::getInstRecord(curTick, tc, curStaticInst, - thread->readPC()); - - DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", - curStaticInst->getName(), curStaticInst->getOpcode(), - curStaticInst->machInst); + DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n", + curStaticInst->getName(), curStaticInst->machInst); #if FULL_SYSTEM - thread->setInst(inst); + thread->setInst(inst); #endif // FULL_SYSTEM + } } void diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 980ea2f96..10787c474 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -74,7 +74,6 @@ namespace Trace { class BaseSimpleCPU : public BaseCPU { protected: - typedef TheISA::MachInst MachInst; typedef TheISA::MiscReg MiscReg; typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; @@ -122,7 +121,10 @@ class BaseSimpleCPU : public BaseCPU #endif // current instruction - MachInst inst; + TheISA::MachInst inst; + + // current extended machine instruction + TheISA::ExtMachInst extMachInst; // Static data storage TheISA::LargestRead dataReg; diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 416c8ab56..3424c3086 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -439,9 +439,6 @@ class StaticInst : public StaticInstBase //This is defined as inline below. static StaticInstPtr decode(ExtMachInst mach_inst); - /// Return opcode of machine instruction - uint32_t getOpcode() { return bits(machInst, 31, 26);} - /// Return name of machine instruction std::string getName() { return mnemonic; } }; @@ -474,7 +471,7 @@ class StaticInstPtr : public RefCountingPtr /// Construct directly from machine instruction. /// Calls StaticInst::decode(). - StaticInstPtr(TheISA::ExtMachInst mach_inst) + explicit StaticInstPtr(TheISA::ExtMachInst mach_inst) : RefCountingPtr(StaticInst::decode(mach_inst)) { } -- cgit v1.2.3 From a2b56088fb4d12aee73ecfeaba88cfa46f98567e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 15 Mar 2007 02:47:42 +0000 Subject: 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 --- src/cpu/base.hh | 8 +++++++- src/cpu/o3/fetch.hh | 4 ++++ src/cpu/o3/fetch_impl.hh | 8 +++++--- src/cpu/simple/atomic.cc | 32 ++++++++++++++++++++++---------- src/cpu/simple/base.cc | 23 ++++++++++++----------- src/cpu/simple/base.hh | 9 +++++++-- src/cpu/static_inst.hh | 1 + 7 files changed, 58 insertions(+), 27 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/base.hh b/src/cpu/base.hh index d4213887d..85f5b7725 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -34,11 +34,11 @@ #include +#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 threadContexts; + std::vector predecoders; public: diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 8347ed775..da7ce00f5 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -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]; diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 89faeb1ab..1256dd233 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -103,6 +103,7 @@ DefaultFetch::IcachePort::recvRetry() template DefaultFetch::DefaultFetch(Params *params) : branchPred(params), + predecoder(NULL), decodeToFetchDelay(params->decodeToFetchDelay), renameToFetchDelay(params->renameToFetchDelay), iewToFetchDelay(params->iewToFetchDelay), @@ -1117,9 +1118,10 @@ DefaultFetch::fetch(bool &status_change) inst = TheISA::gtoh(*reinterpret_cast (&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, diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index df7e780e6..0361db012 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -500,17 +500,28 @@ AtomicSimpleCPU::tick() Fault fault = setupFetchRequest(ifetch_req); if (fault == NoFault) { - ifetch_pkt->reinitFromRequest(); + Tick icache_latency = 0; + bool icache_access = false; + dcache_access = false; // assume no dcache access - Tick icache_latency = icachePort.sendAtomic(ifetch_pkt); - // ifetch_req is initialized to read the instruction directly - // into the CPU object's inst field. + //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. + } - dcache_access = false; // assume no dcache access 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) diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index c27be02bf..2ad328542 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -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 } } diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 10787c474..a7686bbb1 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -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; diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 3424c3086..a58ac85d6 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -35,6 +35,7 @@ #include #include "arch/isa_traits.hh" +#include "arch/utility.hh" #include "sim/faults.hh" #include "base/bitfield.hh" #include "base/hashmap.hh" -- cgit v1.2.3