This change adds the float32_to_uint64_round_to_zero function to the softfloat library. This function fills out the complement of float32 to INT round-to-zero conversion rountines, where INT is {int32_t, uint32_t, int64_t, uint64_t}.
This contribution can be licensed under either the softfloat-2a or -2b license. Signed-off-by: Tom Musta <tommu...@gmail.com> Tested-by: Tom Musta <tommu...@gmail.com> --- fpu/softfloat.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ include/fpu/softfloat.h | 1 + 2 files changed, 55 insertions(+), 0 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 5f02c16..d6df78a 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1628,6 +1628,60 @@ uint64 float32_to_uint64(float32 a STATUS_PARAM) /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit unsigned integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. If +| `a' is a NaN, the largest unsigned integer is returned. Otherwise, if the +| conversion overflows, the largest unsigned integer is returned. If the +| 'a' is negative, the result is rounded and zero is returned; values that do +| not round to zero will raise the inexact flag. +*----------------------------------------------------------------------------*/ + +uint64 float32_to_uint64_round_to_zero(float32 a STATUS_PARAM) +{ + flag aSign; + int_fast16_t aExp, shiftCount; + uint32_t aSig; + uint64_t aSig64; + uint64_t z; + a = float32_squash_input_denormal(a STATUS_VAR); + + aSig = extractFloat32Frac(a); + aExp = extractFloat32Exp(a); + aSign = extractFloat32Sign(a); + if ((aSign) && (aExp > 126)) { + float_raise(float_flag_invalid STATUS_VAR); + if (float32_is_any_nan(a)) { + return LIT64(0xFFFFFFFFFFFFFFFF); + } else { + return 0; + } + } + shiftCount = 0xBE - aExp; + if (aExp) { + aSig |= 0x00800000; + } + if (shiftCount < 0) { + float_raise(float_flag_invalid STATUS_VAR); + return LIT64(0xFFFFFFFFFFFFFFFF); + } else if (aExp <= 0x7E) { + if (aExp | aSig) { + STATUS(float_exception_flags) |= float_flag_inexact; + } + return 0; + } + + aSig64 = aSig; + aSig64 <<= 40; + z = aSig64 >> shiftCount; + if (shiftCount && ((uint64_t)(aSig64 << (-shiftCount & 63)))) { + STATUS(float_exception_flags) |= float_flag_inexact; + } + return z; +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value | `a' to the 64-bit two's complement integer format. The conversion is | performed according to the IEC/IEEE Standard for Binary Floating-Point | Arithmetic, except that the conversion is always rounded toward zero. If diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index db878c1..4b3090c 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -342,6 +342,7 @@ uint32 float32_to_uint32( float32 STATUS_PARAM ); uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM ); int64 float32_to_int64( float32 STATUS_PARAM ); uint64 float32_to_uint64(float32 STATUS_PARAM); +uint64 float32_to_uint64_round_to_zero(float32 STATUS_PARAM); int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM ); float64 float32_to_float64( float32 STATUS_PARAM ); floatx80 float32_to_floatx80( float32 STATUS_PARAM ); -- 1.7.1