In cases of forwarding between signed and unsigned subword classes, the
forwarding code was not correctly setting the sign bit. This may
potentially lead to run-time errors (segmentation faults or incorrect
results).
Suggested work-around
Changes to memunit.cc given below will fix this problem.
/*************************************************************************/
/* MemMatch : check for match between load and store and also forward */
/* : values where possible. Returns 1 on success, 0 on failure */
/*************************************************************************/
static int MemMatch(instance *ld, instance *st) // check for match and also copy
{
INSTRUCTION load = ld->code->instruction;
INSTRUCTION store = st->code->instruction;
switch (store)
{
case iSTW:
if ((load == iLDUW) || (load == iLDSW) || (load == iLDUWA))
{
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %d from %d to %d\n",st->rs1vali,st->tag,ld->tag);
#endif
/* -- Added -- RPS Jan 4 1999 */
if(load == iLDSW){
ld->rdvali = (int)st->rs1vali;
} else {
ld->rdvali= (unsigned)st->rs1vali;
}
return 1;
}
else if (load == iLDF)
{
float tmp;
int *addr = (int *)&tmp;
*addr = st->rs1vali;
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %d as %f from %d to %d\n",st->rs1vali,tmp,st->tag,ld->tag);
#endif
ld->rdvalfh = tmp;
return 1;
}
return 0;
break;
case iSTD:
if (load == iLDD)
{
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %d/%d from %d to %d\n",st->rs1valipair.a,st->rs1valipair.b,st->tag,ld->tag);
#endif
ld->rdvalipair.a=st->rs1valipair.a;
ld->rdvalipair.b=st->rs1valipair.b;
return 1;
}
else
return 0;
break;
case iSTB:
if ((load == iLDUB) || (load == iLDSB))
{
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %d from %d to %d\n",st->rs1vali,st->tag,ld->tag);
#endif
/* -- Added -- RPS Jan 4 1999 */
if(load == iLDSB){
ld->rdvali=(char)st->rs1vali;
} else {
ld->rdvali=(unsigned char)st->rs1vali;
}
return 1;
}
else
return 0;
break;
case iLDSTUB:
if (load == iLDUB)
{
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %d from %d to %d\n",st->rs1vali,st->tag,ld->tag);
#endif
ld->rdvali=255;
return 1;
}
else
return 0;
break;
case iSTH:
if ((load == iLDUH) || (load == iLDSH))
{
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %d from %d to %d\n",st->rs1vali,st->tag,ld->tag);
#endif
/* -- Added -- RPS Jan 4 1999 */
if(load == iLDSH){
ld->rdvali=(short)st->rs1vali;
} else {
ld->rdvali=(unsigned short)st->rs1vali;
}
return 1;
}
else
return 0;
break;
case iSTDF:
if (load == iLDDF)
{
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %f from %d to %d\n",st->rs1valf,st->tag,ld->tag);
#endif
ld->rdvalf=st->rs1valf;
return 1;
}
else
return 0;
break;
case iSTF:
if (load == iLDF)
{
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %f from %d to %d\n",st->rs1valfh,st->tag,ld->tag);
#endif
ld->rdvalfh=st->rs1valfh;
return 1;
}
else if (load == iLDSW || load == iLDUW)
{
int tmp;
float *addr = (float *)&tmp;
*addr = st->rs1valfh;
#ifdef COREFILE
if(GetSimTime() > DEBUG_TIME)
fprintf(corefile,"Forwarded value %f as %d from %d to %d\n",st->rs1valfh,tmp,st->tag,ld->tag);
#endif
/* -- Added -- RPS Jan 4 1999 */
if(load == iLDSW){
ld->rdvali = (int)tmp;
} else {
ld->rdvali = (unsigned int)tmp;
}
return 1;
}
else
return 0;
break;
default:
return 0;
break;
}
}