summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/checker/cpu.cc8
-rw-r--r--src/cpu/checker/cpu_impl.hh6
-rw-r--r--src/cpu/exetrace.cc95
-rw-r--r--src/cpu/memtest/memtest.cc44
-rw-r--r--src/cpu/memtest/memtest.hh16
-rw-r--r--src/cpu/o3/alpha/dyn_inst.hh2
-rw-r--r--src/cpu/o3/alpha/dyn_inst_impl.hh2
-rw-r--r--src/cpu/o3/fetch.hh2
-rw-r--r--src/cpu/o3/fetch_impl.hh9
-rw-r--r--src/cpu/o3/lsq_impl.hh9
-rw-r--r--src/cpu/o3/lsq_unit.hh4
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh2
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst.hh2
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst_impl.hh2
-rw-r--r--src/cpu/ozone/dyn_inst.hh2
-rw-r--r--src/cpu/ozone/dyn_inst_impl.hh2
-rw-r--r--src/cpu/ozone/front_end.hh2
-rw-r--r--src/cpu/ozone/front_end_impl.hh4
-rw-r--r--src/cpu/ozone/lw_lsq.hh4
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh2
-rw-r--r--src/cpu/quiesce_event.cc2
-rw-r--r--src/cpu/simple/atomic.cc18
-rw-r--r--src/cpu/simple/atomic.hh18
-rw-r--r--src/cpu/simple/base.cc52
-rw-r--r--src/cpu/simple/base.hh1
-rw-r--r--src/cpu/simple/timing.cc74
-rw-r--r--src/cpu/simple/timing.hh20
-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
32 files changed, 294 insertions, 173 deletions
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index f6d56eef6..9cb6b032e 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -34,10 +34,8 @@
#include "cpu/base.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
-#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
-#include "mem/packet_impl.hh"
-#include "sim/byteswap.hh"
+#include "cpu/thread_context.hh"
#if FULL_SYSTEM
#include "arch/vtophys.hh"
@@ -171,7 +169,7 @@ CheckerCPU::read(Addr addr, T &data, unsigned flags)
// translate to physical address
translateDataReadReq(memReq);
- Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
pkt->dataStatic(&data);
@@ -258,7 +256,7 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
T inst_data;
/*
// This code would work if the LSQ allowed for snooping.
- Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
pkt.dataStatic(&inst_data);
dcachePort->sendFunctional(pkt);
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 8aec79754..36c7349e6 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -37,8 +37,6 @@
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
-#include "mem/packet_impl.hh"
-#include "sim/byteswap.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
@@ -183,7 +181,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
}
if (fault == NoFault) {
- Packet *pkt = new Packet(memReq, Packet::ReadReq,
+ PacketPtr pkt = new Packet(memReq, Packet::ReadReq,
Packet::Broadcast);
pkt->dataStatic(&machInst);
@@ -202,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/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index 024cd7e41..91e073cf0 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -38,42 +38,42 @@
#include "base/misc.hh"
#include "base/statistics.hh"
-//#include "cpu/simple_thread.hh"
#include "cpu/memtest/memtest.hh"
+//#include "cpu/simple_thread.hh"
//#include "mem/cache/base_cache.hh"
+#include "mem/mem_object.hh"
+#include "mem/port.hh"
+#include "mem/packet.hh"
//#include "mem/physical.hh"
+#include "mem/request.hh"
#include "sim/builder.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"
-#include "mem/packet.hh"
-#include "mem/request.hh"
-#include "mem/port.hh"
-#include "mem/mem_object.hh"
using namespace std;
int TESTER_ALLOCATOR=0;
bool
-MemTest::CpuPort::recvTiming(Packet *pkt)
+MemTest::CpuPort::recvTiming(PacketPtr pkt)
{
memtest->completeRequest(pkt);
return true;
}
Tick
-MemTest::CpuPort::recvAtomic(Packet *pkt)
+MemTest::CpuPort::recvAtomic(PacketPtr pkt)
{
panic("MemTest doesn't expect recvAtomic callback!");
return curTick;
}
void
-MemTest::CpuPort::recvFunctional(Packet *pkt)
+MemTest::CpuPort::recvFunctional(PacketPtr pkt)
{
//Do nothing if we see one come through
- if (curTick != 0)//Supress warning durring initialization
- warn("Functional Writes not implemented in MemTester\n");
+// if (curTick != 0)//Supress warning durring initialization
+// warn("Functional Writes not implemented in MemTester\n");
//Need to find any response values that intersect and update
return;
}
@@ -94,7 +94,7 @@ MemTest::CpuPort::recvRetry()
}
void
-MemTest::sendPkt(Packet *pkt) {
+MemTest::sendPkt(PacketPtr pkt) {
if (atomic) {
cachePort.sendAtomic(pkt);
pkt->makeAtomicResponse();
@@ -113,7 +113,7 @@ MemTest::MemTest(const string &name,
// PhysicalMemory *check_mem,
unsigned _memorySize,
unsigned _percentReads,
-// unsigned _percentCopies,
+ unsigned _percentFunctional,
unsigned _percentUncacheable,
unsigned _progressInterval,
unsigned _percentSourceUnaligned,
@@ -130,7 +130,7 @@ MemTest::MemTest(const string &name,
// checkMem(check_mem),
size(_memorySize),
percentReads(_percentReads),
-// percentCopies(_percentCopies),
+ percentFunctional(_percentFunctional),
percentUncacheable(_percentUncacheable),
progressInterval(_progressInterval),
nextProgressMessage(_progressInterval),
@@ -204,7 +204,7 @@ printData(ostream &os, uint8_t *data, int nbytes)
}
void
-MemTest::completeRequest(Packet *pkt)
+MemTest::completeRequest(PacketPtr pkt)
{
MemTestSenderState *state =
dynamic_cast<MemTestSenderState *>(pkt->senderState);
@@ -345,8 +345,8 @@ MemTest::tick()
} else {
paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
}
- //bool probe = (random() % 2 == 1) && !req->isUncacheable();
- bool probe = false;
+ bool probe = (random() % 100 < percentFunctional) && !(flags & UNCACHEABLE);
+ //bool probe = false;
paddr &= ~((1 << access_size) - 1);
req->setPhys(paddr, 1 << access_size, flags);
@@ -381,13 +381,14 @@ MemTest::tick()
<< dec << curTick << endl;
}
- Packet *pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
pkt->dataDynamicArray(new uint8_t[req->getSize()]);
MemTestSenderState *state = new MemTestSenderState(result);
pkt->senderState = state;
if (probe) {
cachePort.sendFunctional(pkt);
+ pkt->makeAtomicResponse();
completeRequest(pkt);
} else {
// req->completionEvent = new MemCompleteEvent(req, result, this);
@@ -420,7 +421,7 @@ MemTest::tick()
<< dec << curTick << endl;
}
*/
- Packet *pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
uint8_t *pkt_data = new uint8_t[req->getSize()];
pkt->dataDynamicArray(pkt_data);
memcpy(pkt_data, &data, req->getSize());
@@ -431,6 +432,7 @@ MemTest::tick()
if (probe) {
cachePort.sendFunctional(pkt);
+ pkt->makeAtomicResponse();
completeRequest(pkt);
} else {
// req->completionEvent = new MemCompleteEvent(req, NULL, this);
@@ -499,7 +501,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
// SimObjectParam<PhysicalMemory *> check_mem;
Param<unsigned> memory_size;
Param<unsigned> percent_reads;
-// Param<unsigned> percent_copies;
+ Param<unsigned> percent_functional;
Param<unsigned> percent_uncacheable;
Param<unsigned> progress_interval;
Param<unsigned> percent_source_unaligned;
@@ -518,7 +520,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest)
// INIT_PARAM(check_mem, "check memory"),
INIT_PARAM(memory_size, "memory size"),
INIT_PARAM(percent_reads, "target read percentage"),
-// INIT_PARAM(percent_copies, "target copy percentage"),
+ INIT_PARAM(percent_functional, "percentage of access that are functional"),
INIT_PARAM(percent_uncacheable, "target uncacheable percentage"),
INIT_PARAM(progress_interval, "progress report interval (in accesses)"),
INIT_PARAM(percent_source_unaligned,
@@ -535,7 +537,7 @@ END_INIT_SIM_OBJECT_PARAMS(MemTest)
CREATE_SIM_OBJECT(MemTest)
{
return new MemTest(getInstanceName(), /*cache->getInterface(),*/ /*main_mem,*/
- /*check_mem,*/ memory_size, percent_reads, /*percent_copies,*/
+ /*check_mem,*/ memory_size, percent_reads, percent_functional,
percent_uncacheable, progress_interval,
percent_source_unaligned, percent_dest_unaligned,
trace_addr, max_loads, atomic);
diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh
index 5de41f0d8..edde4a3b2 100644
--- a/src/cpu/memtest/memtest.hh
+++ b/src/cpu/memtest/memtest.hh
@@ -55,7 +55,7 @@ class MemTest : public MemObject
// PhysicalMemory *check_mem,
unsigned _memorySize,
unsigned _percentReads,
-// unsigned _percentCopies,
+ unsigned _percentFunctional,
unsigned _percentUncacheable,
unsigned _progressInterval,
unsigned _percentSourceUnaligned,
@@ -102,11 +102,11 @@ class MemTest : public MemObject
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
@@ -133,7 +133,7 @@ class MemTest : public MemObject
};
// Request *dataReq;
- Packet *retryPkt;
+ PacketPtr retryPkt;
// MemInterface *cacheInterface;
// PhysicalMemory *mainMem;
// PhysicalMemory *checkMem;
@@ -144,7 +144,7 @@ class MemTest : public MemObject
unsigned size; // size of testing memory region
unsigned percentReads; // target percentage of read accesses
-// unsigned percentCopies; // target percentage of copy accesses
+ unsigned percentFunctional; // target percentage of functional accesses
unsigned percentUncacheable;
int id;
@@ -184,9 +184,9 @@ class MemTest : public MemObject
Stats::Scalar<> numCopiesStat;
// called by MemCompleteEvent::process()
- void completeRequest(Packet *pkt);
+ void completeRequest(PacketPtr pkt);
- void sendPkt(Packet *pkt);
+ void sendPkt(PacketPtr pkt);
void doRetry();
diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh
index 9dee610b6..294aadde8 100644
--- a/src/cpu/o3/alpha/dyn_inst.hh
+++ b/src/cpu/o3/alpha/dyn_inst.hh
@@ -86,7 +86,7 @@ class AlphaDynInst : public BaseDynInst<Impl>
Fault initiateAcc();
/** Completes the access. Only valid for memory operations. */
- Fault completeAcc(Packet *pkt);
+ Fault completeAcc(PacketPtr pkt);
private:
/** Initializes variables. */
diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh
index 2d1b4b309..b273a7b9b 100644
--- a/src/cpu/o3/alpha/dyn_inst_impl.hh
+++ b/src/cpu/o3/alpha/dyn_inst_impl.hh
@@ -100,7 +100,7 @@ AlphaDynInst<Impl>::initiateAcc()
template <class Impl>
Fault
-AlphaDynInst<Impl>::completeAcc(Packet *pkt)
+AlphaDynInst<Impl>::completeAcc(PacketPtr pkt)
{
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 280bf0e71..5555bff85 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -36,7 +36,7 @@
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/pc_event.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
#include "mem/port.hh"
#include "sim/eventq.hh"
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 07d4ebb42..e7bf83b20 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -78,9 +78,12 @@ DefaultFetch<Impl>::IcachePort::recvStatusChange(Status status)
template<class Impl>
bool
-DefaultFetch<Impl>::IcachePort::recvTiming(Packet *pkt)
+DefaultFetch<Impl>::IcachePort::recvTiming(PacketPtr pkt)
{
- fetch->processCacheCompletion(pkt);
+ if (pkt->isResponse()) {
+ fetch->processCacheCompletion(pkt);
+ }
+ //else Snooped a coherence request, just return
return true;
}
@@ -1115,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/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 7b7d1eb8e..317e23b14 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -63,7 +63,14 @@ template <class Impl>
bool
LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
{
- lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt);
+ if (pkt->isResponse()) {
+ lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt);
+ }
+ else {
+ //else it is a coherence request, maybe you need to do something
+ warn("Recieved a coherence request (Invalidate?), 03CPU doesn't"
+ "update LSQ for these\n");
+ }
return true;
}
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 11a02e7c7..1b207fdbc 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -40,7 +40,7 @@
#include "config/full_system.hh"
#include "base/hashmap.hh"
#include "cpu/inst_seq.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
#include "mem/port.hh"
/**
@@ -219,7 +219,7 @@ class LSQUnit {
void writeback(DynInstPtr &inst, PacketPtr pkt);
/** Handles completing the send of a store to memory. */
- void storePostSend(Packet *pkt);
+ void storePostSend(PacketPtr pkt);
/** Completes the store at the specified index. */
void completeStore(int store_idx);
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index 3f9db912f..d940d7cb3 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -763,7 +763,7 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
template <class Impl>
void
-LSQUnit<Impl>::storePostSend(Packet *pkt)
+LSQUnit<Impl>::storePostSend(PacketPtr pkt)
{
if (isStalled() &&
storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
diff --git a/src/cpu/o3/mips/dyn_inst.hh b/src/cpu/o3/mips/dyn_inst.hh
index 06bdfcec4..aa30bfa1e 100755
--- a/src/cpu/o3/mips/dyn_inst.hh
+++ b/src/cpu/o3/mips/dyn_inst.hh
@@ -87,7 +87,7 @@ class MipsDynInst : public BaseDynInst<Impl>
Fault initiateAcc();
/** Completes the access. Only valid for memory operations. */
- Fault completeAcc(Packet *pkt);
+ Fault completeAcc(PacketPtr pkt);
private:
/** Initializes variables. */
diff --git a/src/cpu/o3/mips/dyn_inst_impl.hh b/src/cpu/o3/mips/dyn_inst_impl.hh
index 57dec1ccf..5bc01b9b3 100755
--- a/src/cpu/o3/mips/dyn_inst_impl.hh
+++ b/src/cpu/o3/mips/dyn_inst_impl.hh
@@ -100,7 +100,7 @@ MipsDynInst<Impl>::initiateAcc()
template <class Impl>
Fault
-MipsDynInst<Impl>::completeAcc(Packet *pkt)
+MipsDynInst<Impl>::completeAcc(PacketPtr pkt)
{
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh
index 75ac464ec..e7390626e 100644
--- a/src/cpu/ozone/dyn_inst.hh
+++ b/src/cpu/ozone/dyn_inst.hh
@@ -133,7 +133,7 @@ class OzoneDynInst : public BaseDynInst<Impl>
Fault initiateAcc();
- Fault completeAcc(Packet *pkt);
+ Fault completeAcc(PacketPtr pkt);
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh
index db1460eba..0a1e1c139 100644
--- a/src/cpu/ozone/dyn_inst_impl.hh
+++ b/src/cpu/ozone/dyn_inst_impl.hh
@@ -108,7 +108,7 @@ OzoneDynInst<Impl>::initiateAcc()
template <class Impl>
Fault
-OzoneDynInst<Impl>::completeAcc(Packet *pkt)
+OzoneDynInst<Impl>::completeAcc(PacketPtr pkt)
{
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh
index 59cf9785c..2bdca35b9 100644
--- a/src/cpu/ozone/front_end.hh
+++ b/src/cpu/ozone/front_end.hh
@@ -129,7 +129,7 @@ class FrontEnd
const bool is_branch = false, const bool branch_taken = false);
DynInstPtr getInst();
- void processCacheCompletion(Packet *pkt);
+ void processCacheCompletion(PacketPtr pkt);
void addFreeRegs(int num_freed);
diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh
index c814ff9c7..36e87ec9c 100644
--- a/src/cpu/ozone/front_end_impl.hh
+++ b/src/cpu/ozone/front_end_impl.hh
@@ -74,7 +74,7 @@ FrontEnd<Impl>::IcachePort::recvStatusChange(Status status)
template<class Impl>
bool
-FrontEnd<Impl>::IcachePort::recvTiming(Packet *pkt)
+FrontEnd<Impl>::IcachePort::recvTiming(PacketPtr pkt)
{
fe->processCacheCompletion(pkt);
return true;
@@ -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/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh
index 9b93ce74f..dc58a8285 100644
--- a/src/cpu/ozone/lw_lsq.hh
+++ b/src/cpu/ozone/lw_lsq.hh
@@ -222,7 +222,7 @@ class OzoneLWLSQ {
void writeback(DynInstPtr &inst, PacketPtr pkt);
/** Handles completing the send of a store to memory. */
- void storePostSend(Packet *pkt, DynInstPtr &inst);
+ void storePostSend(PacketPtr pkt, DynInstPtr &inst);
/** Completes the store at the specified index. */
void completeStore(DynInstPtr &inst);
@@ -260,7 +260,7 @@ class OzoneLWLSQ {
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1); }
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); }
virtual bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index e523712da..1f3f18502 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -832,7 +832,7 @@ OzoneLWLSQ<Impl>::dumpInsts()
template <class Impl>
void
-OzoneLWLSQ<Impl>::storePostSend(Packet *pkt, DynInstPtr &inst)
+OzoneLWLSQ<Impl>::storePostSend(PacketPtr pkt, DynInstPtr &inst)
{
if (isStalled() &&
inst->seqNum == stallingStoreIsn) {
diff --git a/src/cpu/quiesce_event.cc b/src/cpu/quiesce_event.cc
index 8dd20db02..fa79e6d1e 100644
--- a/src/cpu/quiesce_event.cc
+++ b/src/cpu/quiesce_event.cc
@@ -28,6 +28,7 @@
* Authors: Kevin Lim
*/
+#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "cpu/quiesce_event.hh"
@@ -39,6 +40,7 @@ EndQuiesceEvent::EndQuiesceEvent(ThreadContext *_tc)
void
EndQuiesceEvent::process()
{
+ DPRINTF(Quiesce, "activating %s\n", tc->getCpuPtr()->name());
tc->activate();
}
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 87ecafd69..edba55b0d 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -32,7 +32,8 @@
#include "arch/utility.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/atomic.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -92,21 +93,21 @@ AtomicSimpleCPU::init()
}
bool
-AtomicSimpleCPU::CpuPort::recvTiming(Packet *pkt)
+AtomicSimpleCPU::CpuPort::recvTiming(PacketPtr pkt)
{
panic("AtomicSimpleCPU doesn't expect recvTiming callback!");
return true;
}
Tick
-AtomicSimpleCPU::CpuPort::recvAtomic(Packet *pkt)
+AtomicSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
{
- panic("AtomicSimpleCPU doesn't expect recvAtomic callback!");
+ //Snooping a coherence request, just return
return curTick;
}
void
-AtomicSimpleCPU::CpuPort::recvFunctional(Packet *pkt)
+AtomicSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
{
//No internal storage to update, just return
return;
@@ -262,7 +263,7 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
{
// use the CPU's statically allocated read request and packet objects
Request *req = data_read_req;
- Packet *pkt = data_read_pkt;
+ PacketPtr pkt = data_read_pkt;
req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
@@ -344,7 +345,7 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
// use the CPU's statically allocated write request and packet objects
Request *req = data_write_req;
- Packet *pkt = data_write_pkt;
+ PacketPtr pkt = data_write_pkt;
req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
@@ -450,7 +451,8 @@ AtomicSimpleCPU::tick()
for (int i = 0; i < width; ++i) {
numCycles++;
- checkForInterrupts();
+ if (!curStaticInst || !curStaticInst->isDelayedCommit())
+ checkForInterrupts();
Fault fault = setupFetchRequest(ifetch_req);
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 52afd76ef..0edca9369 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -92,11 +92,11 @@ class AtomicSimpleCPU : public BaseSimpleCPU
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
@@ -110,12 +110,12 @@ class AtomicSimpleCPU : public BaseSimpleCPU
CpuPort icachePort;
CpuPort dcachePort;
- Request *ifetch_req;
- Packet *ifetch_pkt;
- Request *data_read_req;
- Packet *data_read_pkt;
- Request *data_write_req;
- Packet *data_write_pkt;
+ Request *ifetch_req;
+ PacketPtr ifetch_pkt;
+ Request *data_read_req;
+ PacketPtr data_read_pkt;
+ Request *data_write_req;
+ PacketPtr data_write_pkt;
bool dcache_access;
Tick dcache_latency;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 522fe79aa..cbb3980cb 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -47,7 +47,7 @@
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "kern/kernel_stats.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/debug.hh"
@@ -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/timing.cc b/src/cpu/simple/timing.cc
index ad5c0e5d6..fe6775ea4 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -32,7 +32,8 @@
#include "arch/utility.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/timing.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -65,14 +66,14 @@ TimingSimpleCPU::init()
}
Tick
-TimingSimpleCPU::CpuPort::recvAtomic(Packet *pkt)
+TimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
{
panic("TimingSimpleCPU doesn't expect recvAtomic callback!");
return curTick;
}
void
-TimingSimpleCPU::CpuPort::recvFunctional(Packet *pkt)
+TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
{
//No internal storage to update, jusst return
return;
@@ -89,7 +90,7 @@ TimingSimpleCPU::CpuPort::recvStatusChange(Status status)
void
-TimingSimpleCPU::CpuPort::TickEvent::schedule(Packet *_pkt, Tick t)
+TimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t)
{
pkt = _pkt;
Event::schedule(t);
@@ -268,7 +269,7 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access.
if (fault == NoFault) {
- Packet *pkt =
+ PacketPtr pkt =
new Packet(req, Packet::ReadReq, Packet::Broadcast);
pkt->dataDynamic<T>(new T);
@@ -426,7 +427,8 @@ TimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
void
TimingSimpleCPU::fetch()
{
- checkForInterrupts();
+ if (!curStaticInst || !curStaticInst->isDelayedCommit())
+ checkForInterrupts();
Request *ifetch_req = new Request();
ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0);
@@ -470,7 +472,7 @@ TimingSimpleCPU::advanceInst(Fault fault)
void
-TimingSimpleCPU::completeIfetch(Packet *pkt)
+TimingSimpleCPU::completeIfetch(PacketPtr pkt)
{
// received a response from the icache: execute the received
// instruction
@@ -526,19 +528,25 @@ TimingSimpleCPU::IcachePort::ITickEvent::process()
}
bool
-TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt)
+TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
{
- // delay processing of returned data until next CPU clock edge
- Tick time = pkt->req->getTime();
- while (time < curTick)
- time += lat;
+ if (pkt->isResponse()) {
+ // delay processing of returned data until next CPU clock edge
+ Tick time = pkt->req->getTime();
+ while (time < curTick)
+ time += lat;
- if (time == curTick)
- cpu->completeIfetch(pkt);
- else
- tickEvent.schedule(pkt, time);
+ if (time == curTick)
+ cpu->completeIfetch(pkt);
+ else
+ tickEvent.schedule(pkt, time);
- return true;
+ return true;
+ }
+ else {
+ //Snooping a Coherence Request, do nothing
+ return true;
+ }
}
void
@@ -548,7 +556,7 @@ TimingSimpleCPU::IcachePort::recvRetry()
// waiting to transmit
assert(cpu->ifetch_pkt != NULL);
assert(cpu->_status == IcacheRetry);
- Packet *tmp = cpu->ifetch_pkt;
+ PacketPtr tmp = cpu->ifetch_pkt;
if (sendTiming(tmp)) {
cpu->_status = IcacheWaitResponse;
cpu->ifetch_pkt = NULL;
@@ -556,7 +564,7 @@ TimingSimpleCPU::IcachePort::recvRetry()
}
void
-TimingSimpleCPU::completeDataAccess(Packet *pkt)
+TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
{
// received a response from the dcache: complete the load or store
// instruction
@@ -598,19 +606,25 @@ TimingSimpleCPU::completeDrain()
}
bool
-TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt)
+TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{
- // delay processing of returned data until next CPU clock edge
- Tick time = pkt->req->getTime();
- while (time < curTick)
- time += lat;
+ if (pkt->isResponse()) {
+ // delay processing of returned data until next CPU clock edge
+ Tick time = pkt->req->getTime();
+ while (time < curTick)
+ time += lat;
- if (time == curTick)
- cpu->completeDataAccess(pkt);
- else
- tickEvent.schedule(pkt, time);
+ if (time == curTick)
+ cpu->completeDataAccess(pkt);
+ else
+ tickEvent.schedule(pkt, time);
- return true;
+ return true;
+ }
+ else {
+ //Snooping a coherence req, do nothing
+ return true;
+ }
}
void
@@ -626,7 +640,7 @@ TimingSimpleCPU::DcachePort::recvRetry()
// waiting to transmit
assert(cpu->dcache_pkt != NULL);
assert(cpu->_status == DcacheRetry);
- Packet *tmp = cpu->dcache_pkt;
+ PacketPtr tmp = cpu->dcache_pkt;
if (sendTiming(tmp)) {
cpu->_status = DcacheWaitResponse;
// memory system takes ownership of packet
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 988ddeded..577e13e40 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -84,9 +84,9 @@ class TimingSimpleCPU : public BaseSimpleCPU
protected:
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
@@ -96,13 +96,13 @@ class TimingSimpleCPU : public BaseSimpleCPU
struct TickEvent : public Event
{
- Packet *pkt;
+ PacketPtr pkt;
TimingSimpleCPU *cpu;
TickEvent(TimingSimpleCPU *_cpu)
:Event(&mainEventQueue), cpu(_cpu) {}
const char *description() { return "Timing CPU clock event"; }
- void schedule(Packet *_pkt, Tick t);
+ void schedule(PacketPtr _pkt, Tick t);
};
};
@@ -117,7 +117,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
virtual void recvRetry();
@@ -144,7 +144,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
virtual void recvRetry();
@@ -163,8 +163,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
IcachePort icachePort;
DcachePort dcachePort;
- Packet *ifetch_pkt;
- Packet *dcache_pkt;
+ PacketPtr ifetch_pkt;
+ PacketPtr dcache_pkt;
int cpu_id;
Tick previousTick;
@@ -192,8 +192,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
void fetch();
- void completeIfetch(Packet *);
- void completeDataAccess(Packet *);
+ void completeIfetch(PacketPtr );
+ void completeDataAccess(PacketPtr );
void advanceInst(Fault fault);
private:
void completeDrain();
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