Make casts from double to unsigned bits portable.
Several places in Icarus Verilog try to get the bits of the integer part of a double by casting to unsigned or unsigned long. But that causes some compilers to generate smart code that converts all values less then 0 to 0, even though we are after the bits, not the math value. So be careful to do this cast only to non-negative values and uminus the bits if necessary to get exactly what we want. Signed-off-by: Stephen Williams <steve@icarus.com>
This commit is contained in:
parent
81e12bf7f6
commit
c3ac01d31b
|
|
@ -215,7 +215,10 @@ static PLI_INT32 sys_rtoi_calltf(PLI_BYTE8*user)
|
||||||
vpi_get_value(arg, &value);
|
vpi_get_value(arg, &value);
|
||||||
|
|
||||||
/* convert */
|
/* convert */
|
||||||
res.aval = (unsigned)value.value.real;
|
if (value.value.real >= 0.0)
|
||||||
|
res.aval = (unsigned)value.value.real;
|
||||||
|
else
|
||||||
|
res.aval = - (unsigned)-value.value.real;
|
||||||
res.bval = 0;
|
res.bval = 0;
|
||||||
|
|
||||||
value.format = vpiVectorVal;
|
value.format = vpiVectorVal;
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ long rtl_dist_uniform(long *seed, long start, long end)
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
i = (unsigned long) r;
|
i = (unsigned long) r;
|
||||||
} else {
|
} else {
|
||||||
i = (unsigned long) (r - 1);
|
i = - ( (unsigned long) (-(r - 1)) );
|
||||||
}
|
}
|
||||||
if (i < start) i = start;
|
if (i < start) i = start;
|
||||||
if (i >= end) i = end - 1;
|
if (i >= end) i = end - 1;
|
||||||
|
|
@ -197,7 +197,7 @@ long rtl_dist_uniform(long *seed, long start, long end)
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
i = (unsigned long) r;
|
i = (unsigned long) r;
|
||||||
} else {
|
} else {
|
||||||
i = (unsigned long) (r - 1);
|
i = - ( (unsigned long) (-(r - 1)) );
|
||||||
}
|
}
|
||||||
if (i <= start) i = start + 1;
|
if (i <= start) i = start + 1;
|
||||||
if (i > end) i = end;
|
if (i > end) i = end;
|
||||||
|
|
@ -208,7 +208,12 @@ long rtl_dist_uniform(long *seed, long start, long end)
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
i = (unsigned long) r;
|
i = (unsigned long) r;
|
||||||
} else {
|
} else {
|
||||||
i = (unsigned long) (r - 1);
|
/* At least some compilers will notice that (r-1)
|
||||||
|
is <0 when castling to unsigned long and
|
||||||
|
replace the result with a zero. This causes
|
||||||
|
much wrongness, so do the casting to the
|
||||||
|
positive version and invert it back. */
|
||||||
|
i = - ( (unsigned long) (-(r - 1)) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue