|  | /* This is a software floating point library which can be used | 
|  | for targets without hardware floating point. | 
|  | Copyright (C) 1994-2021 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GCC. | 
|  |  | 
|  | GCC is free software; you can redistribute it and/or modify it under | 
|  | the terms of the GNU General Public License as published by the Free | 
|  | Software Foundation; either version 3, or (at your option) any later | 
|  | version. | 
|  |  | 
|  | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | 
|  | WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|  | FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|  | for more details. | 
|  |  | 
|  | Under Section 7 of GPL version 3, you are granted additional | 
|  | permissions described in the GCC Runtime Library Exception, version | 
|  | 3.1, as published by the Free Software Foundation. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License and | 
|  | a copy of the GCC Runtime Library Exception along with this program; | 
|  | see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | 
|  | <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | /* This implements IEEE 754 format arithmetic, but does not provide a | 
|  | mechanism for setting the rounding mode, or for generating or handling | 
|  | exceptions. | 
|  |  | 
|  | The original code by Steve Chamberlain, hacked by Mark Eichin and Jim | 
|  | Wilson, all of Cygnus Support.  */ | 
|  |  | 
|  | /* The intended way to use this file is to make two copies, add `#define FLOAT' | 
|  | to one copy, then compile both copies and add them to libgcc.a.  */ | 
|  |  | 
|  | #include "tconfig.h" | 
|  | #include "coretypes.h" | 
|  | #include "tm.h" | 
|  | #include "libgcc_tm.h" | 
|  | #include "fp-bit.h" | 
|  |  | 
|  | /* The following macros can be defined to change the behavior of this file: | 
|  | FLOAT: Implement a `float', aka SFmode, fp library.  If this is not | 
|  | defined, then this file implements a `double', aka DFmode, fp library. | 
|  | FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e. | 
|  | don't include float->double conversion which requires the double library. | 
|  | This is useful only for machines which can't support doubles, e.g. some | 
|  | 8-bit processors. | 
|  | CMPtype: Specify the type that floating point compares should return. | 
|  | This defaults to SItype, aka int. | 
|  | _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding | 
|  | two integers to the FLO_union_type. | 
|  | NO_DENORMALS: Disable handling of denormals. | 
|  | NO_NANS: Disable nan and infinity handling | 
|  | SMALL_MACHINE: Useful when operations on QIs and HIs are faster | 
|  | than on an SI */ | 
|  |  | 
|  | /* We don't currently support extended floats (long doubles) on machines | 
|  | without hardware to deal with them. | 
|  |  | 
|  | These stubs are just to keep the linker from complaining about unresolved | 
|  | references which can be pulled in from libio & libstdc++, even if the | 
|  | user isn't using long doubles.  However, they may generate an unresolved | 
|  | external to abort if abort is not used by the function, and the stubs | 
|  | are referenced from within libc, since libgcc goes before and after the | 
|  | system library.  */ | 
|  |  | 
|  | #ifdef DECLARE_LIBRARY_RENAMES | 
|  | DECLARE_LIBRARY_RENAMES | 
|  | #endif | 
|  |  | 
|  | #ifdef EXTENDED_FLOAT_STUBS | 
|  | extern void abort (void); | 
|  | void __extendsfxf2 (void) { abort(); } | 
|  | void __extenddfxf2 (void) { abort(); } | 
|  | void __truncxfdf2 (void) { abort(); } | 
|  | void __truncxfsf2 (void) { abort(); } | 
|  | void __fixxfsi (void) { abort(); } | 
|  | void __floatsixf (void) { abort(); } | 
|  | void __addxf3 (void) { abort(); } | 
|  | void __subxf3 (void) { abort(); } | 
|  | void __mulxf3 (void) { abort(); } | 
|  | void __divxf3 (void) { abort(); } | 
|  | void __negxf2 (void) { abort(); } | 
|  | void __eqxf2 (void) { abort(); } | 
|  | void __nexf2 (void) { abort(); } | 
|  | void __gtxf2 (void) { abort(); } | 
|  | void __gexf2 (void) { abort(); } | 
|  | void __lexf2 (void) { abort(); } | 
|  | void __ltxf2 (void) { abort(); } | 
|  |  | 
|  | void __extendsftf2 (void) { abort(); } | 
|  | void __extenddftf2 (void) { abort(); } | 
|  | void __trunctfdf2 (void) { abort(); } | 
|  | void __trunctfsf2 (void) { abort(); } | 
|  | void __fixtfsi (void) { abort(); } | 
|  | void __floatsitf (void) { abort(); } | 
|  | void __addtf3 (void) { abort(); } | 
|  | void __subtf3 (void) { abort(); } | 
|  | void __multf3 (void) { abort(); } | 
|  | void __divtf3 (void) { abort(); } | 
|  | void __negtf2 (void) { abort(); } | 
|  | void __eqtf2 (void) { abort(); } | 
|  | void __netf2 (void) { abort(); } | 
|  | void __gttf2 (void) { abort(); } | 
|  | void __getf2 (void) { abort(); } | 
|  | void __letf2 (void) { abort(); } | 
|  | void __lttf2 (void) { abort(); } | 
|  | #else	/* !EXTENDED_FLOAT_STUBS, rest of file */ | 
|  |  | 
|  | /* IEEE "special" number predicates */ | 
|  |  | 
|  | #ifdef NO_NANS | 
|  |  | 
|  | #define nan() 0 | 
|  | #define isnan(x) 0 | 
|  | #define isinf(x) 0 | 
|  | #else | 
|  |  | 
|  | #if   defined L_thenan_sf | 
|  | const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; | 
|  | #elif defined L_thenan_df | 
|  | const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} }; | 
|  | #elif defined L_thenan_tf | 
|  | const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; | 
|  | #elif defined TFLOAT | 
|  | extern const fp_number_type __thenan_tf; | 
|  | #elif defined FLOAT | 
|  | extern const fp_number_type __thenan_sf; | 
|  | #else | 
|  | extern const fp_number_type __thenan_df; | 
|  | #endif | 
|  |  | 
|  | INLINE | 
|  | static const fp_number_type * | 
|  | makenan (void) | 
|  | { | 
|  | #ifdef TFLOAT | 
|  | return & __thenan_tf; | 
|  | #elif defined FLOAT | 
|  | return & __thenan_sf; | 
|  | #else | 
|  | return & __thenan_df; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | INLINE | 
|  | static int | 
|  | isnan (const fp_number_type *x) | 
|  | { | 
|  | return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN, | 
|  | 0); | 
|  | } | 
|  |  | 
|  | INLINE | 
|  | static int | 
|  | isinf (const fp_number_type *  x) | 
|  | { | 
|  | return __builtin_expect (x->class == CLASS_INFINITY, 0); | 
|  | } | 
|  |  | 
|  | #endif /* NO_NANS */ | 
|  |  | 
|  | INLINE | 
|  | static int | 
|  | iszero (const fp_number_type *  x) | 
|  | { | 
|  | return x->class == CLASS_ZERO; | 
|  | } | 
|  |  | 
|  | INLINE | 
|  | static void | 
|  | flip_sign ( fp_number_type *  x) | 
|  | { | 
|  | x->sign = !x->sign; | 
|  | } | 
|  |  | 
|  | /* Count leading zeroes in N.  */ | 
|  | INLINE | 
|  | static int | 
|  | clzusi (USItype n) | 
|  | { | 
|  | extern int __clzsi2 (USItype); | 
|  | if (sizeof (USItype) == sizeof (unsigned int)) | 
|  | return __builtin_clz (n); | 
|  | else if (sizeof (USItype) == sizeof (unsigned long)) | 
|  | return __builtin_clzl (n); | 
|  | else if (sizeof (USItype) == sizeof (unsigned long long)) | 
|  | return __builtin_clzll (n); | 
|  | else | 
|  | return __clzsi2 (n); | 
|  | } | 
|  |  | 
|  | extern FLO_type pack_d (const fp_number_type * ); | 
|  |  | 
|  | #if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) | 
|  | FLO_type | 
|  | pack_d (const fp_number_type *src) | 
|  | { | 
|  | FLO_union_type dst; | 
|  | fractype fraction = src->fraction.ll;	/* wasn't unsigned before? */ | 
|  | int sign = src->sign; | 
|  | int exp = 0; | 
|  |  | 
|  | if (isnan (src)) | 
|  | { | 
|  | exp = EXPMAX; | 
|  | /* Restore the NaN's payload.  */ | 
|  | fraction >>= NGARDS; | 
|  | fraction &= QUIET_NAN - 1; | 
|  | if (src->class == CLASS_QNAN || 1) | 
|  | { | 
|  | #ifdef QUIET_NAN_NEGATED | 
|  | /* The quiet/signaling bit remains unset.  */ | 
|  | /* Make sure the fraction has a non-zero value.  */ | 
|  | if (fraction == 0) | 
|  | fraction |= QUIET_NAN - 1; | 
|  | #else | 
|  | /* Set the quiet/signaling bit.  */ | 
|  | fraction |= QUIET_NAN; | 
|  | #endif | 
|  | } | 
|  | } | 
|  | else if (isinf (src)) | 
|  | { | 
|  | exp = EXPMAX; | 
|  | fraction = 0; | 
|  | } | 
|  | else if (iszero (src)) | 
|  | { | 
|  | exp = 0; | 
|  | fraction = 0; | 
|  | } | 
|  | else if (fraction == 0) | 
|  | { | 
|  | exp = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0)) | 
|  | { | 
|  | #ifdef NO_DENORMALS | 
|  | /* Go straight to a zero representation if denormals are not | 
|  | supported.  The denormal handling would be harmless but | 
|  | isn't unnecessary.  */ | 
|  | exp = 0; | 
|  | fraction = 0; | 
|  | #else /* NO_DENORMALS */ | 
|  | /* This number's exponent is too low to fit into the bits | 
|  | available in the number, so we'll store 0 in the exponent and | 
|  | shift the fraction to the right to make up for it.  */ | 
|  |  | 
|  | int shift = NORMAL_EXPMIN - src->normal_exp; | 
|  |  | 
|  | exp = 0; | 
|  |  | 
|  | if (shift > FRAC_NBITS - NGARDS) | 
|  | { | 
|  | /* No point shifting, since it's more that 64 out.  */ | 
|  | fraction = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0; | 
|  | fraction = (fraction >> shift) | lowbit; | 
|  | } | 
|  | if ((fraction & GARDMASK) == GARDMSB) | 
|  | { | 
|  | if ((fraction & (1 << NGARDS))) | 
|  | fraction += GARDROUND + 1; | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Add to the guards to round up.  */ | 
|  | fraction += GARDROUND; | 
|  | } | 
|  | /* Perhaps the rounding means we now need to change the | 
|  | exponent, because the fraction is no longer denormal.  */ | 
|  | if (fraction >= IMPLICIT_1) | 
|  | { | 
|  | exp += 1; | 
|  | } | 
|  | fraction >>= NGARDS; | 
|  | #endif /* NO_DENORMALS */ | 
|  | } | 
|  | else if (__builtin_expect (src->normal_exp > EXPBIAS, 0)) | 
|  | { | 
|  | exp = EXPMAX; | 
|  | fraction = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | 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.  */ | 
|  | if ((fraction & GARDMASK) == GARDMSB) | 
|  | { | 
|  | if (fraction & (1 << NGARDS)) | 
|  | fraction += GARDROUND + 1; | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Add a one to the guards to round up */ | 
|  | fraction += GARDROUND; | 
|  | } | 
|  | if (fraction >= IMPLICIT_2) | 
|  | { | 
|  | fraction >>= 1; | 
|  | exp += 1; | 
|  | } | 
|  | fraction >>= NGARDS; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* We previously used bitfields to store the number, but this doesn't | 
|  | handle little/big endian systems conveniently, so use shifts and | 
|  | masks */ | 
|  | #if defined TFLOAT && defined HALFFRACBITS | 
|  | { | 
|  | halffractype high, low, unity; | 
|  | int lowsign, lowexp; | 
|  |  | 
|  | unity = (halffractype) 1 << HALFFRACBITS; | 
|  |  | 
|  | /* Set HIGH to the high double's significand, masking out the implicit 1. | 
|  | Set LOW to the low double's full significand.  */ | 
|  | high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1); | 
|  | low = fraction & (unity * 2 - 1); | 
|  |  | 
|  | /* Get the initial sign and exponent of the low double.  */ | 
|  | lowexp = exp - HALFFRACBITS - 1; | 
|  | lowsign = sign; | 
|  |  | 
|  | /* HIGH should be rounded like a normal double, making |LOW| <= | 
|  | 0.5 ULP of HIGH.  Assume round-to-nearest.  */ | 
|  | if (exp < EXPMAX) | 
|  | if (low > unity || (low == unity && (high & 1) == 1)) | 
|  | { | 
|  | /* Round HIGH up and adjust LOW to match.  */ | 
|  | high++; | 
|  | if (high == unity) | 
|  | { | 
|  | /* May make it infinite, but that's OK.  */ | 
|  | high = 0; | 
|  | exp++; | 
|  | } | 
|  | low = unity * 2 - low; | 
|  | lowsign ^= 1; | 
|  | } | 
|  |  | 
|  | high |= (halffractype) exp << HALFFRACBITS; | 
|  | high |= (halffractype) sign << (HALFFRACBITS + EXPBITS); | 
|  |  | 
|  | if (exp == EXPMAX || exp == 0 || low == 0) | 
|  | low = 0; | 
|  | else | 
|  | { | 
|  | while (lowexp > 0 && low < unity) | 
|  | { | 
|  | low <<= 1; | 
|  | lowexp--; | 
|  | } | 
|  |  | 
|  | if (lowexp <= 0) | 
|  | { | 
|  | halffractype roundmsb, round; | 
|  | int shift; | 
|  |  | 
|  | shift = 1 - lowexp; | 
|  | roundmsb = (1 << (shift - 1)); | 
|  | round = low & ((roundmsb << 1) - 1); | 
|  |  | 
|  | low >>= shift; | 
|  | lowexp = 0; | 
|  |  | 
|  | if (round > roundmsb || (round == roundmsb && (low & 1) == 1)) | 
|  | { | 
|  | low++; | 
|  | if (low == unity) | 
|  | /* LOW rounds up to the smallest normal number.  */ | 
|  | lowexp++; | 
|  | } | 
|  | } | 
|  |  | 
|  | low &= unity - 1; | 
|  | low |= (halffractype) lowexp << HALFFRACBITS; | 
|  | low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS); | 
|  | } | 
|  | dst.value_raw = ((fractype) high << HALFSHIFT) | low; | 
|  | } | 
|  | #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) | 
|  | #ifdef TFLOAT | 
|  | { | 
|  | qrtrfractype tmp1 = dst.words[0]; | 
|  | qrtrfractype tmp2 = dst.words[1]; | 
|  | dst.words[0] = dst.words[3]; | 
|  | dst.words[1] = dst.words[2]; | 
|  | dst.words[2] = tmp2; | 
|  | dst.words[3] = tmp1; | 
|  | } | 
|  | #else | 
|  | { | 
|  | halffractype tmp = dst.words[0]; | 
|  | dst.words[0] = dst.words[1]; | 
|  | dst.words[1] = tmp; | 
|  | } | 
|  | #endif | 
|  | #endif | 
|  |  | 
|  | return dst.value; | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf) | 
|  | void | 
|  | unpack_d (FLO_union_type * src, fp_number_type * dst) | 
|  | { | 
|  | /* We previously used bitfields to store the number, but this doesn't | 
|  | handle little/big endian systems conveniently, so use shifts and | 
|  | masks */ | 
|  | fractype fraction; | 
|  | int exp; | 
|  | int sign; | 
|  |  | 
|  | #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) | 
|  | FLO_union_type swapped; | 
|  |  | 
|  | #ifdef TFLOAT | 
|  | swapped.words[0] = src->words[3]; | 
|  | swapped.words[1] = src->words[2]; | 
|  | swapped.words[2] = src->words[1]; | 
|  | swapped.words[3] = src->words[0]; | 
|  | #else | 
|  | swapped.words[0] = src->words[1]; | 
|  | swapped.words[1] = src->words[0]; | 
|  | #endif | 
|  | src = &swapped; | 
|  | #endif | 
|  |  | 
|  | #if defined TFLOAT && defined HALFFRACBITS | 
|  | { | 
|  | halffractype high, low; | 
|  |  | 
|  | high = src->value_raw >> HALFSHIFT; | 
|  | low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1); | 
|  |  | 
|  | fraction = high & ((((fractype)1) << HALFFRACBITS) - 1); | 
|  | fraction <<= FRACBITS - HALFFRACBITS; | 
|  | exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); | 
|  | sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1; | 
|  |  | 
|  | if (exp != EXPMAX && exp != 0 && low != 0) | 
|  | { | 
|  | int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); | 
|  | int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1; | 
|  | int shift; | 
|  | fractype xlow; | 
|  |  | 
|  | xlow = low & ((((fractype)1) << HALFFRACBITS) - 1); | 
|  | if (lowexp) | 
|  | xlow |= (((halffractype)1) << HALFFRACBITS); | 
|  | else | 
|  | lowexp = 1; | 
|  | shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp); | 
|  | if (shift > 0) | 
|  | xlow <<= shift; | 
|  | else if (shift < 0) | 
|  | xlow >>= -shift; | 
|  | if (sign == lowsign) | 
|  | fraction += xlow; | 
|  | else if (fraction >= xlow) | 
|  | fraction -= xlow; | 
|  | else | 
|  | { | 
|  | /* The high part is a power of two but the full number is lower. | 
|  | This code will leave the implicit 1 in FRACTION, but we'd | 
|  | have added that below anyway.  */ | 
|  | fraction = (((fractype) 1 << FRACBITS) - xlow) << 1; | 
|  | exp--; | 
|  | } | 
|  | } | 
|  | } | 
|  | #else | 
|  | fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1); | 
|  | exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1); | 
|  | sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1; | 
|  | #endif | 
|  |  | 
|  | dst->sign = sign; | 
|  | if (exp == 0) | 
|  | { | 
|  | /* Hmm.  Looks like 0 */ | 
|  | if (fraction == 0 | 
|  | #ifdef NO_DENORMALS | 
|  | || 1 | 
|  | #endif | 
|  | ) | 
|  | { | 
|  | /* tastes like zero */ | 
|  | dst->class = CLASS_ZERO; | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Zero exponent with nonzero fraction - it's denormalized, | 
|  | so there isn't a leading implicit one - we'll shift it so | 
|  | it gets one.  */ | 
|  | dst->normal_exp = exp - EXPBIAS + 1; | 
|  | fraction <<= NGARDS; | 
|  |  | 
|  | dst->class = CLASS_NUMBER; | 
|  | #if 1 | 
|  | while (fraction < IMPLICIT_1) | 
|  | { | 
|  | fraction <<= 1; | 
|  | dst->normal_exp--; | 
|  | } | 
|  | #endif | 
|  | dst->fraction.ll = fraction; | 
|  | } | 
|  | } | 
|  | else if (__builtin_expect (exp == EXPMAX, 0)) | 
|  | { | 
|  | /* Huge exponent*/ | 
|  | if (fraction == 0) | 
|  | { | 
|  | /* Attached to a zero fraction - means infinity */ | 
|  | dst->class = CLASS_INFINITY; | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Nonzero fraction, means nan */ | 
|  | #ifdef QUIET_NAN_NEGATED | 
|  | if ((fraction & QUIET_NAN) == 0) | 
|  | #else | 
|  | if (fraction & QUIET_NAN) | 
|  | #endif | 
|  | { | 
|  | dst->class = CLASS_QNAN; | 
|  | } | 
|  | else | 
|  | { | 
|  | dst->class = CLASS_SNAN; | 
|  | } | 
|  | /* Now that we know which kind of NaN we got, discard the | 
|  | quiet/signaling bit, but do preserve the NaN payload.  */ | 
|  | fraction &= ~QUIET_NAN; | 
|  | dst->fraction.ll = fraction << NGARDS; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Nothing strange about this number */ | 
|  | dst->normal_exp = exp - EXPBIAS; | 
|  | dst->class = CLASS_NUMBER; | 
|  | dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1; | 
|  | } | 
|  | } | 
|  | #endif /* L_unpack_df || L_unpack_sf */ | 
|  |  | 
|  | #if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) | 
|  | static const fp_number_type * | 
|  | _fpadd_parts (fp_number_type * a, | 
|  | fp_number_type * b, | 
|  | fp_number_type * tmp) | 
|  | { | 
|  | intfrac tfraction; | 
|  |  | 
|  | /* Put commonly used fields in local variables.  */ | 
|  | int a_normal_exp; | 
|  | int b_normal_exp; | 
|  | fractype a_fraction; | 
|  | fractype b_fraction; | 
|  |  | 
|  | if (isnan (a)) | 
|  | { | 
|  | return a; | 
|  | } | 
|  | if (isnan (b)) | 
|  | { | 
|  | return b; | 
|  | } | 
|  | if (isinf (a)) | 
|  | { | 
|  | /* Adding infinities with opposite signs yields a NaN.  */ | 
|  | if (isinf (b) && a->sign != b->sign) | 
|  | return makenan (); | 
|  | return a; | 
|  | } | 
|  | if (isinf (b)) | 
|  | { | 
|  | return b; | 
|  | } | 
|  | if (iszero (b)) | 
|  | { | 
|  | if (iszero (a)) | 
|  | { | 
|  | *tmp = *a; | 
|  | tmp->sign = a->sign & b->sign; | 
|  | return tmp; | 
|  | } | 
|  | return a; | 
|  | } | 
|  | if (iszero (a)) | 
|  | { | 
|  | return b; | 
|  | } | 
|  |  | 
|  | /* Got two numbers. shift the smaller and increment the exponent till | 
|  | they're the same */ | 
|  | { | 
|  | int diff; | 
|  | int sdiff; | 
|  |  | 
|  | a_normal_exp = a->normal_exp; | 
|  | b_normal_exp = b->normal_exp; | 
|  | a_fraction = a->fraction.ll; | 
|  | b_fraction = b->fraction.ll; | 
|  |  | 
|  | diff = a_normal_exp - b_normal_exp; | 
|  | sdiff = diff; | 
|  |  | 
|  | if (diff < 0) | 
|  | diff = -diff; | 
|  | if (diff < FRAC_NBITS) | 
|  | { | 
|  | if (sdiff > 0) | 
|  | { | 
|  | b_normal_exp += diff; | 
|  | LSHIFT (b_fraction, diff); | 
|  | } | 
|  | else if (sdiff < 0) | 
|  | { | 
|  | a_normal_exp += diff; | 
|  | LSHIFT (a_fraction, diff); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* Somethings's up.. choose the biggest */ | 
|  | if (a_normal_exp > b_normal_exp) | 
|  | { | 
|  | b_normal_exp = a_normal_exp; | 
|  | b_fraction = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | a_normal_exp = b_normal_exp; | 
|  | a_fraction = 0; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (a->sign != b->sign) | 
|  | { | 
|  | if (a->sign) | 
|  | { | 
|  | tfraction = -a_fraction + b_fraction; | 
|  | } | 
|  | else | 
|  | { | 
|  | tfraction = a_fraction - b_fraction; | 
|  | } | 
|  | if (tfraction >= 0) | 
|  | { | 
|  | tmp->sign = 0; | 
|  | tmp->normal_exp = a_normal_exp; | 
|  | tmp->fraction.ll = tfraction; | 
|  | } | 
|  | else | 
|  | { | 
|  | tmp->sign = 1; | 
|  | tmp->normal_exp = a_normal_exp; | 
|  | tmp->fraction.ll = -tfraction; | 
|  | } | 
|  | /* and renormalize it */ | 
|  |  | 
|  | while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll) | 
|  | { | 
|  | tmp->fraction.ll <<= 1; | 
|  | tmp->normal_exp--; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | tmp->sign = a->sign; | 
|  | tmp->normal_exp = a_normal_exp; | 
|  | tmp->fraction.ll = a_fraction + b_fraction; | 
|  | } | 
|  | tmp->class = CLASS_NUMBER; | 
|  | /* Now the fraction is added, we have to shift down to renormalize the | 
|  | number */ | 
|  |  | 
|  | if (tmp->fraction.ll >= IMPLICIT_2) | 
|  | { | 
|  | LSHIFT (tmp->fraction.ll, 1); | 
|  | tmp->normal_exp++; | 
|  | } | 
|  | return tmp; | 
|  | } | 
|  |  | 
|  | FLO_type | 
|  | add (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | fp_number_type tmp; | 
|  | const fp_number_type *res; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | res = _fpadd_parts (&a, &b, &tmp); | 
|  |  | 
|  | return pack_d (res); | 
|  | } | 
|  |  | 
|  | FLO_type | 
|  | sub (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | fp_number_type tmp; | 
|  | const fp_number_type *res; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | b.sign ^= 1; | 
|  |  | 
|  | res = _fpadd_parts (&a, &b, &tmp); | 
|  |  | 
|  | return pack_d (res); | 
|  | } | 
|  | #endif /* L_addsub_sf || L_addsub_df */ | 
|  |  | 
|  | #if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) | 
|  | static inline __attribute__ ((__always_inline__)) const fp_number_type * | 
|  | _fpmul_parts ( fp_number_type *  a, | 
|  | fp_number_type *  b, | 
|  | fp_number_type * tmp) | 
|  | { | 
|  | fractype low = 0; | 
|  | fractype high = 0; | 
|  |  | 
|  | if (isnan (a)) | 
|  | { | 
|  | a->sign = a->sign != b->sign; | 
|  | return a; | 
|  | } | 
|  | if (isnan (b)) | 
|  | { | 
|  | b->sign = a->sign != b->sign; | 
|  | return b; | 
|  | } | 
|  | if (isinf (a)) | 
|  | { | 
|  | if (iszero (b)) | 
|  | return makenan (); | 
|  | a->sign = a->sign != b->sign; | 
|  | return a; | 
|  | } | 
|  | if (isinf (b)) | 
|  | { | 
|  | if (iszero (a)) | 
|  | { | 
|  | return makenan (); | 
|  | } | 
|  | b->sign = a->sign != b->sign; | 
|  | return b; | 
|  | } | 
|  | if (iszero (a)) | 
|  | { | 
|  | a->sign = a->sign != b->sign; | 
|  | return a; | 
|  | } | 
|  | if (iszero (b)) | 
|  | { | 
|  | b->sign = a->sign != b->sign; | 
|  | return b; | 
|  | } | 
|  |  | 
|  | /* Calculate the mantissa by multiplying both numbers to get a | 
|  | twice-as-wide number.  */ | 
|  | { | 
|  | #if defined(NO_DI_MODE) || defined(TFLOAT) | 
|  | { | 
|  | fractype x = a->fraction.ll; | 
|  | fractype ylow = b->fraction.ll; | 
|  | fractype yhigh = 0; | 
|  | int bit; | 
|  |  | 
|  | /* ??? This does multiplies one bit at a time.  Optimize.  */ | 
|  | for (bit = 0; bit < FRAC_NBITS; bit++) | 
|  | { | 
|  | int carry; | 
|  |  | 
|  | if (x & 1) | 
|  | { | 
|  | carry = (low += ylow) < ylow; | 
|  | high += yhigh + carry; | 
|  | } | 
|  | yhigh <<= 1; | 
|  | if (ylow & FRACHIGH) | 
|  | { | 
|  | yhigh |= 1; | 
|  | } | 
|  | ylow <<= 1; | 
|  | x >>= 1; | 
|  | } | 
|  | } | 
|  | #elif defined(FLOAT) | 
|  | /* Multiplying two USIs to get a UDI, we're safe.  */ | 
|  | { | 
|  | UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll; | 
|  |  | 
|  | high = answer >> BITS_PER_SI; | 
|  | low = answer; | 
|  | } | 
|  | #else | 
|  | /* fractype is DImode, but we need the result to be twice as wide. | 
|  | Assuming a widening multiply from DImode to TImode is not | 
|  | available, build one by hand.  */ | 
|  | { | 
|  | USItype nl = a->fraction.ll; | 
|  | USItype nh = a->fraction.ll >> BITS_PER_SI; | 
|  | USItype ml = b->fraction.ll; | 
|  | USItype mh = b->fraction.ll >> BITS_PER_SI; | 
|  | UDItype pp_ll = (UDItype) ml * nl; | 
|  | UDItype pp_hl = (UDItype) mh * nl; | 
|  | UDItype pp_lh = (UDItype) ml * nh; | 
|  | UDItype pp_hh = (UDItype) mh * nh; | 
|  | UDItype res2 = 0; | 
|  | UDItype res0 = 0; | 
|  | UDItype ps_hh__ = pp_hl + pp_lh; | 
|  | if (ps_hh__ < pp_hl) | 
|  | res2 += (UDItype)1 << BITS_PER_SI; | 
|  | pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI; | 
|  | res0 = pp_ll + pp_hl; | 
|  | if (res0 < pp_ll) | 
|  | res2++; | 
|  | res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh; | 
|  | high = res2; | 
|  | low = res0; | 
|  | } | 
|  | #endif | 
|  | } | 
|  |  | 
|  | tmp->normal_exp = a->normal_exp + b->normal_exp | 
|  | + FRAC_NBITS - (FRACBITS + NGARDS); | 
|  | tmp->sign = a->sign != b->sign; | 
|  | while (high >= IMPLICIT_2) | 
|  | { | 
|  | tmp->normal_exp++; | 
|  | if (high & 1) | 
|  | { | 
|  | low >>= 1; | 
|  | low |= FRACHIGH; | 
|  | } | 
|  | high >>= 1; | 
|  | } | 
|  | while (high < IMPLICIT_1) | 
|  | { | 
|  | tmp->normal_exp--; | 
|  |  | 
|  | high <<= 1; | 
|  | if (low & FRACHIGH) | 
|  | high |= 1; | 
|  | low <<= 1; | 
|  | } | 
|  |  | 
|  | if ((high & GARDMASK) == GARDMSB) | 
|  | { | 
|  | if (high & (1 << NGARDS)) | 
|  | { | 
|  | /* Because we're half way, we would round to even by adding | 
|  | GARDROUND + 1, except that's also done in the packing | 
|  | function, and rounding twice will lose precision and cause | 
|  | the result to be too far off.  Example: 32-bit floats with | 
|  | bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp | 
|  | off), not 0x1000 (more than 0.5ulp off).  */ | 
|  | } | 
|  | else if (low) | 
|  | { | 
|  | /* We're a further than half way by a small amount corresponding | 
|  | to the bits set in "low".  Knowing that, we round here and | 
|  | not in pack_d, because there we don't have "low" available | 
|  | anymore.  */ | 
|  | high += GARDROUND + 1; | 
|  |  | 
|  | /* Avoid further rounding in pack_d.  */ | 
|  | high &= ~(fractype) GARDMASK; | 
|  | } | 
|  | } | 
|  | tmp->fraction.ll = high; | 
|  | tmp->class = CLASS_NUMBER; | 
|  | return tmp; | 
|  | } | 
|  |  | 
|  | FLO_type | 
|  | multiply (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | fp_number_type tmp; | 
|  | const fp_number_type *res; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | res = _fpmul_parts (&a, &b, &tmp); | 
|  |  | 
|  | return pack_d (res); | 
|  | } | 
|  | #endif /* L_mul_sf || L_mul_df || L_mul_tf */ | 
|  |  | 
|  | #if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) | 
|  | static inline __attribute__ ((__always_inline__)) const fp_number_type * | 
|  | _fpdiv_parts (fp_number_type * a, | 
|  | fp_number_type * b) | 
|  | { | 
|  | fractype bit; | 
|  | fractype numerator; | 
|  | fractype denominator; | 
|  | fractype quotient; | 
|  |  | 
|  | if (isnan (a)) | 
|  | { | 
|  | return a; | 
|  | } | 
|  | if (isnan (b)) | 
|  | { | 
|  | return b; | 
|  | } | 
|  |  | 
|  | a->sign = a->sign ^ b->sign; | 
|  |  | 
|  | if (isinf (a) || iszero (a)) | 
|  | { | 
|  | if (a->class == b->class) | 
|  | return makenan (); | 
|  | return a; | 
|  | } | 
|  |  | 
|  | if (isinf (b)) | 
|  | { | 
|  | a->fraction.ll = 0; | 
|  | a->normal_exp = 0; | 
|  | return a; | 
|  | } | 
|  | if (iszero (b)) | 
|  | { | 
|  | a->class = CLASS_INFINITY; | 
|  | return a; | 
|  | } | 
|  |  | 
|  | /* Calculate the mantissa by multiplying both 64bit numbers to get a | 
|  | 128 bit number */ | 
|  | { | 
|  | /* quotient = | 
|  | ( numerator / denominator) * 2^(numerator exponent -  denominator exponent) | 
|  | */ | 
|  |  | 
|  | a->normal_exp = a->normal_exp - b->normal_exp; | 
|  | numerator = a->fraction.ll; | 
|  | denominator = b->fraction.ll; | 
|  |  | 
|  | if (numerator < denominator) | 
|  | { | 
|  | /* Fraction will be less than 1.0 */ | 
|  | numerator *= 2; | 
|  | a->normal_exp--; | 
|  | } | 
|  | bit = IMPLICIT_1; | 
|  | quotient = 0; | 
|  | /* ??? Does divide one bit at a time.  Optimize.  */ | 
|  | while (bit) | 
|  | { | 
|  | if (numerator >= denominator) | 
|  | { | 
|  | quotient |= bit; | 
|  | numerator -= denominator; | 
|  | } | 
|  | bit >>= 1; | 
|  | numerator *= 2; | 
|  | } | 
|  |  | 
|  | if ((quotient & GARDMASK) == GARDMSB) | 
|  | { | 
|  | if (quotient & (1 << NGARDS)) | 
|  | { | 
|  | /* Because we're half way, we would round to even by adding | 
|  | GARDROUND + 1, except that's also done in the packing | 
|  | function, and rounding twice will lose precision and cause | 
|  | the result to be too far off.  */ | 
|  | } | 
|  | else if (numerator) | 
|  | { | 
|  | /* We're a further than half way by the small amount | 
|  | corresponding to the bits set in "numerator".  Knowing | 
|  | that, we round here and not in pack_d, because there we | 
|  | don't have "numerator" available anymore.  */ | 
|  | quotient += GARDROUND + 1; | 
|  |  | 
|  | /* Avoid further rounding in pack_d.  */ | 
|  | quotient &= ~(fractype) GARDMASK; | 
|  | } | 
|  | } | 
|  |  | 
|  | a->fraction.ll = quotient; | 
|  | return (a); | 
|  | } | 
|  | } | 
|  |  | 
|  | FLO_type | 
|  | divide (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | const fp_number_type *res; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | res = _fpdiv_parts (&a, &b); | 
|  |  | 
|  | return pack_d (res); | 
|  | } | 
|  | #endif /* L_div_sf || L_div_df */ | 
|  |  | 
|  | #if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \ | 
|  | || defined(L_fpcmp_parts_tf) | 
|  | /* according to the demo, fpcmp returns a comparison with 0... thus | 
|  | a<b -> -1 | 
|  | a==b -> 0 | 
|  | a>b -> +1 | 
|  | */ | 
|  |  | 
|  | int | 
|  | __fpcmp_parts (fp_number_type * a, fp_number_type * b) | 
|  | { | 
|  | #if 0 | 
|  | /* either nan -> unordered. Must be checked outside of this routine.  */ | 
|  | if (isnan (a) && isnan (b)) | 
|  | { | 
|  | return 1;			/* still unordered! */ | 
|  | } | 
|  | #endif | 
|  |  | 
|  | if (isnan (a) || isnan (b)) | 
|  | { | 
|  | return 1;			/* how to indicate unordered compare? */ | 
|  | } | 
|  | if (isinf (a) && isinf (b)) | 
|  | { | 
|  | /* +inf > -inf, but +inf != +inf */ | 
|  | /* b    \a| +inf(0)| -inf(1) | 
|  | ______\+--------+-------- | 
|  | +inf(0)| a==b(0)| a<b(-1) | 
|  | -------+--------+-------- | 
|  | -inf(1)| a>b(1) | a==b(0) | 
|  | -------+--------+-------- | 
|  | So since unordered must be nonzero, just line up the columns... | 
|  | */ | 
|  | return b->sign - a->sign; | 
|  | } | 
|  | /* but not both...  */ | 
|  | if (isinf (a)) | 
|  | { | 
|  | return a->sign ? -1 : 1; | 
|  | } | 
|  | if (isinf (b)) | 
|  | { | 
|  | return b->sign ? 1 : -1; | 
|  | } | 
|  | if (iszero (a) && iszero (b)) | 
|  | { | 
|  | return 0; | 
|  | } | 
|  | if (iszero (a)) | 
|  | { | 
|  | return b->sign ? 1 : -1; | 
|  | } | 
|  | if (iszero (b)) | 
|  | { | 
|  | return a->sign ? -1 : 1; | 
|  | } | 
|  | /* now both are "normal".  */ | 
|  | if (a->sign != b->sign) | 
|  | { | 
|  | /* opposite signs */ | 
|  | return a->sign ? -1 : 1; | 
|  | } | 
|  | /* same sign; exponents? */ | 
|  | if (a->normal_exp > b->normal_exp) | 
|  | { | 
|  | return a->sign ? -1 : 1; | 
|  | } | 
|  | if (a->normal_exp < b->normal_exp) | 
|  | { | 
|  | return a->sign ? 1 : -1; | 
|  | } | 
|  | /* same exponents; check size.  */ | 
|  | if (a->fraction.ll > b->fraction.ll) | 
|  | { | 
|  | return a->sign ? -1 : 1; | 
|  | } | 
|  | if (a->fraction.ll < b->fraction.ll) | 
|  | { | 
|  | return a->sign ? 1 : -1; | 
|  | } | 
|  | /* after all that, they're equal.  */ | 
|  | return 0; | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf) | 
|  | CMPtype | 
|  | compare (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | return __fpcmp_parts (&a, &b); | 
|  | } | 
|  | #endif /* L_compare_sf || L_compare_df */ | 
|  |  | 
|  | /* These should be optimized for their specific tasks someday.  */ | 
|  |  | 
|  | #if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) | 
|  | CMPtype | 
|  | _eq_f2 (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | if (isnan (&a) || isnan (&b)) | 
|  | return 1;			/* false, truth == 0 */ | 
|  |  | 
|  | return __fpcmp_parts (&a, &b) ; | 
|  | } | 
|  | #endif /* L_eq_sf || L_eq_df */ | 
|  |  | 
|  | #if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) | 
|  | CMPtype | 
|  | _ne_f2 (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | if (isnan (&a) || isnan (&b)) | 
|  | return 1;			/* true, truth != 0 */ | 
|  |  | 
|  | return  __fpcmp_parts (&a, &b) ; | 
|  | } | 
|  | #endif /* L_ne_sf || L_ne_df */ | 
|  |  | 
|  | #if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) | 
|  | CMPtype | 
|  | _gt_f2 (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | if (isnan (&a) || isnan (&b)) | 
|  | return -1;			/* false, truth > 0 */ | 
|  |  | 
|  | return __fpcmp_parts (&a, &b); | 
|  | } | 
|  | #endif /* L_gt_sf || L_gt_df */ | 
|  |  | 
|  | #if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) | 
|  | CMPtype | 
|  | _ge_f2 (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | if (isnan (&a) || isnan (&b)) | 
|  | return -1;			/* false, truth >= 0 */ | 
|  | return __fpcmp_parts (&a, &b) ; | 
|  | } | 
|  | #endif /* L_ge_sf || L_ge_df */ | 
|  |  | 
|  | #if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) | 
|  | CMPtype | 
|  | _lt_f2 (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | if (isnan (&a) || isnan (&b)) | 
|  | return 1;			/* false, truth < 0 */ | 
|  |  | 
|  | return __fpcmp_parts (&a, &b); | 
|  | } | 
|  | #endif /* L_lt_sf || L_lt_df */ | 
|  |  | 
|  | #if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) | 
|  | CMPtype | 
|  | _le_f2 (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | if (isnan (&a) || isnan (&b)) | 
|  | return 1;			/* false, truth <= 0 */ | 
|  |  | 
|  | return __fpcmp_parts (&a, &b) ; | 
|  | } | 
|  | #endif /* L_le_sf || L_le_df */ | 
|  |  | 
|  | #if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) | 
|  | CMPtype | 
|  | _unord_f2 (FLO_type arg_a, FLO_type arg_b) | 
|  | { | 
|  | fp_number_type a; | 
|  | fp_number_type b; | 
|  | FLO_union_type au, bu; | 
|  |  | 
|  | au.value = arg_a; | 
|  | bu.value = arg_b; | 
|  |  | 
|  | unpack_d (&au, &a); | 
|  | unpack_d (&bu, &b); | 
|  |  | 
|  | return (isnan (&a) || isnan (&b)); | 
|  | } | 
|  | #endif /* L_unord_sf || L_unord_df */ | 
|  |  | 
|  | #if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) | 
|  | FLO_type | 
|  | si_to_float (SItype arg_a) | 
|  | { | 
|  | fp_number_type in; | 
|  |  | 
|  | in.class = CLASS_NUMBER; | 
|  | in.sign = arg_a < 0; | 
|  | if (!arg_a) | 
|  | { | 
|  | in.class = CLASS_ZERO; | 
|  | } | 
|  | else | 
|  | { | 
|  | USItype uarg; | 
|  | int shift; | 
|  | in.normal_exp = FRACBITS + NGARDS; | 
|  | if (in.sign) | 
|  | { | 
|  | /* Special case for minint, since there is no +ve integer | 
|  | representation for it */ | 
|  | if (arg_a == (- MAX_SI_INT - 1)) | 
|  | { | 
|  | return (FLO_type)(- MAX_SI_INT - 1); | 
|  | } | 
|  | uarg = (-arg_a); | 
|  | } | 
|  | else | 
|  | uarg = arg_a; | 
|  |  | 
|  | in.fraction.ll = uarg; | 
|  | shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS); | 
|  | if (shift > 0) | 
|  | { | 
|  | in.fraction.ll <<= shift; | 
|  | in.normal_exp -= shift; | 
|  | } | 
|  | } | 
|  | return pack_d (&in); | 
|  | } | 
|  | #endif /* L_si_to_sf || L_si_to_df */ | 
|  |  | 
|  | #if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) | 
|  | FLO_type | 
|  | usi_to_float (USItype arg_a) | 
|  | { | 
|  | fp_number_type in; | 
|  |  | 
|  | in.sign = 0; | 
|  | if (!arg_a) | 
|  | { | 
|  | in.class = CLASS_ZERO; | 
|  | } | 
|  | else | 
|  | { | 
|  | int shift; | 
|  | in.class = CLASS_NUMBER; | 
|  | in.normal_exp = FRACBITS + NGARDS; | 
|  | in.fraction.ll = arg_a; | 
|  |  | 
|  | shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS); | 
|  | if (shift < 0) | 
|  | { | 
|  | fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1); | 
|  | in.fraction.ll >>= -shift; | 
|  | in.fraction.ll |= (guard != 0); | 
|  | in.normal_exp -= shift; | 
|  | } | 
|  | else if (shift > 0) | 
|  | { | 
|  | in.fraction.ll <<= shift; | 
|  | in.normal_exp -= shift; | 
|  | } | 
|  | } | 
|  | return pack_d (&in); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) | 
|  | SItype | 
|  | float_to_si (FLO_type arg_a) | 
|  | { | 
|  | fp_number_type a; | 
|  | SItype tmp; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &a); | 
|  |  | 
|  | if (iszero (&a)) | 
|  | return 0; | 
|  | if (isnan (&a)) | 
|  | return 0; | 
|  | /* get reasonable MAX_SI_INT...  */ | 
|  | if (isinf (&a)) | 
|  | return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT; | 
|  | /* it is a number, but a small one */ | 
|  | if (a.normal_exp < 0) | 
|  | return 0; | 
|  | if (a.normal_exp > BITS_PER_SI - 2) | 
|  | return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT; | 
|  | tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp); | 
|  | return a.sign ? (-tmp) : (tmp); | 
|  | } | 
|  | #endif /* L_sf_to_si || L_df_to_si */ | 
|  |  | 
|  | #if defined(L_tf_to_usi) | 
|  | USItype | 
|  | float_to_usi (FLO_type arg_a) | 
|  | { | 
|  | fp_number_type a; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &a); | 
|  |  | 
|  | if (iszero (&a)) | 
|  | return 0; | 
|  | if (isnan (&a)) | 
|  | return 0; | 
|  | /* it is a negative number */ | 
|  | if (a.sign) | 
|  | return 0; | 
|  | /* get reasonable MAX_USI_INT...  */ | 
|  | if (isinf (&a)) | 
|  | return MAX_USI_INT; | 
|  | /* it is a number, but a small one */ | 
|  | if (a.normal_exp < 0) | 
|  | return 0; | 
|  | if (a.normal_exp > BITS_PER_SI - 1) | 
|  | return MAX_USI_INT; | 
|  | else if (a.normal_exp > (FRACBITS + NGARDS)) | 
|  | return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS)); | 
|  | else | 
|  | return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp); | 
|  | } | 
|  | #endif /* L_tf_to_usi */ | 
|  |  | 
|  | #if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) | 
|  | FLO_type | 
|  | negate (FLO_type arg_a) | 
|  | { | 
|  | fp_number_type a; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &a); | 
|  |  | 
|  | flip_sign (&a); | 
|  | return pack_d (&a); | 
|  | } | 
|  | #endif /* L_negate_sf || L_negate_df */ | 
|  |  | 
|  | #ifdef FLOAT | 
|  |  | 
|  | #if defined(L_make_sf) | 
|  | SFtype | 
|  | __make_fp(fp_class_type class, | 
|  | unsigned int sign, | 
|  | int exp, | 
|  | USItype frac) | 
|  | { | 
|  | fp_number_type in; | 
|  |  | 
|  | in.class = class; | 
|  | in.sign = sign; | 
|  | in.normal_exp = exp; | 
|  | in.fraction.ll = frac; | 
|  | return pack_d (&in); | 
|  | } | 
|  | #endif /* L_make_sf */ | 
|  |  | 
|  | #ifndef FLOAT_ONLY | 
|  |  | 
|  | /* This enables one to build an fp library that supports float but not double. | 
|  | Otherwise, we would get an undefined reference to __make_dp. | 
|  | This is needed for some 8-bit ports that can't handle well values that | 
|  | are 8-bytes in size, so we just don't support double for them at all.  */ | 
|  |  | 
|  | #if defined(L_sf_to_df) | 
|  | DFtype | 
|  | sf_to_df (SFtype arg_a) | 
|  | { | 
|  | fp_number_type in; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &in); | 
|  |  | 
|  | return __make_dp (in.class, in.sign, in.normal_exp, | 
|  | ((UDItype) in.fraction.ll) << F_D_BITOFF); | 
|  | } | 
|  | #endif /* L_sf_to_df */ | 
|  |  | 
|  | #if defined(L_sf_to_tf) && defined(TMODES) | 
|  | TFtype | 
|  | sf_to_tf (SFtype arg_a) | 
|  | { | 
|  | fp_number_type in; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &in); | 
|  |  | 
|  | return __make_tp (in.class, in.sign, in.normal_exp, | 
|  | ((UTItype) in.fraction.ll) << F_T_BITOFF); | 
|  | } | 
|  | #endif /* L_sf_to_df */ | 
|  |  | 
|  | #endif /* ! FLOAT_ONLY */ | 
|  | #endif /* FLOAT */ | 
|  |  | 
|  | #ifndef FLOAT | 
|  |  | 
|  | extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype); | 
|  |  | 
|  | #if defined(L_make_df) | 
|  | DFtype | 
|  | __make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac) | 
|  | { | 
|  | fp_number_type in; | 
|  |  | 
|  | in.class = class; | 
|  | in.sign = sign; | 
|  | in.normal_exp = exp; | 
|  | in.fraction.ll = frac; | 
|  | return pack_d (&in); | 
|  | } | 
|  | #endif /* L_make_df */ | 
|  |  | 
|  | #if defined(L_df_to_sf) | 
|  | SFtype | 
|  | df_to_sf (DFtype arg_a) | 
|  | { | 
|  | fp_number_type in; | 
|  | USItype sffrac; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &in); | 
|  |  | 
|  | sffrac = in.fraction.ll >> F_D_BITOFF; | 
|  |  | 
|  | /* We set the lowest guard bit in SFFRAC if we discarded any non | 
|  | zero bits.  */ | 
|  | if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0) | 
|  | sffrac |= 1; | 
|  |  | 
|  | return __make_fp (in.class, in.sign, in.normal_exp, sffrac); | 
|  | } | 
|  | #endif /* L_df_to_sf */ | 
|  |  | 
|  | #if defined(L_df_to_tf) && defined(TMODES) \ | 
|  | && !defined(FLOAT) && !defined(TFLOAT) | 
|  | TFtype | 
|  | df_to_tf (DFtype arg_a) | 
|  | { | 
|  | fp_number_type in; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &in); | 
|  |  | 
|  | return __make_tp (in.class, in.sign, in.normal_exp, | 
|  | ((UTItype) in.fraction.ll) << D_T_BITOFF); | 
|  | } | 
|  | #endif /* L_sf_to_df */ | 
|  |  | 
|  | #ifdef TFLOAT | 
|  | #if defined(L_make_tf) | 
|  | TFtype | 
|  | __make_tp(fp_class_type class, | 
|  | unsigned int sign, | 
|  | int exp, | 
|  | UTItype frac) | 
|  | { | 
|  | fp_number_type in; | 
|  |  | 
|  | in.class = class; | 
|  | in.sign = sign; | 
|  | in.normal_exp = exp; | 
|  | in.fraction.ll = frac; | 
|  | return pack_d (&in); | 
|  | } | 
|  | #endif /* L_make_tf */ | 
|  |  | 
|  | #if defined(L_tf_to_df) | 
|  | DFtype | 
|  | tf_to_df (TFtype arg_a) | 
|  | { | 
|  | fp_number_type in; | 
|  | UDItype sffrac; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &in); | 
|  |  | 
|  | sffrac = in.fraction.ll >> D_T_BITOFF; | 
|  |  | 
|  | /* We set the lowest guard bit in SFFRAC if we discarded any non | 
|  | zero bits.  */ | 
|  | if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0) | 
|  | sffrac |= 1; | 
|  |  | 
|  | return __make_dp (in.class, in.sign, in.normal_exp, sffrac); | 
|  | } | 
|  | #endif /* L_tf_to_df */ | 
|  |  | 
|  | #if defined(L_tf_to_sf) | 
|  | SFtype | 
|  | tf_to_sf (TFtype arg_a) | 
|  | { | 
|  | fp_number_type in; | 
|  | USItype sffrac; | 
|  | FLO_union_type au; | 
|  |  | 
|  | au.value = arg_a; | 
|  | unpack_d (&au, &in); | 
|  |  | 
|  | sffrac = in.fraction.ll >> F_T_BITOFF; | 
|  |  | 
|  | /* We set the lowest guard bit in SFFRAC if we discarded any non | 
|  | zero bits.  */ | 
|  | if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0) | 
|  | sffrac |= 1; | 
|  |  | 
|  | return __make_fp (in.class, in.sign, in.normal_exp, sffrac); | 
|  | } | 
|  | #endif /* L_tf_to_sf */ | 
|  | #endif /* TFLOAT */ | 
|  |  | 
|  | #endif /* ! FLOAT */ | 
|  | #endif /* !EXTENDED_FLOAT_STUBS */ |