Commit 446c8947 by Richard Kenner

(FLO_union_type): Remove bitfields to set sign...

(FLO_union_type): Remove bitfields to set sign, exponent, and
mantissa, and add value_raw field, which is an integer of the
appropriate type.  If _DEBUG_BITFLOAT is defined, provide little and
big endian bitfields.
(pack_d, unpack_d): Switch to use value_raw and explicit shifts and
masks so that we don't have to worry about whether the target is big
or little endian.  If single precision floating point, rename to
pack_f and unpack_f, so there is no confusion in the debugger.

From-SVN: r10312
parent 692ce0fd
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
the floating point routines in libgcc1.c for targets without hardware the floating point routines in libgcc1.c for targets without hardware
floating point. */ floating point. */
/* Copyright (C) 1994 Free Software Foundation, Inc. /* Copyright (C) 1994, 1995 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the under the terms of the GNU General Public License as published by the
...@@ -99,6 +99,8 @@ typedef unsigned int UDItype __attribute__ ((mode (DI))); ...@@ -99,6 +99,8 @@ typedef unsigned int UDItype __attribute__ ((mode (DI)));
# define FRAC_NBITS 32 # define FRAC_NBITS 32
# define FRACHIGH 0x80000000L # define FRACHIGH 0x80000000L
# define FRACHIGH2 0xc0000000L # define FRACHIGH2 0xc0000000L
# define pack_d pack_f
# define unpack_d unpack_f
typedef USItype fractype; typedef USItype fractype;
typedef UHItype halffractype; typedef UHItype halffractype;
typedef SFtype FLO_type; typedef SFtype FLO_type;
...@@ -239,22 +241,27 @@ typedef struct ...@@ -239,22 +241,27 @@ typedef struct
typedef union typedef union
{ {
FLO_type value; FLO_type value;
fractype value_raw;
#ifdef _DEBUG_BITFLOAT #ifdef _DEBUG_BITFLOAT
int l[2]; halffractype l[2];
#endif
struct struct
{ {
#ifndef FLOAT_BIT_ORDER_MISMATCH
unsigned int sign:1 __attribute__ ((packed)); unsigned int sign:1 __attribute__ ((packed));
unsigned int exp:EXPBITS __attribute__ ((packed)); unsigned int exp:EXPBITS __attribute__ ((packed));
fractype fraction:FRACBITS __attribute__ ((packed)); fractype fraction:FRACBITS __attribute__ ((packed));
#else }
bits_big_endian;
struct
{
fractype fraction:FRACBITS __attribute__ ((packed)); fractype fraction:FRACBITS __attribute__ ((packed));
unsigned int exp:EXPBITS __attribute__ ((packed)); unsigned int exp:EXPBITS __attribute__ ((packed));
unsigned int sign:1 __attribute__ ((packed)); unsigned int sign:1 __attribute__ ((packed));
#endif
} }
bits; bits_little_endian;
#endif
} }
FLO_union_type; FLO_union_type;
...@@ -314,31 +321,31 @@ pack_d ( fp_number_type * src) ...@@ -314,31 +321,31 @@ pack_d ( fp_number_type * src)
{ {
FLO_union_type dst; FLO_union_type dst;
fractype fraction = src->fraction.ll; /* wasn't unsigned before? */ fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
int sign = src->sign;
dst.bits.sign = src->sign; int exp = 0;
if (isnan (src)) if (isnan (src))
{ {
dst.bits.exp = EXPMAX; exp = EXPMAX;
dst.bits.fraction = src->fraction.ll;
if (src->class == CLASS_QNAN || 1) if (src->class == CLASS_QNAN || 1)
{ {
dst.bits.fraction |= QUIET_NAN; fraction |= QUIET_NAN;
} }
} }
else if (isinf (src)) else if (isinf (src))
{ {
dst.bits.exp = EXPMAX; exp = EXPMAX;
dst.bits.fraction = 0; fraction = 0;
} }
else if (iszero (src)) else if (iszero (src))
{ {
dst.bits.exp = 0; exp = 0;
dst.bits.fraction = 0; fraction = 0;
} }
else if (fraction == 0) else if (fraction == 0)
{ {
dst.value = 0; exp = 0;
sign = 0;
} }
else else
{ {
...@@ -350,7 +357,7 @@ pack_d ( fp_number_type * src) ...@@ -350,7 +357,7 @@ pack_d ( fp_number_type * src)
int shift = NORMAL_EXPMIN - src->normal_exp; int shift = NORMAL_EXPMIN - src->normal_exp;
dst.bits.exp = 0; exp = 0;
if (shift > FRAC_NBITS - NGARDS) if (shift > FRAC_NBITS - NGARDS)
{ {
...@@ -363,16 +370,15 @@ pack_d ( fp_number_type * src) ...@@ -363,16 +370,15 @@ pack_d ( fp_number_type * src)
fraction >>= shift; fraction >>= shift;
} }
fraction >>= NGARDS; fraction >>= NGARDS;
dst.bits.fraction = fraction;
} }
else if (src->normal_exp > EXPBIAS) else if (src->normal_exp > EXPBIAS)
{ {
dst.bits.exp = EXPMAX; exp = EXPMAX;
dst.bits.fraction = 0; fraction = 0;
} }
else else
{ {
dst.bits.exp = src->normal_exp + EXPBIAS; exp = src->normal_exp + EXPBIAS;
/* IF the gard bits are the all zero, but the first, then we're /* IF the gard bits are the all zero, but the first, then we're
half way between two numbers, choose the one which makes the half way between two numbers, choose the one which makes the
lsb of the answer 0. */ lsb of the answer 0. */
...@@ -389,22 +395,33 @@ pack_d ( fp_number_type * src) ...@@ -389,22 +395,33 @@ pack_d ( fp_number_type * src)
if (fraction >= IMPLICIT_2) if (fraction >= IMPLICIT_2)
{ {
fraction >>= 1; fraction >>= 1;
dst.bits.exp += 1; exp += 1;
} }
fraction >>= NGARDS; fraction >>= NGARDS;
dst.bits.fraction = fraction;
} }
} }
/* We previously used bitfields to store the number, but this doesn't
handle little/big endian systems conviently, so use shifts and
masks */
dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
return dst.value; return dst.value;
} }
static void static void
unpack_d (FLO_union_type * src, fp_number_type * dst) unpack_d (FLO_union_type * src, fp_number_type * dst)
{ {
fractype fraction = src->bits.fraction; /* We previously used bitfields to store the number, but this doesn't
handle little/big endian systems conviently, so use shifts and
dst->sign = src->bits.sign; masks */
if (src->bits.exp == 0) fractype fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1);
int exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
int sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
dst->sign = sign;
if (exp == 0)
{ {
/* Hmm. Looks like 0 */ /* Hmm. Looks like 0 */
if (fraction == 0) if (fraction == 0)
...@@ -417,7 +434,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst) ...@@ -417,7 +434,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
/* Zero exponent with non zero fraction - it's denormalized, /* Zero exponent with non zero fraction - it's denormalized,
so there isn't a leading implicit one - we'll shift it so so there isn't a leading implicit one - we'll shift it so
it gets one. */ it gets one. */
dst->normal_exp = src->bits.exp - EXPBIAS + 1; dst->normal_exp = exp - EXPBIAS + 1;
fraction <<= NGARDS; fraction <<= NGARDS;
dst->class = CLASS_NUMBER; dst->class = CLASS_NUMBER;
...@@ -431,7 +448,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst) ...@@ -431,7 +448,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
dst->fraction.ll = fraction; dst->fraction.ll = fraction;
} }
} }
else if (src->bits.exp == EXPMAX) else if (exp == EXPMAX)
{ {
/* Huge exponent*/ /* Huge exponent*/
if (fraction == 0) if (fraction == 0)
...@@ -442,7 +459,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst) ...@@ -442,7 +459,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
else else
{ {
/* Non zero fraction, means nan */ /* Non zero fraction, means nan */
if (dst->sign) if (sign)
{ {
dst->class = CLASS_SNAN; dst->class = CLASS_SNAN;
} }
...@@ -457,7 +474,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst) ...@@ -457,7 +474,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
else else
{ {
/* Nothing strange about this number */ /* Nothing strange about this number */
dst->normal_exp = src->bits.exp - EXPBIAS; dst->normal_exp = exp - EXPBIAS;
dst->class = CLASS_NUMBER; dst->class = CLASS_NUMBER;
dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1; dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment