diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/checker/cpu_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/exetrace.cc | 95 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/ozone/front_end_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 50 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 1 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh | 20 | ||||
-rw-r--r-- | src/cpu/static_inst.cc | 7 | ||||
-rw-r--r-- | src/cpu/static_inst.hh | 22 | ||||
-rw-r--r-- | src/cpu/thread_state.cc | 4 | ||||
-rw-r--r-- | src/cpu/thread_state.hh | 10 |
11 files changed, 155 insertions, 60 deletions
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index ba34c5cfc..36c7349e6 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -200,7 +200,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst) validateInst(inst); curStaticInst = StaticInst::decode(makeExtMI(machInst, - thread->readPC())); + thread->getTC())); #if FULL_SYSTEM thread->setInst(machInst); diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 8b1e60aea..9d85311bb 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -60,61 +60,66 @@ Trace::InstRecord::dump(ostream &outs) if (flags[PRINT_REG_DELTA]) { #if THE_ISA == SPARC_ISA - static uint64_t regs[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - static uint64_t ccr = 0; - static uint64_t y = 0; - static uint64_t floats[32]; - uint64_t newVal; - static const char * prefixes[4] = {"G", "O", "L", "I"}; - - char buf[256]; - sprintf(buf, "PC = 0x%016llx", thread->readNextPC()); - outs << buf; - sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC()); - outs << buf; - newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); - if(newVal != ccr) + //Don't print what happens for each micro-op, just print out + //once at the last op, and for regular instructions. + if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { - sprintf(buf, " CCR = 0x%016llx", newVal); + static uint64_t regs[32] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; + static uint64_t ccr = 0; + static uint64_t y = 0; + static uint64_t floats[32]; + uint64_t newVal; + static const char * prefixes[4] = {"G", "O", "L", "I"}; + + char buf[256]; + sprintf(buf, "PC = 0x%016llx", thread->readNextPC()); outs << buf; - ccr = newVal; - } - newVal = thread->readMiscReg(SparcISA::MISCREG_Y); - if(newVal != y) - { - sprintf(buf, " Y = 0x%016llx", newVal); + sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC()); outs << buf; - y = newVal; - } - for(int y = 0; y < 4; y++) - { - for(int x = 0; x < 8; x++) + newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); + if(newVal != ccr) + { + sprintf(buf, " CCR = 0x%016llx", newVal); + outs << buf; + ccr = newVal; + } + newVal = thread->readMiscReg(SparcISA::MISCREG_Y); + if(newVal != y) + { + sprintf(buf, " Y = 0x%016llx", newVal); + outs << buf; + y = newVal; + } + for(int y = 0; y < 4; y++) { - int index = x + 8 * y; - newVal = thread->readIntReg(index); - if(regs[index] != newVal) + for(int x = 0; x < 8; x++) { - sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal); - outs << buf; - regs[index] = newVal; + int index = x + 8 * y; + newVal = thread->readIntReg(index); + if(regs[index] != newVal) + { + sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal); + outs << buf; + regs[index] = newVal; + } } } - } - for(int y = 0; y < 32; y++) - { - newVal = thread->readFloatRegBits(2 * y, 64); - if(floats[y] != newVal) + for(int y = 0; y < 32; y++) { - sprintf(buf, " F%d = 0x%016llx", y, newVal); - outs << buf; - floats[y] = newVal; + newVal = thread->readFloatRegBits(2 * y, 64); + if(floats[y] != newVal) + { + sprintf(buf, " F%d = 0x%016llx", 2 * y, newVal); + outs << buf; + floats[y] = newVal; + } } + outs << endl; } - outs << endl; #endif } else if (flags[INTEL_FORMAT]) { diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index da75bfecf..e7bf83b20 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1118,7 +1118,7 @@ DefaultFetch<Impl>::fetch(bool &status_change) inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *> (&cacheData[tid][offset])); - ext_inst = TheISA::makeExtMI(inst, fetch_PC); + ext_inst = TheISA::makeExtMI(inst, cpu->tcBase(tid)); // Create a new DynInst from the instruction fetched. DynInstPtr instruction = new DynInst(ext_inst, fetch_PC, diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index eed6de6dd..36e87ec9c 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -883,7 +883,7 @@ FrontEnd<Impl>::getInstFromCacheline() // Get the instruction from the array of the cache line. inst = htog(*reinterpret_cast<MachInst *>(&cacheData[offset])); - ExtMachInst decode_inst = TheISA::makeExtMI(inst, PC); + ExtMachInst decode_inst = TheISA::makeExtMI(inst, tc); // Create a new DynInst from the instruction fetched. DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst), diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index a79d3c542..cbb3980cb 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -396,7 +396,20 @@ BaseSimpleCPU::preExecute() // decode the instruction inst = gtoh(inst); - curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC())); + //If we're not in the middle of a macro instruction + if (!curMacroStaticInst) { + StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); + if (instPtr->isMacroOp()) { + curMacroStaticInst = instPtr; + curStaticInst = curMacroStaticInst->fetchMicroOp(0); + } else { + curStaticInst = instPtr; + } + } else { + //Read the next micro op from the macro op + curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPC()); + } + traceData = Trace::getInstRecord(curTick, tc, curStaticInst, thread->readPC()); @@ -446,18 +459,35 @@ BaseSimpleCPU::advancePC(Fault fault) { if (fault != NoFault) { fault->invoke(tc); - } - else { - // go to the next instruction - thread->setPC(thread->readNextPC()); + } else { + //If we're at the last micro op for this instruction + if (curStaticInst->isLastMicroOp()) { + //We should be working with a macro op + assert(curMacroStaticInst); + //Close out this macro op, and clean up the + //microcode state + curMacroStaticInst = StaticInst::nullStaticInstPtr; + thread->setMicroPC(0); + thread->setNextMicroPC(1); + } + //If we're still in a macro op + if (curMacroStaticInst) { + //Advance the micro pc + thread->setMicroPC(thread->readNextMicroPC()); + //Advance the "next" micro pc. Note that there are no delay + //slots, and micro ops are "word" addressed. + thread->setNextMicroPC(thread->readNextMicroPC() + 1); + } 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()); + thread->setNextPC(thread->readNextNPC()); + thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); + assert(thread->readNextPC() != thread->readNextNPC()); #else - thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); + thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); #endif - + } } #if FULL_SYSTEM diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 57cfa3c2c..af6b6f835 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -128,6 +128,7 @@ class BaseSimpleCPU : public BaseCPU TheISA::IntReg dataReg; StaticInstPtr curStaticInst; + StaticInstPtr curMacroStaticInst; void checkForInterrupts(); Fault setupFetchRequest(Request *req); diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 6fa6500bd..fe22e6c43 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -377,6 +377,16 @@ class SimpleThread : public ThreadState regs.setPC(val); } + uint64_t readMicroPC() + { + return microPC; + } + + void setMicroPC(uint64_t val) + { + microPC = val; + } + uint64_t readNextPC() { return regs.readNextPC(); @@ -387,6 +397,16 @@ class SimpleThread : public ThreadState regs.setNextPC(val); } + uint64_t readNextMicroPC() + { + return nextMicroPC; + } + + void setNextMicroPC(uint64_t val) + { + nextMicroPC = val; + } + uint64_t readNextNPC() { return regs.readNextNPC(); diff --git a/src/cpu/static_inst.cc b/src/cpu/static_inst.cc index c311d2282..cb4a7cdf7 100644 --- a/src/cpu/static_inst.cc +++ b/src/cpu/static_inst.cc @@ -75,3 +75,10 @@ StaticInst::hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const return false; } +StaticInstPtr +StaticInst::fetchMicroOp(MicroPC micropc) +{ + panic("StaticInst::fetchMicroOp() called on instruction " + "that is not microcoded."); +} + diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 578d14191..523cfae40 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -67,6 +67,8 @@ namespace Trace { class InstRecord; } +typedef uint32_t MicroPC; + /** * Base, ISA-independent static instruction class. * @@ -139,6 +141,14 @@ class StaticInstBase : public RefCounted IsIprAccess, ///< Accesses IPRs IsUnverifiable, ///< Can't be verified by a checker + //Flags for microcode + IsMacroOp, ///< Is a macroop containing microops + IsMicroOp, ///< Is a microop + IsDelayedCommit, ///< This microop doesn't commit right away + IsLastMicroOp, ///< This microop ends a microop sequence + //This flag doesn't do anything yet + IsMicroBranch, ///< This microop branches within the microcode for a macroop + NumFlags }; @@ -230,6 +240,12 @@ class StaticInstBase : public RefCounted bool isQuiesce() const { return flags[IsQuiesce]; } bool isIprAccess() const { return flags[IsIprAccess]; } bool isUnverifiable() const { return flags[IsUnverifiable]; } + bool isMacroOp() const { return flags[IsMacroOp]; } + bool isMicroOp() const { return flags[IsMicroOp]; } + bool isDelayedCommit() const { return flags[IsDelayedCommit]; } + bool isLastMicroOp() const { return flags[IsLastMicroOp]; } + //This flag doesn't do anything yet + bool isMicroBranch() const { return flags[IsMicroBranch]; } //@} /// Operation class. Used to select appropriate function unit in issue. @@ -347,6 +363,12 @@ class StaticInst : public StaticInstBase #include "cpu/static_inst_exec_sigs.hh" /** + * Return the microop that goes with a particular micropc. This should + * only be defined/used in macroops which will contain microops + */ + virtual StaticInstPtr fetchMicroOp(MicroPC micropc); + + /** * Return the target address for a PC-relative branch. * Invalid if not a PC-relative branch (i.e. isDirectCtrl() * should be true). diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index 6a96560f1..c644ae8d7 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -42,13 +42,13 @@ ThreadState::ThreadState(int _cpuId, int _tid) : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL), - funcExeInst(0), storeCondFailures(0) + microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) #else ThreadState::ThreadState(int _cpuId, int _tid, Process *_process, short _asid, MemObject *mem) : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), process(_process), asid(_asid), - funcExeInst(0), storeCondFailures(0) + microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) #endif { numInst = 0; diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 14e033b7f..60353760c 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -200,6 +200,16 @@ struct ThreadState { */ TheISA::MachInst inst; + /** The current microcode pc for the currently executing macro + * operation. + */ + MicroPC microPC; + + /** The next microcode pc for the currently executing macro + * operation. + */ + MicroPC nextMicroPC; + public: /** * Temporary storage to pass the source address from copy_load to |