The multiplication routines fnUMUL and fnSMUL in
funcs.cc were incorrectly coded to typecast the input
parameters to INT32 instead of INT64. As a result,
an intermediate multiply was being computed using 32-bit arithmetic
and truncation. This caused programs that use long long
(64-bit integer) data types to see incorrect values in the upper word
of the 64-bit datum.
Suggested work-around
The fnUMUL and fnSMUL in funcs.cc must be
changed to replace any internal INT32 or UINT32 data
types to INT64 or UINT64, respectively. The full
code for these functions is provided below:
void fnUMUL(instance *inst, state *)
{
UINT64 destval;
if (inst->code->aux1)
{
destval=UINT64(inst->rs1vali) * UINT64(inst->code->imm);
}
else
{
destval=UINT64(inst->rs1vali) * UINT64(inst->rs2vali);
}
inst->rdvali = destval; /* WRITE ALL 64 bits when supported... */
inst->rccvali = (destval >> 32); /* Y reg gets 32 MSBs */
}
void fnSMUL(instance *inst, state *)
{
INT64 destval;
if (inst->code->aux1)
{
destval=INT64(inst->rs1vali) * INT64(inst->code->imm);
}
else
{
destval=INT64(inst->rs1vali) * INT64(inst->rs2vali);
}
inst->rdvali = destval; /* WRITE ALL 64 bits when supported... */
inst->rccvali = (UINT64(destval) >> 32); /* Y reg gets 32 MSBs */
}