summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2008-10-12 16:59:55 -0700
committerGabe Black <gblack@eecs.umich.edu>2008-10-12 16:59:55 -0700
commitc9ea0b73492bf116c836c54199898f29d9664bc0 (patch)
tree3490b28e25623c49be123d50cf2004ffe1a83e01 /src/cpu
parent2736086d7c67a24d9eb87827a22a2b352e342ba2 (diff)
downloadgem5-c9ea0b73492bf116c836c54199898f29d9664bc0.tar.xz
CPU: Make the highest order bit in the micro pc determine if it's combinational or from the ROM.
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/simple/base.cc29
-rw-r--r--src/cpu/static_inst.hh20
2 files changed, 36 insertions, 13 deletions
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 48e5db347..d207bda14 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -368,9 +368,13 @@ BaseSimpleCPU::preExecute()
// decode the instruction
inst = gtoh(inst);
- //If we're not in the middle of a macro instruction
- if (!curMacroStaticInst) {
+ MicroPC upc = thread->readMicroPC();
+ if (isRomMicroPC(upc)) {
+ stayAtPC = false;
+ curStaticInst = microcodeRom.fetchMicroop(upc, curMacroStaticInst);
+ } else if (!curMacroStaticInst) {
+ //We're not in the middle of a macro instruction
StaticInstPtr instPtr = NULL;
//Predecode, ie bundle up an ExtMachInst
@@ -401,15 +405,13 @@ BaseSimpleCPU::preExecute()
//out micro ops
if (instPtr && instPtr->isMacroop()) {
curMacroStaticInst = instPtr;
- curStaticInst = curMacroStaticInst->
- fetchMicroop(thread->readMicroPC());
+ curStaticInst = curMacroStaticInst->fetchMicroop(upc);
} else {
curStaticInst = instPtr;
}
} else {
//Read the next micro op from the macro op
- curStaticInst = curMacroStaticInst->
- fetchMicroop(thread->readMicroPC());
+ curStaticInst = curMacroStaticInst->fetchMicroop(upc);
}
//If we decoded an instruction this "tick", record information about it.
@@ -469,22 +471,23 @@ BaseSimpleCPU::advancePC(Fault fault)
if (fault != NoFault) {
curMacroStaticInst = StaticInst::nullStaticInstPtr;
predecoder.reset();
- thread->setMicroPC(0);
- thread->setNextMicroPC(1);
+ thread->setMicroPC(normalMicroPC(0));
+ thread->setNextMicroPC(normalMicroPC(1));
fault->invoke(tc);
} else {
//If we're at the last micro op for this instruction
if (curStaticInst && curStaticInst->isLastMicroop()) {
- //We should be working with a macro op
- assert(curMacroStaticInst);
+ //We should be working with a macro op or be in the ROM
+ assert(curMacroStaticInst ||
+ isRomMicroPC(thread->readMicroPC()));
//Close out this macro op, and clean up the
//microcode state
curMacroStaticInst = StaticInst::nullStaticInstPtr;
- thread->setMicroPC(0);
- thread->setNextMicroPC(1);
+ thread->setMicroPC(normalMicroPC(0));
+ thread->setNextMicroPC(normalMicroPC(1));
}
//If we're still in a macro op
- if (curMacroStaticInst) {
+ if (curMacroStaticInst || isRomMicroPC(thread->readMicroPC())) {
//Advance the micro pc
thread->setMicroPC(thread->readNextMicroPC());
//Advance the "next" micro pc. Note that there are no delay
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 8a1b3e749..c9eb6ff24 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -74,6 +74,26 @@ namespace Trace {
typedef uint32_t MicroPC;
+static const MicroPC MicroPCRomBit = 1 << (sizeof(MicroPC) * 8 - 1);
+
+static inline MicroPC
+romMicroPC(MicroPC upc)
+{
+ return upc | MicroPCRomBit;
+}
+
+static inline MicroPC
+normalMicroPC(MicroPC upc)
+{
+ return upc & ~MicroPCRomBit;
+}
+
+static inline bool
+isRomMicroPC(MicroPC upc)
+{
+ return MicroPCRomBit & upc;
+}
+
/**
* Base, ISA-independent static instruction class.
*