From 25cbb61cdc180a441758b10eb7dd74002de01f68 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 24 Nov 2014 15:47:12 +0000 Subject: softfloat: Implement uint64_to_float64() and uint64_to_float32() Reimplement from scratch the uint64_to_float64() and uint64_to_float32() conversion functions. Signed-off-by: Peter Maydell --- fpu/softfloat.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'fpu/softfloat.c') diff --git a/fpu/softfloat.c b/fpu/softfloat.c index f79669fce2..3ab75a34bc 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 -- cgit v1.2.3