inorder: handle serializing instructions

including IPR accesses and store-conditionals. These class of instructions will not
execute correctly in a superscalar machine
This commit is contained in:
Korey Sewell 2011-06-19 21:43:41 -04:00
parent 83a0fd24f7
commit 716e447da8
7 changed files with 39 additions and 27 deletions

View file

@ -1093,6 +1093,7 @@ PipelineStage::sendInstToNextStage(DynInstPtr inst)
// Take note of trace data for this inst & stage
if (inst->traceData) {
//@todo: exec traces are broke. fix them
inst->traceData->setStageCycle(stageNum, curTick());
}

View file

@ -272,6 +272,7 @@ Resource::rejectRequest(DynInstPtr inst)
void
Resource::execute(int slot_idx)
{
//@todo: have each resource print out command their executing
DPRINTF(Resource, "[tid:%i]: Executing %s resource.\n",
reqs[slot_idx]->getTid(), name());
reqs[slot_idx]->setCompleted(true);

View file

@ -105,8 +105,10 @@ CacheUnit::CachePort::recvTiming(Packet *pkt)
pkt->getAddr());
else if (pkt->isResponse())
cachePortUnit->processCacheCompletion(pkt);
else
DPRINTF(Cache, "Received snoop pkt %x,Ignoring\n", pkt->getAddr());
else {
//@note: depending on consistency model, update here
DPRINTF(InOrderCachePort, "Received snoop pkt %x,Ignoring\n", pkt->getAddr());
}
return true;
}

View file

@ -45,7 +45,7 @@ ExecutionUnit::ExecutionUnit(string res_name, int res_id, int res_width,
int res_latency, InOrderCPU *_cpu,
ThePipeline::Params *params)
: Resource(res_name, res_id, res_width, res_latency, _cpu),
lastExecuteTick(0), lastControlTick(0), serializeTick(0)
lastExecuteTick(0), lastControlTick(0)
{ }
void
@ -103,13 +103,6 @@ ExecutionUnit::execute(int slot_num)
#if TRACING_ON
InstSeqNum seq_num = inst->seqNum;
#endif
if (cur_tick == serializeTick) {
DPRINTF(InOrderExecute, "Can not execute [tid:%i][sn:%i][PC:%s] %s. "
"All instructions are being serialized this cycle\n",
inst->readTid(), seq_num, inst->pcState(), inst->instName());
exec_req->done(false);
return;
}
switch (exec_req->cmd)
{
@ -131,15 +124,9 @@ ExecutionUnit::execute(int slot_num)
lastExecuteTick = cur_tick;
}
//@todo: handle address generation here
assert(!inst->isMemRef());
if (inst->isSerializeAfter()) {
serializeTick = cur_tick;
DPRINTF(InOrderExecute, "Serializing execution after [tid:%i] "
"[sn:%i] [PC:%s] %s.\n", inst->readTid(), seq_num,
inst->pcState(), inst->instName());
}
if (inst->isControl()) {
if (lastControlTick == cur_tick) {
DPRINTF(InOrderExecute, "Can not Execute More than One Control "
@ -219,11 +206,12 @@ ExecutionUnit::execute(int slot_num)
#if TRACING_ON
for (int didx = 0; didx < inst->numDestRegs(); didx++)
if (inst->resultType(didx) == InOrderDynInst::Float ||
inst->resultType(didx) == InOrderDynInst::FloatBits ||
inst->resultType(didx) == InOrderDynInst::Double)
DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Dest result %i "
"of FP execution is %08f (%x).\n", inst->readTid(),
seq_num, didx, inst->readFloatResult(didx),
inst->readIntResult(didx));
inst->readFloatBitsResult(didx));
else
DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Dest result %i "
"of Int execution is 0x%x.\n", inst->readTid(),

View file

@ -76,7 +76,6 @@ class ExecutionUnit : public Resource {
Stats::Scalar executions;
Tick lastExecuteTick;
Tick lastControlTick;
Tick serializeTick;
};

View file

@ -52,7 +52,8 @@ UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width,
for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
serializeOnNextInst[tid] = false;
serializeAfterSeqNum[tid] = 0;
regDepMap[tid] = &cpu->archRegDepMap[tid];
}
@ -152,11 +153,12 @@ UseDefUnit::findRequest(DynInstPtr inst)
void
UseDefUnit::execute(int slot_idx)
{
// After this is working, change this to a reinterpret cast
// for performance considerations
UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_idx]);
assert(ud_req);
DynInstPtr inst = ud_req->inst;
ThreadID tid = inst->readTid();
InstSeqNum seq_num = inst->seqNum;
int ud_idx = ud_req->useDefIdx;
if (inst->fault != NoFault) {
DPRINTF(InOrderUseDef,
"[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
@ -166,11 +168,28 @@ UseDefUnit::execute(int slot_idx)
return;
}
ThreadID tid = inst->readTid();
InstSeqNum seq_num = inst->seqNum;
int ud_idx = ud_req->useDefIdx;
if (serializeOnNextInst[tid] &&
seq_num > serializeAfterSeqNum[tid]) {
inst->setSerializeBefore();
serializeOnNextInst[tid] = false;
}
if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
cpu->instList[tid].front() != inst) {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize before instruction encountered."
" Blocking until pipeline is clear.\n", tid, seq_num);
ud_req->done(false);
return;
} else if (inst->isStoreConditional() || inst->isSerializeAfter()) {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize after instruction encountered."
" Blocking until pipeline is clear.\n", tid, seq_num);
serializeOnNextInst[tid] = true;
serializeAfterSeqNum[tid] = seq_num;
}
// If there is a non-speculative instruction
// in the pipeline then stall instructions here
// ---
if (*nonSpecInstActive[tid] == true && seq_num > *nonSpecSeqNum[tid]) {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because"
"there is non-speculative instruction [sn:%i] has not "

View file

@ -76,9 +76,11 @@ class UseDefUnit : public Resource {
RegDepMap *regDepMap[ThePipeline::MaxThreads];
bool *nonSpecInstActive[ThePipeline::MaxThreads];
InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
bool serializeOnNextInst[ThePipeline::MaxThreads];
InstSeqNum serializeAfterSeqNum[ThePipeline::MaxThreads];
Stats::Average uniqueRegsPerSwitch;
std::map<RegIndex, bool> uniqueIntRegMap;
std::map<RegIndex, bool> uniqueFloatRegMap;