summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/checker/cpu_impl.hh2
-rw-r--r--src/cpu/exetrace.cc95
-rw-r--r--src/cpu/o3/fetch_impl.hh2
-rw-r--r--src/cpu/ozone/front_end_impl.hh2
-rw-r--r--src/cpu/simple/base.cc50
-rw-r--r--src/cpu/simple/base.hh1
-rw-r--r--src/cpu/simple_thread.hh20
-rw-r--r--src/cpu/static_inst.cc7
-rw-r--r--src/cpu/static_inst.hh22
-rw-r--r--src/cpu/thread_state.cc4
-rw-r--r--src/cpu/thread_state.hh10
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