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:
parent
83a0fd24f7
commit
716e447da8
7 changed files with 39 additions and 27 deletions
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -76,7 +76,6 @@ class ExecutionUnit : public Resource {
|
|||
Stats::Scalar executions;
|
||||
Tick lastExecuteTick;
|
||||
Tick lastControlTick;
|
||||
Tick serializeTick;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue