Reimplement from scratch the uint64_to_float64() and uint64_to_float32() conversion functions.
Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> --- fpu/softfloat.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ include/fpu/softfloat.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index f79669f..3ab75a3 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1302,6 +1302,35 @@ float32 int64_to_float32(int64_t a STATUS_PARAM) } +float32 uint64_to_float32(uint64_t a STATUS_PARAM) +{ + int shiftcount; + + if (a == 0) { + return float32_zero; + } + + /* Determine (left) shift needed to put first set bit into bit posn 23 + * (since packFloat32() expects the binary point between bits 23 and 22); + * this is the fast case for smallish numbers. + */ + shiftcount = countLeadingZeros64(a) - 40; + if (shiftcount >= 0) { + return packFloat32(0, 0x95 - shiftcount, a << shiftcount); + } + /* Otherwise we need to do a round-and-pack. roundAndPackFloat32() + * expects the binary point between bits 30 and 29, hence the + 7. + */ + shiftcount += 7; + if (shiftcount < 0) { + shift64RightJamming(a, -shiftcount, &a); + } else { + a <<= shiftcount; + } + + return roundAndPackFloat32(0, 0x9c - shiftcount, a STATUS_VAR); +} + /*---------------------------------------------------------------------------- | Returns the result of converting the 64-bit two's complement integer `a' | to the double-precision floating-point format. The conversion is performed @@ -1321,6 +1350,24 @@ float64 int64_to_float64(int64_t a STATUS_PARAM) } +float64 uint64_to_float64(uint64_t a STATUS_PARAM) +{ + int exp = 0x43C; + int shiftcount; + + if (a == 0) { + return float64_zero; + } + + shiftcount = countLeadingZeros64(a) - 1; + if (shiftcount < 0) { + shift64RightJamming(a, -shiftcount, &a); + } else { + a <<= shiftcount; + } + return roundAndPackFloat64(0, exp - shiftcount, a STATUS_VAR); +} + /*---------------------------------------------------------------------------- | Returns the result of converting the 64-bit two's complement integer `a' | to the extended double-precision floating-point format. The conversion diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 772f9a1..50c2fec 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -274,6 +274,8 @@ floatx80 int32_to_floatx80(int32_t STATUS_PARAM); float128 int32_to_float128(int32_t STATUS_PARAM); float32 int64_to_float32(int64_t STATUS_PARAM); float64 int64_to_float64(int64_t STATUS_PARAM); +float32 uint64_to_float32(uint64_t STATUS_PARAM); +float64 uint64_to_float64(uint64_t STATUS_PARAM); floatx80 int64_to_floatx80(int64_t STATUS_PARAM); float128 int64_to_float128(int64_t STATUS_PARAM); float128 uint64_to_float128(uint64_t STATUS_PARAM); -- 1.9.1