inorder: bug in mdu

segfault was caused by squashed multiply thats in the process of an event.
use isProcessing flag to handle this and cleanup the MDU code
This commit is contained in:
Korey Sewell 2011-06-19 21:43:38 -04:00
parent 4c979f9325
commit c95fe261ab
5 changed files with 78 additions and 55 deletions

View file

@ -297,16 +297,18 @@ Resource::setupSquash(DynInstPtr inst, int stage_num, ThreadID tid)
cpu->resPool->scheduleEvent(
(InOrderCPU::CPUEventType)ResourcePool::SquashAll, inst, 0);
}
void
Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
ThreadID tid)
{
for (int i = 0; i < width; i++) {
ResReqPtr req_ptr = reqs[i];
DynInstPtr inst = req_ptr->getInst();
if (req_ptr->valid &&
req_ptr->getInst()->readTid() == tid &&
req_ptr->getInst()->seqNum > squash_seq_num) {
inst->readTid() == tid &&
inst->seqNum > squash_seq_num) {
DPRINTF(Resource, "[tid:%i]: Squashing [sn:%i].\n",
req_ptr->getInst()->readTid(),

View file

@ -389,7 +389,7 @@ class ResourceRequest
/** Get/Set IsProcessing variables */
bool isProcessing() { return processing; }
void setProcessing() { processing = true; }
void setProcessing(bool cond = true) { processing = cond; }
/** Get/Set IsWaiting variables */
bool isMemStall() { return memStall; }

View file

@ -79,7 +79,10 @@ ResourcePool::ResourcePool(InOrderCPU *_cpu, ThePipeline::Params *params)
stage_width, 0, _cpu, params));
resources.push_back(new MultDivUnit("mult_div_unit", MDU,
stage_width * 2, 0, _cpu, params));
stage_width * 2,
0,
_cpu,
params));
memObjects.push_back(DCache);
resources.push_back(new CacheUnit("dcache_port", DCache,

View file

@ -86,25 +86,6 @@ MultDivUnit::init()
initSlots();
}
int
MultDivUnit::findSlot(DynInstPtr inst)
{
DPRINTF(InOrderMDU, "Finding slot for inst:%i\n | slots-free:%i | "
"slots-used:%i\n", inst->seqNum, slotsAvail(), slotsInUse());
return Resource::findSlot(inst);
}
void
MultDivUnit::freeSlot(int slot_idx)
{
DPRINTF(InOrderMDU, "Freeing slot for inst:%i\n | slots-free:%i | "
"slots-used:%i\n", reqs[slot_idx]->getInst()->seqNum,
slotsAvail(), slotsInUse());
Resource::freeSlot(slot_idx);
}
//@TODO: Should we push this behavior into base-class to generically
// accomodate all multicyle resources?
void
@ -124,7 +105,7 @@ MultDivUnit::requestAgain(DynInstPtr inst, bool &service_request)
"[tid:%i]: [sn:%i]: Updating the command for this "
"instruction\n", inst->readTid(), inst->seqNum);
} else {
// If same command, just check to see if memory access was completed
// If same command, just check to see if access was completed
// but dont try to re-execute
DPRINTF(InOrderMDU,
"[tid:%i]: [sn:%i]: requesting this resource again\n",
@ -212,41 +193,47 @@ MultDivUnit::execute(int slot_num)
ResourceRequest* mult_div_req = reqs[slot_num];
DynInstPtr inst = reqs[slot_num]->inst;
DPRINTF(InOrderMDU, "Executing [sn:%i] ...\n", slot_num);
switch (mult_div_req->cmd)
{
case StartMultDiv:
DPRINTF(InOrderMDU, "Start MDU called ...\n");
{
DPRINTF(InOrderMDU, "Start MDU called ...\n");
if (inst->opClass() == IntMultOp) {
scheduleEvent(slot_num, multLatency);
} else if (inst->opClass() == IntDivOp) {
int op_size = getDivOpSize(inst);
OpClass op_class = inst->opClass();
if (op_class == IntMultOp) {
scheduleEvent(slot_num, multLatency);
} else if (op_class == IntDivOp) {
int op_size = getDivOpSize(inst);
switch (op_size)
{
case 8:
scheduleEvent(slot_num, div8Latency);
break;
switch (op_size)
{
case 8:
scheduleEvent(slot_num, div8Latency);
break;
case 16:
scheduleEvent(slot_num, div16Latency);
break;
case 16:
scheduleEvent(slot_num, div16Latency);
break;
case 24:
scheduleEvent(slot_num, div24Latency);
break;
case 24:
scheduleEvent(slot_num, div24Latency);
break;
case 32:
scheduleEvent(slot_num, div32Latency);
break;
case 32:
scheduleEvent(slot_num, div32Latency);
break;
}
lastDivSize = op_size;
}
lastDivSize = op_size;
// Allow to pass through to next stage while
// event processes
mult_div_req->setProcessing();
mult_div_req->setCompleted();
}
// Allow to pass through to next stage while
// event processes
mult_div_req->setCompleted();
break;
case MultDiv:
@ -264,7 +251,7 @@ MultDivUnit::execute(int slot_num)
// counting down the time
{
DPRINTF(InOrderMDU, "End MDU called ...\n");
if (mult_div_req->getInst()->isExecuted()) {
if (!mult_div_req->isProcessing()) {
DPRINTF(InOrderMDU, "Mult/Div finished.\n");
mult_div_req->done();
} else {
@ -295,7 +282,6 @@ MultDivUnit::exeMulDiv(int slot_num)
if (inst->fault == NoFault) {
inst->setExecuted();
mult_div_req->setCompleted();
DPRINTF(InOrderMDU, "[tid:%i]: The result of execution is 0x%x.\n",
inst->readTid(), inst->readIntResult(0));
@ -303,8 +289,40 @@ MultDivUnit::exeMulDiv(int slot_num)
DPRINTF(InOrderMDU, "[tid:%i]: [sn:%i]: had a %s "
"fault.\n", inst->readTid(), inst->seqNum, inst->fault->name());
}
mult_div_req->setProcessing(false);
}
void
MultDivUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
ThreadID tid)
{
for (int i = 0; i < width; i++) {
ResReqPtr req_ptr = reqs[i];
DynInstPtr inst = req_ptr->getInst();
if (req_ptr->valid &&
inst->readTid() == tid &&
inst->seqNum > squash_seq_num) {
DPRINTF(InOrderMDU, "[tid:%i]: Squashing [sn:%i].\n",
req_ptr->getInst()->readTid(),
req_ptr->getInst()->seqNum);
req_ptr->setSquashed();
int req_slot_num = req_ptr->getSlot();
if (req_ptr->isProcessing())
DPRINTF(InOrderMDU, "[tid:%i]: Squashed [sn:%i], but "
"waiting for MDU operation to complete.\n",
req_ptr->getInst()->readTid(),
req_ptr->getInst()->seqNum);
else
freeSlot(req_slot_num);
}
}
}
MDUEvent::MDUEvent()
: ResourceEvent()
@ -319,7 +337,8 @@ MDUEvent::process()
ResourceRequest* mult_div_req = resource->reqs[slotIdx];
mult_div_req->done();
if (mult_div_req->isSquashed())
mdu_res->freeSlot(slotIdx);
}

View file

@ -64,10 +64,6 @@ class MultDivUnit : public Resource {
* valid mult/div sequence is being maintained
*/
int getSlot(DynInstPtr inst);
int findSlot(DynInstPtr inst);
void freeSlot(int slot_idx);
void init();
@ -84,6 +80,9 @@ class MultDivUnit : public Resource {
void requestAgain(DynInstPtr inst, bool &try_request);
void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
ThreadID tid);
protected:
/** Latency & Repeat Rate for Multiply Insts */
unsigned multRepeatRate;