--- gcc/config/fp-bit.c 2018/04/24 18:20:24 1.1.1.1 +++ gcc/config/fp-bit.c 2018/04/24 18:27:25 1.1.1.2 @@ -2,7 +2,7 @@ the floating point routines in libgcc1.c for targets without hardware 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 under the terms of the GNU General Public License as published by the @@ -24,7 +24,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* As a special exception, if you link this library with other files, some of which are compiled with GCC, to produce an executable, @@ -98,6 +99,8 @@ typedef unsigned int UDItype __attribute # define FRAC_NBITS 32 # define FRACHIGH 0x80000000L # define FRACHIGH2 0xc0000000L +# define pack_d pack_f +# define unpack_d unpack_f typedef USItype fractype; typedef UHItype halffractype; typedef SFtype FLO_type; @@ -238,22 +241,39 @@ typedef struct typedef union { FLO_type value; -#ifdef _DEBUG_BITFLOAT - int l[2]; + fractype value_raw; + +#ifndef FLOAT + halffractype words[2]; #endif + +#ifdef FLOAT_BIT_ORDER_MISMATCH + struct + { + fractype fraction:FRACBITS __attribute__ ((packed)); + unsigned int exp:EXPBITS __attribute__ ((packed)); + unsigned int sign:1 __attribute__ ((packed)); + } + bits; +#endif + +#ifdef _DEBUG_BITFLOAT struct { -#ifndef FLOAT_BIT_ORDER_MISMATCH unsigned int sign:1 __attribute__ ((packed)); unsigned int exp:EXPBITS __attribute__ ((packed)); fractype fraction:FRACBITS __attribute__ ((packed)); -#else + } + bits_big_endian; + + struct + { fractype fraction:FRACBITS __attribute__ ((packed)); unsigned int exp:EXPBITS __attribute__ ((packed)); unsigned int sign:1 __attribute__ ((packed)); -#endif } - bits; + bits_little_endian; +#endif } FLO_union_type; @@ -313,31 +333,31 @@ pack_d ( fp_number_type * src) { FLO_union_type dst; fractype fraction = src->fraction.ll; /* wasn't unsigned before? */ - - dst.bits.sign = src->sign; + int sign = src->sign; + int exp = 0; if (isnan (src)) { - dst.bits.exp = EXPMAX; - dst.bits.fraction = src->fraction.ll; + exp = EXPMAX; if (src->class == CLASS_QNAN || 1) { - dst.bits.fraction |= QUIET_NAN; + fraction |= QUIET_NAN; } } else if (isinf (src)) { - dst.bits.exp = EXPMAX; - dst.bits.fraction = 0; + exp = EXPMAX; + fraction = 0; } else if (iszero (src)) { - dst.bits.exp = 0; - dst.bits.fraction = 0; + exp = 0; + fraction = 0; } else if (fraction == 0) { - dst.value = 0; + exp = 0; + sign = 0; } else { @@ -349,7 +369,7 @@ pack_d ( fp_number_type * src) int shift = NORMAL_EXPMIN - src->normal_exp; - dst.bits.exp = 0; + exp = 0; if (shift > FRAC_NBITS - NGARDS) { @@ -362,16 +382,15 @@ pack_d ( fp_number_type * src) fraction >>= shift; } fraction >>= NGARDS; - dst.bits.fraction = fraction; } else if (src->normal_exp > EXPBIAS) { - dst.bits.exp = EXPMAX; - dst.bits.fraction = 0; + exp = EXPMAX; + fraction = 0; } 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 half way between two numbers, choose the one which makes the lsb of the answer 0. */ @@ -388,22 +407,66 @@ pack_d ( fp_number_type * src) if (fraction >= IMPLICIT_2) { fraction >>= 1; - dst.bits.exp += 1; + exp += 1; } 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 */ +#ifdef FLOAT_BIT_ORDER_MISMATCH + dst.bits.fraction = fraction; + dst.bits.exp = exp; + dst.bits.sign = sign; +#else + 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); +#endif + +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) + { + halffractype tmp = dst.words[0]; + dst.words[0] = dst.words[1]; + dst.words[1] = tmp; + } +#endif + return dst.value; } static void 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 + masks */ + fractype fraction; + int exp; + int sign; + +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) + FLO_union_type swapped; + + swapped.words[0] = src->words[1]; + swapped.words[1] = src->words[0]; + src = &swapped; +#endif + +#ifdef FLOAT_BIT_ORDER_MISMATCH + fraction = src->bits.fraction; + exp = src->bits.exp; + sign = src->bits.sign; +#else + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1); + exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1); + sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1; +#endif - dst->sign = src->bits.sign; - if (src->bits.exp == 0) + dst->sign = sign; + if (exp == 0) { /* Hmm. Looks like 0 */ if (fraction == 0) @@ -416,7 +479,7 @@ unpack_d (FLO_union_type * src, fp_numbe /* Zero exponent with non zero fraction - it's denormalized, so there isn't a leading implicit one - we'll shift it so it gets one. */ - dst->normal_exp = src->bits.exp - EXPBIAS + 1; + dst->normal_exp = exp - EXPBIAS + 1; fraction <<= NGARDS; dst->class = CLASS_NUMBER; @@ -430,18 +493,18 @@ unpack_d (FLO_union_type * src, fp_numbe dst->fraction.ll = fraction; } } - else if (src->bits.exp == EXPMAX) + else if (exp == EXPMAX) { /* Huge exponent*/ if (fraction == 0) { - /* Attatched to a zero fraction - means infinity */ + /* Attached to a zero fraction - means infinity */ dst->class = CLASS_INFINITY; } else { /* Non zero fraction, means nan */ - if (dst->sign) + if (sign) { dst->class = CLASS_SNAN; } @@ -456,7 +519,7 @@ unpack_d (FLO_union_type * src, fp_numbe else { /* Nothing strange about this number */ - dst->normal_exp = src->bits.exp - EXPBIAS; + dst->normal_exp = exp - EXPBIAS; dst->class = CLASS_NUMBER; dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1; } @@ -485,6 +548,9 @@ _fpadd_parts (fp_number_type * a, } if (isinf (a)) { + /* Adding infinities with opposite signs yields a NaN. */ + if (isinf (b) && a->sign != b->sign) + return nan (); return a; } if (isinf (b)) @@ -566,7 +632,7 @@ _fpadd_parts (fp_number_type * a, tmp->normal_exp = a_normal_exp; tmp->fraction.ll = -tfraction; } - /* and renomalize it */ + /* and renormalize it */ while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll) {