Skip to content

Commit

Permalink
softfloat: Revert and reimplement remaining portions of 75d62a5 and 3…
Browse files Browse the repository at this point in the history
…430b0b

Revert the remaining portions of commits 75d62a5 and 3430b0b
which are under a SoftFloat-2b license, ie the functions
uint64_to_float32() and uint64_to_float64(). (The float64_to_uint64()
and float64_to_uint64_round_to_zero() functions were completely
rewritten in commits fb3ea83 and 0a87a31 so can stay.)

Reimplement from scratch the uint64_to_float64() and uint64_to_float32()
conversion functions.

[This is a mechanical squashing together of two separate "revert"
and "reimplement" patches.]

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1421073508-23909-3-git-send-email-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Jan 29, 2015
1 parent a7d1ac7 commit 6bb8e0f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 37 deletions.
100 changes: 65 additions & 35 deletions fpu/softfloat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1302,27 +1302,6 @@ float32 int64_to_float32(int64_t a STATUS_PARAM)

}

float32 uint64_to_float32(uint64_t a STATUS_PARAM)
{
int8 shiftCount;

if ( a == 0 ) return float32_zero;
shiftCount = countLeadingZeros64( a ) - 40;
if ( 0 <= shiftCount ) {
return packFloat32(0, 0x95 - shiftCount, a<<shiftCount);
}
else {
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
Expand All @@ -1342,20 +1321,6 @@ float64 int64_to_float64(int64_t a STATUS_PARAM)

}

float64 uint64_to_float64(uint64_t a STATUS_PARAM)
{
int exp = 0x43C;

if (a == 0) {
return float64_zero;
}
if ((int64_t)a < 0) {
shift64RightJamming(a, 1, &a);
exp += 1;
}
return normalizeRoundAndPackFloat64(0, exp, 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
Expand Down Expand Up @@ -1410,6 +1375,71 @@ float128 int64_to_float128(int64_t a STATUS_PARAM)

}

/*----------------------------------------------------------------------------
| Returns the result of converting the 64-bit unsigned integer `a'
| to the single-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/

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 unsigned integer `a'
| to the double-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/

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 unsigned integer `a'
| to the quadruple-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/

float128 uint64_to_float128(uint64_t a STATUS_PARAM)
{
if (a == 0) {
Expand Down
4 changes: 2 additions & 2 deletions include/fpu/softfloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,11 @@ float64 uint32_to_float64(uint32_t STATUS_PARAM);
floatx80 int32_to_floatx80(int32_t STATUS_PARAM);
float128 int32_to_float128(int32_t STATUS_PARAM);
float32 int64_to_float32(int64_t STATUS_PARAM);
float32 uint64_to_float32(uint64_t STATUS_PARAM);
float64 int64_to_float64(int64_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);
float32 uint64_to_float32(uint64_t STATUS_PARAM);
float64 uint64_to_float64(uint64_t STATUS_PARAM);
float128 uint64_to_float128(uint64_t STATUS_PARAM);

/* We provide the int16 versions for symmetry of API with float-to-int */
Expand Down

0 comments on commit 6bb8e0f

Please sign in to comment.