THis includes fix for special case when conversion from fp to int/long. The previous src did not test both the flags and result and so missed this subtle bug when an Invalid happens for this type of conversion. These results are indications of undefined behavior for these operations. All fp operations now passs when this update is fixed. Much of the information why these outputs should occur is somewhat alluded to by Pascal Cuoq originally from INSA in Lyon here: https://frama-c.com/2013/10/09/Overflow-float-integer.html

This commit is contained in:
James E. Stine 2024-01-12 00:37:50 -06:00
parent dbe8394651
commit e707eeb7c8

View File

@ -266,28 +266,34 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
// integer result selection
///////////////////////////////////////////////////////////////////////////////////////
// Causes undefined behavior for invalid:
// unsigned: if invalid (e.g., negative fp to unsigned int, result should overflow and
// overflows to the maximum value
// signed: if invalid, result should overflow to maximum negative value
// but is undefined and used for information only
// select the overflow integer res
// - negitive infinity and out of range negitive input
// | int | long |
// signed | -2^31 | -2^63 |
// unsigned | 0 | 0 |
// | int | long |
// signed | -2^31 | -2^63 |
// unsigned | 2^32-1 | 2^64-1 |
//
// - positive infinity and out of range positive input and NaNs
// | int | long |
// signed | 2^31-1 | 2^63-1 |
// signed | -2^31 |-2^63 |
// unsigned | 2^32-1 | 2^64-1 |
//
// other: 32 bit unsinged res should be sign extended as if it were a signed number
// other: 32 bit unsigned res should be sign extended as if it were a signed number
always_comb
if(Signed)
if(Xs&~NaNIn) // signed negitive
if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else // signed positive
if(Int64) OfIntRes = {1'b0, {P.XLEN-1{1'b1}}};
else OfIntRes = {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b1}}; // unsigned negitive
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
// select the integer output