11debfc3dSmrg /* This is a software floating point library which can be used
21debfc3dSmrg for targets without hardware floating point.
3*8feb0f0bSmrg Copyright (C) 1994-2020 Free Software Foundation, Inc.
41debfc3dSmrg
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
81debfc3dSmrg the terms of the GNU General Public License as published by the Free
91debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
101debfc3dSmrg version.
111debfc3dSmrg
121debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
141debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
151debfc3dSmrg for more details.
161debfc3dSmrg
171debfc3dSmrg Under Section 7 of GPL version 3, you are granted additional
181debfc3dSmrg permissions described in the GCC Runtime Library Exception, version
191debfc3dSmrg 3.1, as published by the Free Software Foundation.
201debfc3dSmrg
211debfc3dSmrg You should have received a copy of the GNU General Public License and
221debfc3dSmrg a copy of the GCC Runtime Library Exception along with this program;
231debfc3dSmrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
241debfc3dSmrg <http://www.gnu.org/licenses/>. */
251debfc3dSmrg
261debfc3dSmrg /* This implements IEEE 754 format arithmetic, but does not provide a
271debfc3dSmrg mechanism for setting the rounding mode, or for generating or handling
281debfc3dSmrg exceptions.
291debfc3dSmrg
301debfc3dSmrg The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
311debfc3dSmrg Wilson, all of Cygnus Support. */
321debfc3dSmrg
331debfc3dSmrg /* The intended way to use this file is to make two copies, add `#define FLOAT'
341debfc3dSmrg to one copy, then compile both copies and add them to libgcc.a. */
351debfc3dSmrg
361debfc3dSmrg #include "tconfig.h"
371debfc3dSmrg #include "coretypes.h"
381debfc3dSmrg #include "tm.h"
391debfc3dSmrg #include "libgcc_tm.h"
401debfc3dSmrg #include "fp-bit.h"
411debfc3dSmrg
421debfc3dSmrg /* The following macros can be defined to change the behavior of this file:
431debfc3dSmrg FLOAT: Implement a `float', aka SFmode, fp library. If this is not
441debfc3dSmrg defined, then this file implements a `double', aka DFmode, fp library.
451debfc3dSmrg FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
461debfc3dSmrg don't include float->double conversion which requires the double library.
471debfc3dSmrg This is useful only for machines which can't support doubles, e.g. some
481debfc3dSmrg 8-bit processors.
491debfc3dSmrg CMPtype: Specify the type that floating point compares should return.
501debfc3dSmrg This defaults to SItype, aka int.
511debfc3dSmrg _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
521debfc3dSmrg two integers to the FLO_union_type.
531debfc3dSmrg NO_DENORMALS: Disable handling of denormals.
541debfc3dSmrg NO_NANS: Disable nan and infinity handling
551debfc3dSmrg SMALL_MACHINE: Useful when operations on QIs and HIs are faster
561debfc3dSmrg than on an SI */
571debfc3dSmrg
581debfc3dSmrg /* We don't currently support extended floats (long doubles) on machines
591debfc3dSmrg without hardware to deal with them.
601debfc3dSmrg
611debfc3dSmrg These stubs are just to keep the linker from complaining about unresolved
621debfc3dSmrg references which can be pulled in from libio & libstdc++, even if the
631debfc3dSmrg user isn't using long doubles. However, they may generate an unresolved
641debfc3dSmrg external to abort if abort is not used by the function, and the stubs
651debfc3dSmrg are referenced from within libc, since libgcc goes before and after the
661debfc3dSmrg system library. */
671debfc3dSmrg
681debfc3dSmrg #ifdef DECLARE_LIBRARY_RENAMES
691debfc3dSmrg DECLARE_LIBRARY_RENAMES
701debfc3dSmrg #endif
711debfc3dSmrg
721debfc3dSmrg #ifdef EXTENDED_FLOAT_STUBS
731debfc3dSmrg extern void abort (void);
__extendsfxf2(void)741debfc3dSmrg void __extendsfxf2 (void) { abort(); }
__extenddfxf2(void)751debfc3dSmrg void __extenddfxf2 (void) { abort(); }
__truncxfdf2(void)761debfc3dSmrg void __truncxfdf2 (void) { abort(); }
__truncxfsf2(void)771debfc3dSmrg void __truncxfsf2 (void) { abort(); }
__fixxfsi(void)781debfc3dSmrg void __fixxfsi (void) { abort(); }
__floatsixf(void)791debfc3dSmrg void __floatsixf (void) { abort(); }
__addxf3(void)801debfc3dSmrg void __addxf3 (void) { abort(); }
__subxf3(void)811debfc3dSmrg void __subxf3 (void) { abort(); }
__mulxf3(void)821debfc3dSmrg void __mulxf3 (void) { abort(); }
__divxf3(void)831debfc3dSmrg void __divxf3 (void) { abort(); }
__negxf2(void)841debfc3dSmrg void __negxf2 (void) { abort(); }
__eqxf2(void)851debfc3dSmrg void __eqxf2 (void) { abort(); }
__nexf2(void)861debfc3dSmrg void __nexf2 (void) { abort(); }
__gtxf2(void)871debfc3dSmrg void __gtxf2 (void) { abort(); }
__gexf2(void)881debfc3dSmrg void __gexf2 (void) { abort(); }
__lexf2(void)891debfc3dSmrg void __lexf2 (void) { abort(); }
__ltxf2(void)901debfc3dSmrg void __ltxf2 (void) { abort(); }
911debfc3dSmrg
__extendsftf2(void)921debfc3dSmrg void __extendsftf2 (void) { abort(); }
__extenddftf2(void)931debfc3dSmrg void __extenddftf2 (void) { abort(); }
__trunctfdf2(void)941debfc3dSmrg void __trunctfdf2 (void) { abort(); }
__trunctfsf2(void)951debfc3dSmrg void __trunctfsf2 (void) { abort(); }
__fixtfsi(void)961debfc3dSmrg void __fixtfsi (void) { abort(); }
__floatsitf(void)971debfc3dSmrg void __floatsitf (void) { abort(); }
__addtf3(void)981debfc3dSmrg void __addtf3 (void) { abort(); }
__subtf3(void)991debfc3dSmrg void __subtf3 (void) { abort(); }
__multf3(void)1001debfc3dSmrg void __multf3 (void) { abort(); }
__divtf3(void)1011debfc3dSmrg void __divtf3 (void) { abort(); }
__negtf2(void)1021debfc3dSmrg void __negtf2 (void) { abort(); }
__eqtf2(void)1031debfc3dSmrg void __eqtf2 (void) { abort(); }
__netf2(void)1041debfc3dSmrg void __netf2 (void) { abort(); }
__gttf2(void)1051debfc3dSmrg void __gttf2 (void) { abort(); }
__getf2(void)1061debfc3dSmrg void __getf2 (void) { abort(); }
__letf2(void)1071debfc3dSmrg void __letf2 (void) { abort(); }
__lttf2(void)1081debfc3dSmrg void __lttf2 (void) { abort(); }
1091debfc3dSmrg #else /* !EXTENDED_FLOAT_STUBS, rest of file */
1101debfc3dSmrg
1111debfc3dSmrg /* IEEE "special" number predicates */
1121debfc3dSmrg
1131debfc3dSmrg #ifdef NO_NANS
1141debfc3dSmrg
1151debfc3dSmrg #define nan() 0
1161debfc3dSmrg #define isnan(x) 0
1171debfc3dSmrg #define isinf(x) 0
1181debfc3dSmrg #else
1191debfc3dSmrg
1201debfc3dSmrg #if defined L_thenan_sf
1211debfc3dSmrg const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1221debfc3dSmrg #elif defined L_thenan_df
1231debfc3dSmrg const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1241debfc3dSmrg #elif defined L_thenan_tf
1251debfc3dSmrg const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1261debfc3dSmrg #elif defined TFLOAT
1271debfc3dSmrg extern const fp_number_type __thenan_tf;
1281debfc3dSmrg #elif defined FLOAT
1291debfc3dSmrg extern const fp_number_type __thenan_sf;
1301debfc3dSmrg #else
1311debfc3dSmrg extern const fp_number_type __thenan_df;
1321debfc3dSmrg #endif
1331debfc3dSmrg
1341debfc3dSmrg INLINE
1351debfc3dSmrg static const fp_number_type *
1361debfc3dSmrg makenan (void)
1371debfc3dSmrg {
1381debfc3dSmrg #ifdef TFLOAT
1391debfc3dSmrg return & __thenan_tf;
1401debfc3dSmrg #elif defined FLOAT
1411debfc3dSmrg return & __thenan_sf;
1421debfc3dSmrg #else
1431debfc3dSmrg return & __thenan_df;
1441debfc3dSmrg #endif
1451debfc3dSmrg }
1461debfc3dSmrg
1471debfc3dSmrg INLINE
1481debfc3dSmrg static int
1491debfc3dSmrg isnan (const fp_number_type *x)
1501debfc3dSmrg {
1511debfc3dSmrg return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN,
1521debfc3dSmrg 0);
1531debfc3dSmrg }
1541debfc3dSmrg
1551debfc3dSmrg INLINE
1561debfc3dSmrg static int
1571debfc3dSmrg isinf (const fp_number_type * x)
1581debfc3dSmrg {
1591debfc3dSmrg return __builtin_expect (x->class == CLASS_INFINITY, 0);
1601debfc3dSmrg }
1611debfc3dSmrg
1621debfc3dSmrg #endif /* NO_NANS */
1631debfc3dSmrg
1641debfc3dSmrg INLINE
1651debfc3dSmrg static int
1661debfc3dSmrg iszero (const fp_number_type * x)
1671debfc3dSmrg {
1681debfc3dSmrg return x->class == CLASS_ZERO;
1691debfc3dSmrg }
1701debfc3dSmrg
1711debfc3dSmrg INLINE
1721debfc3dSmrg static void
1731debfc3dSmrg flip_sign ( fp_number_type * x)
1741debfc3dSmrg {
1751debfc3dSmrg x->sign = !x->sign;
1761debfc3dSmrg }
1771debfc3dSmrg
1781debfc3dSmrg /* Count leading zeroes in N. */
1791debfc3dSmrg INLINE
1801debfc3dSmrg static int
1811debfc3dSmrg clzusi (USItype n)
1821debfc3dSmrg {
1831debfc3dSmrg extern int __clzsi2 (USItype);
1841debfc3dSmrg if (sizeof (USItype) == sizeof (unsigned int))
1851debfc3dSmrg return __builtin_clz (n);
1861debfc3dSmrg else if (sizeof (USItype) == sizeof (unsigned long))
1871debfc3dSmrg return __builtin_clzl (n);
1881debfc3dSmrg else if (sizeof (USItype) == sizeof (unsigned long long))
1891debfc3dSmrg return __builtin_clzll (n);
1901debfc3dSmrg else
1911debfc3dSmrg return __clzsi2 (n);
1921debfc3dSmrg }
1931debfc3dSmrg
1941debfc3dSmrg extern FLO_type pack_d (const fp_number_type * );
1951debfc3dSmrg
1961debfc3dSmrg #if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
1971debfc3dSmrg FLO_type
1981debfc3dSmrg pack_d (const fp_number_type *src)
1991debfc3dSmrg {
2001debfc3dSmrg FLO_union_type dst;
2011debfc3dSmrg fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
2021debfc3dSmrg int sign = src->sign;
2031debfc3dSmrg int exp = 0;
2041debfc3dSmrg
2051debfc3dSmrg if (isnan (src))
2061debfc3dSmrg {
2071debfc3dSmrg exp = EXPMAX;
2081debfc3dSmrg /* Restore the NaN's payload. */
2091debfc3dSmrg fraction >>= NGARDS;
2101debfc3dSmrg fraction &= QUIET_NAN - 1;
2111debfc3dSmrg if (src->class == CLASS_QNAN || 1)
2121debfc3dSmrg {
2131debfc3dSmrg #ifdef QUIET_NAN_NEGATED
2141debfc3dSmrg /* The quiet/signaling bit remains unset. */
2151debfc3dSmrg /* Make sure the fraction has a non-zero value. */
2161debfc3dSmrg if (fraction == 0)
2171debfc3dSmrg fraction |= QUIET_NAN - 1;
2181debfc3dSmrg #else
2191debfc3dSmrg /* Set the quiet/signaling bit. */
2201debfc3dSmrg fraction |= QUIET_NAN;
2211debfc3dSmrg #endif
2221debfc3dSmrg }
2231debfc3dSmrg }
2241debfc3dSmrg else if (isinf (src))
2251debfc3dSmrg {
2261debfc3dSmrg exp = EXPMAX;
2271debfc3dSmrg fraction = 0;
2281debfc3dSmrg }
2291debfc3dSmrg else if (iszero (src))
2301debfc3dSmrg {
2311debfc3dSmrg exp = 0;
2321debfc3dSmrg fraction = 0;
2331debfc3dSmrg }
2341debfc3dSmrg else if (fraction == 0)
2351debfc3dSmrg {
2361debfc3dSmrg exp = 0;
2371debfc3dSmrg }
2381debfc3dSmrg else
2391debfc3dSmrg {
2401debfc3dSmrg if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0))
2411debfc3dSmrg {
2421debfc3dSmrg #ifdef NO_DENORMALS
2431debfc3dSmrg /* Go straight to a zero representation if denormals are not
2441debfc3dSmrg supported. The denormal handling would be harmless but
2451debfc3dSmrg isn't unnecessary. */
2461debfc3dSmrg exp = 0;
2471debfc3dSmrg fraction = 0;
2481debfc3dSmrg #else /* NO_DENORMALS */
2491debfc3dSmrg /* This number's exponent is too low to fit into the bits
2501debfc3dSmrg available in the number, so we'll store 0 in the exponent and
2511debfc3dSmrg shift the fraction to the right to make up for it. */
2521debfc3dSmrg
2531debfc3dSmrg int shift = NORMAL_EXPMIN - src->normal_exp;
2541debfc3dSmrg
2551debfc3dSmrg exp = 0;
2561debfc3dSmrg
2571debfc3dSmrg if (shift > FRAC_NBITS - NGARDS)
2581debfc3dSmrg {
2591debfc3dSmrg /* No point shifting, since it's more that 64 out. */
2601debfc3dSmrg fraction = 0;
2611debfc3dSmrg }
2621debfc3dSmrg else
2631debfc3dSmrg {
2641debfc3dSmrg int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
2651debfc3dSmrg fraction = (fraction >> shift) | lowbit;
2661debfc3dSmrg }
2671debfc3dSmrg if ((fraction & GARDMASK) == GARDMSB)
2681debfc3dSmrg {
2691debfc3dSmrg if ((fraction & (1 << NGARDS)))
2701debfc3dSmrg fraction += GARDROUND + 1;
2711debfc3dSmrg }
2721debfc3dSmrg else
2731debfc3dSmrg {
2741debfc3dSmrg /* Add to the guards to round up. */
2751debfc3dSmrg fraction += GARDROUND;
2761debfc3dSmrg }
2771debfc3dSmrg /* Perhaps the rounding means we now need to change the
2781debfc3dSmrg exponent, because the fraction is no longer denormal. */
2791debfc3dSmrg if (fraction >= IMPLICIT_1)
2801debfc3dSmrg {
2811debfc3dSmrg exp += 1;
2821debfc3dSmrg }
2831debfc3dSmrg fraction >>= NGARDS;
2841debfc3dSmrg #endif /* NO_DENORMALS */
2851debfc3dSmrg }
2861debfc3dSmrg else if (__builtin_expect (src->normal_exp > EXPBIAS, 0))
2871debfc3dSmrg {
2881debfc3dSmrg exp = EXPMAX;
2891debfc3dSmrg fraction = 0;
2901debfc3dSmrg }
2911debfc3dSmrg else
2921debfc3dSmrg {
2931debfc3dSmrg exp = src->normal_exp + EXPBIAS;
2941debfc3dSmrg /* IF the gard bits are the all zero, but the first, then we're
2951debfc3dSmrg half way between two numbers, choose the one which makes the
2961debfc3dSmrg lsb of the answer 0. */
2971debfc3dSmrg if ((fraction & GARDMASK) == GARDMSB)
2981debfc3dSmrg {
2991debfc3dSmrg if (fraction & (1 << NGARDS))
3001debfc3dSmrg fraction += GARDROUND + 1;
3011debfc3dSmrg }
3021debfc3dSmrg else
3031debfc3dSmrg {
3041debfc3dSmrg /* Add a one to the guards to round up */
3051debfc3dSmrg fraction += GARDROUND;
3061debfc3dSmrg }
3071debfc3dSmrg if (fraction >= IMPLICIT_2)
3081debfc3dSmrg {
3091debfc3dSmrg fraction >>= 1;
3101debfc3dSmrg exp += 1;
3111debfc3dSmrg }
3121debfc3dSmrg fraction >>= NGARDS;
3131debfc3dSmrg }
3141debfc3dSmrg }
3151debfc3dSmrg
3161debfc3dSmrg /* We previously used bitfields to store the number, but this doesn't
3171debfc3dSmrg handle little/big endian systems conveniently, so use shifts and
3181debfc3dSmrg masks */
3191debfc3dSmrg #if defined TFLOAT && defined HALFFRACBITS
3201debfc3dSmrg {
3211debfc3dSmrg halffractype high, low, unity;
3221debfc3dSmrg int lowsign, lowexp;
3231debfc3dSmrg
3241debfc3dSmrg unity = (halffractype) 1 << HALFFRACBITS;
3251debfc3dSmrg
3261debfc3dSmrg /* Set HIGH to the high double's significand, masking out the implicit 1.
3271debfc3dSmrg Set LOW to the low double's full significand. */
3281debfc3dSmrg high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
3291debfc3dSmrg low = fraction & (unity * 2 - 1);
3301debfc3dSmrg
3311debfc3dSmrg /* Get the initial sign and exponent of the low double. */
3321debfc3dSmrg lowexp = exp - HALFFRACBITS - 1;
3331debfc3dSmrg lowsign = sign;
3341debfc3dSmrg
3351debfc3dSmrg /* HIGH should be rounded like a normal double, making |LOW| <=
3361debfc3dSmrg 0.5 ULP of HIGH. Assume round-to-nearest. */
3371debfc3dSmrg if (exp < EXPMAX)
3381debfc3dSmrg if (low > unity || (low == unity && (high & 1) == 1))
3391debfc3dSmrg {
3401debfc3dSmrg /* Round HIGH up and adjust LOW to match. */
3411debfc3dSmrg high++;
3421debfc3dSmrg if (high == unity)
3431debfc3dSmrg {
3441debfc3dSmrg /* May make it infinite, but that's OK. */
3451debfc3dSmrg high = 0;
3461debfc3dSmrg exp++;
3471debfc3dSmrg }
3481debfc3dSmrg low = unity * 2 - low;
3491debfc3dSmrg lowsign ^= 1;
3501debfc3dSmrg }
3511debfc3dSmrg
3521debfc3dSmrg high |= (halffractype) exp << HALFFRACBITS;
3531debfc3dSmrg high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
3541debfc3dSmrg
3551debfc3dSmrg if (exp == EXPMAX || exp == 0 || low == 0)
3561debfc3dSmrg low = 0;
3571debfc3dSmrg else
3581debfc3dSmrg {
3591debfc3dSmrg while (lowexp > 0 && low < unity)
3601debfc3dSmrg {
3611debfc3dSmrg low <<= 1;
3621debfc3dSmrg lowexp--;
3631debfc3dSmrg }
3641debfc3dSmrg
3651debfc3dSmrg if (lowexp <= 0)
3661debfc3dSmrg {
3671debfc3dSmrg halffractype roundmsb, round;
3681debfc3dSmrg int shift;
3691debfc3dSmrg
3701debfc3dSmrg shift = 1 - lowexp;
3711debfc3dSmrg roundmsb = (1 << (shift - 1));
3721debfc3dSmrg round = low & ((roundmsb << 1) - 1);
3731debfc3dSmrg
3741debfc3dSmrg low >>= shift;
3751debfc3dSmrg lowexp = 0;
3761debfc3dSmrg
3771debfc3dSmrg if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
3781debfc3dSmrg {
3791debfc3dSmrg low++;
3801debfc3dSmrg if (low == unity)
3811debfc3dSmrg /* LOW rounds up to the smallest normal number. */
3821debfc3dSmrg lowexp++;
3831debfc3dSmrg }
3841debfc3dSmrg }
3851debfc3dSmrg
3861debfc3dSmrg low &= unity - 1;
3871debfc3dSmrg low |= (halffractype) lowexp << HALFFRACBITS;
3881debfc3dSmrg low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
3891debfc3dSmrg }
3901debfc3dSmrg dst.value_raw = ((fractype) high << HALFSHIFT) | low;
3911debfc3dSmrg }
3921debfc3dSmrg #else
3931debfc3dSmrg dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
3941debfc3dSmrg dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
3951debfc3dSmrg dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
3961debfc3dSmrg #endif
3971debfc3dSmrg
3981debfc3dSmrg #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
3991debfc3dSmrg #ifdef TFLOAT
4001debfc3dSmrg {
4011debfc3dSmrg qrtrfractype tmp1 = dst.words[0];
4021debfc3dSmrg qrtrfractype tmp2 = dst.words[1];
4031debfc3dSmrg dst.words[0] = dst.words[3];
4041debfc3dSmrg dst.words[1] = dst.words[2];
4051debfc3dSmrg dst.words[2] = tmp2;
4061debfc3dSmrg dst.words[3] = tmp1;
4071debfc3dSmrg }
4081debfc3dSmrg #else
4091debfc3dSmrg {
4101debfc3dSmrg halffractype tmp = dst.words[0];
4111debfc3dSmrg dst.words[0] = dst.words[1];
4121debfc3dSmrg dst.words[1] = tmp;
4131debfc3dSmrg }
4141debfc3dSmrg #endif
4151debfc3dSmrg #endif
4161debfc3dSmrg
4171debfc3dSmrg return dst.value;
4181debfc3dSmrg }
4191debfc3dSmrg #endif
4201debfc3dSmrg
4211debfc3dSmrg #if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
4221debfc3dSmrg void
4231debfc3dSmrg unpack_d (FLO_union_type * src, fp_number_type * dst)
4241debfc3dSmrg {
4251debfc3dSmrg /* We previously used bitfields to store the number, but this doesn't
4261debfc3dSmrg handle little/big endian systems conveniently, so use shifts and
4271debfc3dSmrg masks */
4281debfc3dSmrg fractype fraction;
4291debfc3dSmrg int exp;
4301debfc3dSmrg int sign;
4311debfc3dSmrg
4321debfc3dSmrg #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
4331debfc3dSmrg FLO_union_type swapped;
4341debfc3dSmrg
4351debfc3dSmrg #ifdef TFLOAT
4361debfc3dSmrg swapped.words[0] = src->words[3];
4371debfc3dSmrg swapped.words[1] = src->words[2];
4381debfc3dSmrg swapped.words[2] = src->words[1];
4391debfc3dSmrg swapped.words[3] = src->words[0];
4401debfc3dSmrg #else
4411debfc3dSmrg swapped.words[0] = src->words[1];
4421debfc3dSmrg swapped.words[1] = src->words[0];
4431debfc3dSmrg #endif
4441debfc3dSmrg src = &swapped;
4451debfc3dSmrg #endif
4461debfc3dSmrg
4471debfc3dSmrg #if defined TFLOAT && defined HALFFRACBITS
4481debfc3dSmrg {
4491debfc3dSmrg halffractype high, low;
4501debfc3dSmrg
4511debfc3dSmrg high = src->value_raw >> HALFSHIFT;
4521debfc3dSmrg low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
4531debfc3dSmrg
4541debfc3dSmrg fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
4551debfc3dSmrg fraction <<= FRACBITS - HALFFRACBITS;
4561debfc3dSmrg exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
4571debfc3dSmrg sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
4581debfc3dSmrg
4591debfc3dSmrg if (exp != EXPMAX && exp != 0 && low != 0)
4601debfc3dSmrg {
4611debfc3dSmrg int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
4621debfc3dSmrg int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
4631debfc3dSmrg int shift;
4641debfc3dSmrg fractype xlow;
4651debfc3dSmrg
4661debfc3dSmrg xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
4671debfc3dSmrg if (lowexp)
4681debfc3dSmrg xlow |= (((halffractype)1) << HALFFRACBITS);
4691debfc3dSmrg else
4701debfc3dSmrg lowexp = 1;
4711debfc3dSmrg shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
4721debfc3dSmrg if (shift > 0)
4731debfc3dSmrg xlow <<= shift;
4741debfc3dSmrg else if (shift < 0)
4751debfc3dSmrg xlow >>= -shift;
4761debfc3dSmrg if (sign == lowsign)
4771debfc3dSmrg fraction += xlow;
4781debfc3dSmrg else if (fraction >= xlow)
4791debfc3dSmrg fraction -= xlow;
4801debfc3dSmrg else
4811debfc3dSmrg {
4821debfc3dSmrg /* The high part is a power of two but the full number is lower.
4831debfc3dSmrg This code will leave the implicit 1 in FRACTION, but we'd
4841debfc3dSmrg have added that below anyway. */
4851debfc3dSmrg fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
4861debfc3dSmrg exp--;
4871debfc3dSmrg }
4881debfc3dSmrg }
4891debfc3dSmrg }
4901debfc3dSmrg #else
4911debfc3dSmrg fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
4921debfc3dSmrg exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
4931debfc3dSmrg sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
4941debfc3dSmrg #endif
4951debfc3dSmrg
4961debfc3dSmrg dst->sign = sign;
4971debfc3dSmrg if (exp == 0)
4981debfc3dSmrg {
4991debfc3dSmrg /* Hmm. Looks like 0 */
5001debfc3dSmrg if (fraction == 0
5011debfc3dSmrg #ifdef NO_DENORMALS
5021debfc3dSmrg || 1
5031debfc3dSmrg #endif
5041debfc3dSmrg )
5051debfc3dSmrg {
5061debfc3dSmrg /* tastes like zero */
5071debfc3dSmrg dst->class = CLASS_ZERO;
5081debfc3dSmrg }
5091debfc3dSmrg else
5101debfc3dSmrg {
5111debfc3dSmrg /* Zero exponent with nonzero fraction - it's denormalized,
5121debfc3dSmrg so there isn't a leading implicit one - we'll shift it so
5131debfc3dSmrg it gets one. */
5141debfc3dSmrg dst->normal_exp = exp - EXPBIAS + 1;
5151debfc3dSmrg fraction <<= NGARDS;
5161debfc3dSmrg
5171debfc3dSmrg dst->class = CLASS_NUMBER;
5181debfc3dSmrg #if 1
5191debfc3dSmrg while (fraction < IMPLICIT_1)
5201debfc3dSmrg {
5211debfc3dSmrg fraction <<= 1;
5221debfc3dSmrg dst->normal_exp--;
5231debfc3dSmrg }
5241debfc3dSmrg #endif
5251debfc3dSmrg dst->fraction.ll = fraction;
5261debfc3dSmrg }
5271debfc3dSmrg }
5281debfc3dSmrg else if (__builtin_expect (exp == EXPMAX, 0))
5291debfc3dSmrg {
5301debfc3dSmrg /* Huge exponent*/
5311debfc3dSmrg if (fraction == 0)
5321debfc3dSmrg {
5331debfc3dSmrg /* Attached to a zero fraction - means infinity */
5341debfc3dSmrg dst->class = CLASS_INFINITY;
5351debfc3dSmrg }
5361debfc3dSmrg else
5371debfc3dSmrg {
5381debfc3dSmrg /* Nonzero fraction, means nan */
5391debfc3dSmrg #ifdef QUIET_NAN_NEGATED
5401debfc3dSmrg if ((fraction & QUIET_NAN) == 0)
5411debfc3dSmrg #else
5421debfc3dSmrg if (fraction & QUIET_NAN)
5431debfc3dSmrg #endif
5441debfc3dSmrg {
5451debfc3dSmrg dst->class = CLASS_QNAN;
5461debfc3dSmrg }
5471debfc3dSmrg else
5481debfc3dSmrg {
5491debfc3dSmrg dst->class = CLASS_SNAN;
5501debfc3dSmrg }
5511debfc3dSmrg /* Now that we know which kind of NaN we got, discard the
5521debfc3dSmrg quiet/signaling bit, but do preserve the NaN payload. */
5531debfc3dSmrg fraction &= ~QUIET_NAN;
5541debfc3dSmrg dst->fraction.ll = fraction << NGARDS;
5551debfc3dSmrg }
5561debfc3dSmrg }
5571debfc3dSmrg else
5581debfc3dSmrg {
5591debfc3dSmrg /* Nothing strange about this number */
5601debfc3dSmrg dst->normal_exp = exp - EXPBIAS;
5611debfc3dSmrg dst->class = CLASS_NUMBER;
5621debfc3dSmrg dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
5631debfc3dSmrg }
5641debfc3dSmrg }
5651debfc3dSmrg #endif /* L_unpack_df || L_unpack_sf */
5661debfc3dSmrg
5671debfc3dSmrg #if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
5681debfc3dSmrg static const fp_number_type *
5691debfc3dSmrg _fpadd_parts (fp_number_type * a,
5701debfc3dSmrg fp_number_type * b,
5711debfc3dSmrg fp_number_type * tmp)
5721debfc3dSmrg {
5731debfc3dSmrg intfrac tfraction;
5741debfc3dSmrg
5751debfc3dSmrg /* Put commonly used fields in local variables. */
5761debfc3dSmrg int a_normal_exp;
5771debfc3dSmrg int b_normal_exp;
5781debfc3dSmrg fractype a_fraction;
5791debfc3dSmrg fractype b_fraction;
5801debfc3dSmrg
5811debfc3dSmrg if (isnan (a))
5821debfc3dSmrg {
5831debfc3dSmrg return a;
5841debfc3dSmrg }
5851debfc3dSmrg if (isnan (b))
5861debfc3dSmrg {
5871debfc3dSmrg return b;
5881debfc3dSmrg }
5891debfc3dSmrg if (isinf (a))
5901debfc3dSmrg {
5911debfc3dSmrg /* Adding infinities with opposite signs yields a NaN. */
5921debfc3dSmrg if (isinf (b) && a->sign != b->sign)
5931debfc3dSmrg return makenan ();
5941debfc3dSmrg return a;
5951debfc3dSmrg }
5961debfc3dSmrg if (isinf (b))
5971debfc3dSmrg {
5981debfc3dSmrg return b;
5991debfc3dSmrg }
6001debfc3dSmrg if (iszero (b))
6011debfc3dSmrg {
6021debfc3dSmrg if (iszero (a))
6031debfc3dSmrg {
6041debfc3dSmrg *tmp = *a;
6051debfc3dSmrg tmp->sign = a->sign & b->sign;
6061debfc3dSmrg return tmp;
6071debfc3dSmrg }
6081debfc3dSmrg return a;
6091debfc3dSmrg }
6101debfc3dSmrg if (iszero (a))
6111debfc3dSmrg {
6121debfc3dSmrg return b;
6131debfc3dSmrg }
6141debfc3dSmrg
6151debfc3dSmrg /* Got two numbers. shift the smaller and increment the exponent till
6161debfc3dSmrg they're the same */
6171debfc3dSmrg {
6181debfc3dSmrg int diff;
6191debfc3dSmrg int sdiff;
6201debfc3dSmrg
6211debfc3dSmrg a_normal_exp = a->normal_exp;
6221debfc3dSmrg b_normal_exp = b->normal_exp;
6231debfc3dSmrg a_fraction = a->fraction.ll;
6241debfc3dSmrg b_fraction = b->fraction.ll;
6251debfc3dSmrg
6261debfc3dSmrg diff = a_normal_exp - b_normal_exp;
6271debfc3dSmrg sdiff = diff;
6281debfc3dSmrg
6291debfc3dSmrg if (diff < 0)
6301debfc3dSmrg diff = -diff;
6311debfc3dSmrg if (diff < FRAC_NBITS)
6321debfc3dSmrg {
6331debfc3dSmrg if (sdiff > 0)
6341debfc3dSmrg {
6351debfc3dSmrg b_normal_exp += diff;
6361debfc3dSmrg LSHIFT (b_fraction, diff);
6371debfc3dSmrg }
6381debfc3dSmrg else if (sdiff < 0)
6391debfc3dSmrg {
6401debfc3dSmrg a_normal_exp += diff;
6411debfc3dSmrg LSHIFT (a_fraction, diff);
6421debfc3dSmrg }
6431debfc3dSmrg }
6441debfc3dSmrg else
6451debfc3dSmrg {
6461debfc3dSmrg /* Somethings's up.. choose the biggest */
6471debfc3dSmrg if (a_normal_exp > b_normal_exp)
6481debfc3dSmrg {
6491debfc3dSmrg b_normal_exp = a_normal_exp;
6501debfc3dSmrg b_fraction = 0;
6511debfc3dSmrg }
6521debfc3dSmrg else
6531debfc3dSmrg {
6541debfc3dSmrg a_normal_exp = b_normal_exp;
6551debfc3dSmrg a_fraction = 0;
6561debfc3dSmrg }
6571debfc3dSmrg }
6581debfc3dSmrg }
6591debfc3dSmrg
6601debfc3dSmrg if (a->sign != b->sign)
6611debfc3dSmrg {
6621debfc3dSmrg if (a->sign)
6631debfc3dSmrg {
6641debfc3dSmrg tfraction = -a_fraction + b_fraction;
6651debfc3dSmrg }
6661debfc3dSmrg else
6671debfc3dSmrg {
6681debfc3dSmrg tfraction = a_fraction - b_fraction;
6691debfc3dSmrg }
6701debfc3dSmrg if (tfraction >= 0)
6711debfc3dSmrg {
6721debfc3dSmrg tmp->sign = 0;
6731debfc3dSmrg tmp->normal_exp = a_normal_exp;
6741debfc3dSmrg tmp->fraction.ll = tfraction;
6751debfc3dSmrg }
6761debfc3dSmrg else
6771debfc3dSmrg {
6781debfc3dSmrg tmp->sign = 1;
6791debfc3dSmrg tmp->normal_exp = a_normal_exp;
6801debfc3dSmrg tmp->fraction.ll = -tfraction;
6811debfc3dSmrg }
6821debfc3dSmrg /* and renormalize it */
6831debfc3dSmrg
6841debfc3dSmrg while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
6851debfc3dSmrg {
6861debfc3dSmrg tmp->fraction.ll <<= 1;
6871debfc3dSmrg tmp->normal_exp--;
6881debfc3dSmrg }
6891debfc3dSmrg }
6901debfc3dSmrg else
6911debfc3dSmrg {
6921debfc3dSmrg tmp->sign = a->sign;
6931debfc3dSmrg tmp->normal_exp = a_normal_exp;
6941debfc3dSmrg tmp->fraction.ll = a_fraction + b_fraction;
6951debfc3dSmrg }
6961debfc3dSmrg tmp->class = CLASS_NUMBER;
6971debfc3dSmrg /* Now the fraction is added, we have to shift down to renormalize the
6981debfc3dSmrg number */
6991debfc3dSmrg
7001debfc3dSmrg if (tmp->fraction.ll >= IMPLICIT_2)
7011debfc3dSmrg {
7021debfc3dSmrg LSHIFT (tmp->fraction.ll, 1);
7031debfc3dSmrg tmp->normal_exp++;
7041debfc3dSmrg }
7051debfc3dSmrg return tmp;
7061debfc3dSmrg }
7071debfc3dSmrg
7081debfc3dSmrg FLO_type
7091debfc3dSmrg add (FLO_type arg_a, FLO_type arg_b)
7101debfc3dSmrg {
7111debfc3dSmrg fp_number_type a;
7121debfc3dSmrg fp_number_type b;
7131debfc3dSmrg fp_number_type tmp;
7141debfc3dSmrg const fp_number_type *res;
7151debfc3dSmrg FLO_union_type au, bu;
7161debfc3dSmrg
7171debfc3dSmrg au.value = arg_a;
7181debfc3dSmrg bu.value = arg_b;
7191debfc3dSmrg
7201debfc3dSmrg unpack_d (&au, &a);
7211debfc3dSmrg unpack_d (&bu, &b);
7221debfc3dSmrg
7231debfc3dSmrg res = _fpadd_parts (&a, &b, &tmp);
7241debfc3dSmrg
7251debfc3dSmrg return pack_d (res);
7261debfc3dSmrg }
7271debfc3dSmrg
7281debfc3dSmrg FLO_type
7291debfc3dSmrg sub (FLO_type arg_a, FLO_type arg_b)
7301debfc3dSmrg {
7311debfc3dSmrg fp_number_type a;
7321debfc3dSmrg fp_number_type b;
7331debfc3dSmrg fp_number_type tmp;
7341debfc3dSmrg const fp_number_type *res;
7351debfc3dSmrg FLO_union_type au, bu;
7361debfc3dSmrg
7371debfc3dSmrg au.value = arg_a;
7381debfc3dSmrg bu.value = arg_b;
7391debfc3dSmrg
7401debfc3dSmrg unpack_d (&au, &a);
7411debfc3dSmrg unpack_d (&bu, &b);
7421debfc3dSmrg
7431debfc3dSmrg b.sign ^= 1;
7441debfc3dSmrg
7451debfc3dSmrg res = _fpadd_parts (&a, &b, &tmp);
7461debfc3dSmrg
7471debfc3dSmrg return pack_d (res);
7481debfc3dSmrg }
7491debfc3dSmrg #endif /* L_addsub_sf || L_addsub_df */
7501debfc3dSmrg
7511debfc3dSmrg #if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
7521debfc3dSmrg static inline __attribute__ ((__always_inline__)) const fp_number_type *
7531debfc3dSmrg _fpmul_parts ( fp_number_type * a,
7541debfc3dSmrg fp_number_type * b,
7551debfc3dSmrg fp_number_type * tmp)
7561debfc3dSmrg {
7571debfc3dSmrg fractype low = 0;
7581debfc3dSmrg fractype high = 0;
7591debfc3dSmrg
7601debfc3dSmrg if (isnan (a))
7611debfc3dSmrg {
7621debfc3dSmrg a->sign = a->sign != b->sign;
7631debfc3dSmrg return a;
7641debfc3dSmrg }
7651debfc3dSmrg if (isnan (b))
7661debfc3dSmrg {
7671debfc3dSmrg b->sign = a->sign != b->sign;
7681debfc3dSmrg return b;
7691debfc3dSmrg }
7701debfc3dSmrg if (isinf (a))
7711debfc3dSmrg {
7721debfc3dSmrg if (iszero (b))
7731debfc3dSmrg return makenan ();
7741debfc3dSmrg a->sign = a->sign != b->sign;
7751debfc3dSmrg return a;
7761debfc3dSmrg }
7771debfc3dSmrg if (isinf (b))
7781debfc3dSmrg {
7791debfc3dSmrg if (iszero (a))
7801debfc3dSmrg {
7811debfc3dSmrg return makenan ();
7821debfc3dSmrg }
7831debfc3dSmrg b->sign = a->sign != b->sign;
7841debfc3dSmrg return b;
7851debfc3dSmrg }
7861debfc3dSmrg if (iszero (a))
7871debfc3dSmrg {
7881debfc3dSmrg a->sign = a->sign != b->sign;
7891debfc3dSmrg return a;
7901debfc3dSmrg }
7911debfc3dSmrg if (iszero (b))
7921debfc3dSmrg {
7931debfc3dSmrg b->sign = a->sign != b->sign;
7941debfc3dSmrg return b;
7951debfc3dSmrg }
7961debfc3dSmrg
7971debfc3dSmrg /* Calculate the mantissa by multiplying both numbers to get a
7981debfc3dSmrg twice-as-wide number. */
7991debfc3dSmrg {
8001debfc3dSmrg #if defined(NO_DI_MODE) || defined(TFLOAT)
8011debfc3dSmrg {
8021debfc3dSmrg fractype x = a->fraction.ll;
8031debfc3dSmrg fractype ylow = b->fraction.ll;
8041debfc3dSmrg fractype yhigh = 0;
8051debfc3dSmrg int bit;
8061debfc3dSmrg
8071debfc3dSmrg /* ??? This does multiplies one bit at a time. Optimize. */
8081debfc3dSmrg for (bit = 0; bit < FRAC_NBITS; bit++)
8091debfc3dSmrg {
8101debfc3dSmrg int carry;
8111debfc3dSmrg
8121debfc3dSmrg if (x & 1)
8131debfc3dSmrg {
8141debfc3dSmrg carry = (low += ylow) < ylow;
8151debfc3dSmrg high += yhigh + carry;
8161debfc3dSmrg }
8171debfc3dSmrg yhigh <<= 1;
8181debfc3dSmrg if (ylow & FRACHIGH)
8191debfc3dSmrg {
8201debfc3dSmrg yhigh |= 1;
8211debfc3dSmrg }
8221debfc3dSmrg ylow <<= 1;
8231debfc3dSmrg x >>= 1;
8241debfc3dSmrg }
8251debfc3dSmrg }
8261debfc3dSmrg #elif defined(FLOAT)
8271debfc3dSmrg /* Multiplying two USIs to get a UDI, we're safe. */
8281debfc3dSmrg {
8291debfc3dSmrg UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
8301debfc3dSmrg
8311debfc3dSmrg high = answer >> BITS_PER_SI;
8321debfc3dSmrg low = answer;
8331debfc3dSmrg }
8341debfc3dSmrg #else
8351debfc3dSmrg /* fractype is DImode, but we need the result to be twice as wide.
8361debfc3dSmrg Assuming a widening multiply from DImode to TImode is not
8371debfc3dSmrg available, build one by hand. */
8381debfc3dSmrg {
8391debfc3dSmrg USItype nl = a->fraction.ll;
8401debfc3dSmrg USItype nh = a->fraction.ll >> BITS_PER_SI;
8411debfc3dSmrg USItype ml = b->fraction.ll;
8421debfc3dSmrg USItype mh = b->fraction.ll >> BITS_PER_SI;
8431debfc3dSmrg UDItype pp_ll = (UDItype) ml * nl;
8441debfc3dSmrg UDItype pp_hl = (UDItype) mh * nl;
8451debfc3dSmrg UDItype pp_lh = (UDItype) ml * nh;
8461debfc3dSmrg UDItype pp_hh = (UDItype) mh * nh;
8471debfc3dSmrg UDItype res2 = 0;
8481debfc3dSmrg UDItype res0 = 0;
8491debfc3dSmrg UDItype ps_hh__ = pp_hl + pp_lh;
8501debfc3dSmrg if (ps_hh__ < pp_hl)
8511debfc3dSmrg res2 += (UDItype)1 << BITS_PER_SI;
8521debfc3dSmrg pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
8531debfc3dSmrg res0 = pp_ll + pp_hl;
8541debfc3dSmrg if (res0 < pp_ll)
8551debfc3dSmrg res2++;
8561debfc3dSmrg res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
8571debfc3dSmrg high = res2;
8581debfc3dSmrg low = res0;
8591debfc3dSmrg }
8601debfc3dSmrg #endif
8611debfc3dSmrg }
8621debfc3dSmrg
8631debfc3dSmrg tmp->normal_exp = a->normal_exp + b->normal_exp
8641debfc3dSmrg + FRAC_NBITS - (FRACBITS + NGARDS);
8651debfc3dSmrg tmp->sign = a->sign != b->sign;
8661debfc3dSmrg while (high >= IMPLICIT_2)
8671debfc3dSmrg {
8681debfc3dSmrg tmp->normal_exp++;
8691debfc3dSmrg if (high & 1)
8701debfc3dSmrg {
8711debfc3dSmrg low >>= 1;
8721debfc3dSmrg low |= FRACHIGH;
8731debfc3dSmrg }
8741debfc3dSmrg high >>= 1;
8751debfc3dSmrg }
8761debfc3dSmrg while (high < IMPLICIT_1)
8771debfc3dSmrg {
8781debfc3dSmrg tmp->normal_exp--;
8791debfc3dSmrg
8801debfc3dSmrg high <<= 1;
8811debfc3dSmrg if (low & FRACHIGH)
8821debfc3dSmrg high |= 1;
8831debfc3dSmrg low <<= 1;
8841debfc3dSmrg }
8851debfc3dSmrg
8861debfc3dSmrg if ((high & GARDMASK) == GARDMSB)
8871debfc3dSmrg {
8881debfc3dSmrg if (high & (1 << NGARDS))
8891debfc3dSmrg {
8901debfc3dSmrg /* Because we're half way, we would round to even by adding
8911debfc3dSmrg GARDROUND + 1, except that's also done in the packing
8921debfc3dSmrg function, and rounding twice will lose precision and cause
8931debfc3dSmrg the result to be too far off. Example: 32-bit floats with
8941debfc3dSmrg bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp
8951debfc3dSmrg off), not 0x1000 (more than 0.5ulp off). */
8961debfc3dSmrg }
8971debfc3dSmrg else if (low)
8981debfc3dSmrg {
8991debfc3dSmrg /* We're a further than half way by a small amount corresponding
9001debfc3dSmrg to the bits set in "low". Knowing that, we round here and
9011debfc3dSmrg not in pack_d, because there we don't have "low" available
9021debfc3dSmrg anymore. */
9031debfc3dSmrg high += GARDROUND + 1;
9041debfc3dSmrg
9051debfc3dSmrg /* Avoid further rounding in pack_d. */
9061debfc3dSmrg high &= ~(fractype) GARDMASK;
9071debfc3dSmrg }
9081debfc3dSmrg }
9091debfc3dSmrg tmp->fraction.ll = high;
9101debfc3dSmrg tmp->class = CLASS_NUMBER;
9111debfc3dSmrg return tmp;
9121debfc3dSmrg }
9131debfc3dSmrg
9141debfc3dSmrg FLO_type
9151debfc3dSmrg multiply (FLO_type arg_a, FLO_type arg_b)
9161debfc3dSmrg {
9171debfc3dSmrg fp_number_type a;
9181debfc3dSmrg fp_number_type b;
9191debfc3dSmrg fp_number_type tmp;
9201debfc3dSmrg const fp_number_type *res;
9211debfc3dSmrg FLO_union_type au, bu;
9221debfc3dSmrg
9231debfc3dSmrg au.value = arg_a;
9241debfc3dSmrg bu.value = arg_b;
9251debfc3dSmrg
9261debfc3dSmrg unpack_d (&au, &a);
9271debfc3dSmrg unpack_d (&bu, &b);
9281debfc3dSmrg
9291debfc3dSmrg res = _fpmul_parts (&a, &b, &tmp);
9301debfc3dSmrg
9311debfc3dSmrg return pack_d (res);
9321debfc3dSmrg }
9331debfc3dSmrg #endif /* L_mul_sf || L_mul_df || L_mul_tf */
9341debfc3dSmrg
9351debfc3dSmrg #if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
9361debfc3dSmrg static inline __attribute__ ((__always_inline__)) const fp_number_type *
9371debfc3dSmrg _fpdiv_parts (fp_number_type * a,
9381debfc3dSmrg fp_number_type * b)
9391debfc3dSmrg {
9401debfc3dSmrg fractype bit;
9411debfc3dSmrg fractype numerator;
9421debfc3dSmrg fractype denominator;
9431debfc3dSmrg fractype quotient;
9441debfc3dSmrg
9451debfc3dSmrg if (isnan (a))
9461debfc3dSmrg {
9471debfc3dSmrg return a;
9481debfc3dSmrg }
9491debfc3dSmrg if (isnan (b))
9501debfc3dSmrg {
9511debfc3dSmrg return b;
9521debfc3dSmrg }
9531debfc3dSmrg
9541debfc3dSmrg a->sign = a->sign ^ b->sign;
9551debfc3dSmrg
9561debfc3dSmrg if (isinf (a) || iszero (a))
9571debfc3dSmrg {
9581debfc3dSmrg if (a->class == b->class)
9591debfc3dSmrg return makenan ();
9601debfc3dSmrg return a;
9611debfc3dSmrg }
9621debfc3dSmrg
9631debfc3dSmrg if (isinf (b))
9641debfc3dSmrg {
9651debfc3dSmrg a->fraction.ll = 0;
9661debfc3dSmrg a->normal_exp = 0;
9671debfc3dSmrg return a;
9681debfc3dSmrg }
9691debfc3dSmrg if (iszero (b))
9701debfc3dSmrg {
9711debfc3dSmrg a->class = CLASS_INFINITY;
9721debfc3dSmrg return a;
9731debfc3dSmrg }
9741debfc3dSmrg
9751debfc3dSmrg /* Calculate the mantissa by multiplying both 64bit numbers to get a
9761debfc3dSmrg 128 bit number */
9771debfc3dSmrg {
9781debfc3dSmrg /* quotient =
9791debfc3dSmrg ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
9801debfc3dSmrg */
9811debfc3dSmrg
9821debfc3dSmrg a->normal_exp = a->normal_exp - b->normal_exp;
9831debfc3dSmrg numerator = a->fraction.ll;
9841debfc3dSmrg denominator = b->fraction.ll;
9851debfc3dSmrg
9861debfc3dSmrg if (numerator < denominator)
9871debfc3dSmrg {
9881debfc3dSmrg /* Fraction will be less than 1.0 */
9891debfc3dSmrg numerator *= 2;
9901debfc3dSmrg a->normal_exp--;
9911debfc3dSmrg }
9921debfc3dSmrg bit = IMPLICIT_1;
9931debfc3dSmrg quotient = 0;
9941debfc3dSmrg /* ??? Does divide one bit at a time. Optimize. */
9951debfc3dSmrg while (bit)
9961debfc3dSmrg {
9971debfc3dSmrg if (numerator >= denominator)
9981debfc3dSmrg {
9991debfc3dSmrg quotient |= bit;
10001debfc3dSmrg numerator -= denominator;
10011debfc3dSmrg }
10021debfc3dSmrg bit >>= 1;
10031debfc3dSmrg numerator *= 2;
10041debfc3dSmrg }
10051debfc3dSmrg
10061debfc3dSmrg if ((quotient & GARDMASK) == GARDMSB)
10071debfc3dSmrg {
10081debfc3dSmrg if (quotient & (1 << NGARDS))
10091debfc3dSmrg {
10101debfc3dSmrg /* Because we're half way, we would round to even by adding
10111debfc3dSmrg GARDROUND + 1, except that's also done in the packing
10121debfc3dSmrg function, and rounding twice will lose precision and cause
10131debfc3dSmrg the result to be too far off. */
10141debfc3dSmrg }
10151debfc3dSmrg else if (numerator)
10161debfc3dSmrg {
10171debfc3dSmrg /* We're a further than half way by the small amount
10181debfc3dSmrg corresponding to the bits set in "numerator". Knowing
10191debfc3dSmrg that, we round here and not in pack_d, because there we
10201debfc3dSmrg don't have "numerator" available anymore. */
10211debfc3dSmrg quotient += GARDROUND + 1;
10221debfc3dSmrg
10231debfc3dSmrg /* Avoid further rounding in pack_d. */
10241debfc3dSmrg quotient &= ~(fractype) GARDMASK;
10251debfc3dSmrg }
10261debfc3dSmrg }
10271debfc3dSmrg
10281debfc3dSmrg a->fraction.ll = quotient;
10291debfc3dSmrg return (a);
10301debfc3dSmrg }
10311debfc3dSmrg }
10321debfc3dSmrg
10331debfc3dSmrg FLO_type
10341debfc3dSmrg divide (FLO_type arg_a, FLO_type arg_b)
10351debfc3dSmrg {
10361debfc3dSmrg fp_number_type a;
10371debfc3dSmrg fp_number_type b;
10381debfc3dSmrg const fp_number_type *res;
10391debfc3dSmrg FLO_union_type au, bu;
10401debfc3dSmrg
10411debfc3dSmrg au.value = arg_a;
10421debfc3dSmrg bu.value = arg_b;
10431debfc3dSmrg
10441debfc3dSmrg unpack_d (&au, &a);
10451debfc3dSmrg unpack_d (&bu, &b);
10461debfc3dSmrg
10471debfc3dSmrg res = _fpdiv_parts (&a, &b);
10481debfc3dSmrg
10491debfc3dSmrg return pack_d (res);
10501debfc3dSmrg }
10511debfc3dSmrg #endif /* L_div_sf || L_div_df */
10521debfc3dSmrg
10531debfc3dSmrg #if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
10541debfc3dSmrg || defined(L_fpcmp_parts_tf)
10551debfc3dSmrg /* according to the demo, fpcmp returns a comparison with 0... thus
10561debfc3dSmrg a<b -> -1
10571debfc3dSmrg a==b -> 0
10581debfc3dSmrg a>b -> +1
10591debfc3dSmrg */
10601debfc3dSmrg
10611debfc3dSmrg int
10621debfc3dSmrg __fpcmp_parts (fp_number_type * a, fp_number_type * b)
10631debfc3dSmrg {
10641debfc3dSmrg #if 0
10651debfc3dSmrg /* either nan -> unordered. Must be checked outside of this routine. */
10661debfc3dSmrg if (isnan (a) && isnan (b))
10671debfc3dSmrg {
10681debfc3dSmrg return 1; /* still unordered! */
10691debfc3dSmrg }
10701debfc3dSmrg #endif
10711debfc3dSmrg
10721debfc3dSmrg if (isnan (a) || isnan (b))
10731debfc3dSmrg {
10741debfc3dSmrg return 1; /* how to indicate unordered compare? */
10751debfc3dSmrg }
10761debfc3dSmrg if (isinf (a) && isinf (b))
10771debfc3dSmrg {
10781debfc3dSmrg /* +inf > -inf, but +inf != +inf */
10791debfc3dSmrg /* b \a| +inf(0)| -inf(1)
10801debfc3dSmrg ______\+--------+--------
10811debfc3dSmrg +inf(0)| a==b(0)| a<b(-1)
10821debfc3dSmrg -------+--------+--------
10831debfc3dSmrg -inf(1)| a>b(1) | a==b(0)
10841debfc3dSmrg -------+--------+--------
10851debfc3dSmrg So since unordered must be nonzero, just line up the columns...
10861debfc3dSmrg */
10871debfc3dSmrg return b->sign - a->sign;
10881debfc3dSmrg }
10891debfc3dSmrg /* but not both... */
10901debfc3dSmrg if (isinf (a))
10911debfc3dSmrg {
10921debfc3dSmrg return a->sign ? -1 : 1;
10931debfc3dSmrg }
10941debfc3dSmrg if (isinf (b))
10951debfc3dSmrg {
10961debfc3dSmrg return b->sign ? 1 : -1;
10971debfc3dSmrg }
10981debfc3dSmrg if (iszero (a) && iszero (b))
10991debfc3dSmrg {
11001debfc3dSmrg return 0;
11011debfc3dSmrg }
11021debfc3dSmrg if (iszero (a))
11031debfc3dSmrg {
11041debfc3dSmrg return b->sign ? 1 : -1;
11051debfc3dSmrg }
11061debfc3dSmrg if (iszero (b))
11071debfc3dSmrg {
11081debfc3dSmrg return a->sign ? -1 : 1;
11091debfc3dSmrg }
11101debfc3dSmrg /* now both are "normal". */
11111debfc3dSmrg if (a->sign != b->sign)
11121debfc3dSmrg {
11131debfc3dSmrg /* opposite signs */
11141debfc3dSmrg return a->sign ? -1 : 1;
11151debfc3dSmrg }
11161debfc3dSmrg /* same sign; exponents? */
11171debfc3dSmrg if (a->normal_exp > b->normal_exp)
11181debfc3dSmrg {
11191debfc3dSmrg return a->sign ? -1 : 1;
11201debfc3dSmrg }
11211debfc3dSmrg if (a->normal_exp < b->normal_exp)
11221debfc3dSmrg {
11231debfc3dSmrg return a->sign ? 1 : -1;
11241debfc3dSmrg }
11251debfc3dSmrg /* same exponents; check size. */
11261debfc3dSmrg if (a->fraction.ll > b->fraction.ll)
11271debfc3dSmrg {
11281debfc3dSmrg return a->sign ? -1 : 1;
11291debfc3dSmrg }
11301debfc3dSmrg if (a->fraction.ll < b->fraction.ll)
11311debfc3dSmrg {
11321debfc3dSmrg return a->sign ? 1 : -1;
11331debfc3dSmrg }
11341debfc3dSmrg /* after all that, they're equal. */
11351debfc3dSmrg return 0;
11361debfc3dSmrg }
11371debfc3dSmrg #endif
11381debfc3dSmrg
11391debfc3dSmrg #if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
11401debfc3dSmrg CMPtype
11411debfc3dSmrg compare (FLO_type arg_a, FLO_type arg_b)
11421debfc3dSmrg {
11431debfc3dSmrg fp_number_type a;
11441debfc3dSmrg fp_number_type b;
11451debfc3dSmrg FLO_union_type au, bu;
11461debfc3dSmrg
11471debfc3dSmrg au.value = arg_a;
11481debfc3dSmrg bu.value = arg_b;
11491debfc3dSmrg
11501debfc3dSmrg unpack_d (&au, &a);
11511debfc3dSmrg unpack_d (&bu, &b);
11521debfc3dSmrg
11531debfc3dSmrg return __fpcmp_parts (&a, &b);
11541debfc3dSmrg }
11551debfc3dSmrg #endif /* L_compare_sf || L_compare_df */
11561debfc3dSmrg
11571debfc3dSmrg /* These should be optimized for their specific tasks someday. */
11581debfc3dSmrg
11591debfc3dSmrg #if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
11601debfc3dSmrg CMPtype
11611debfc3dSmrg _eq_f2 (FLO_type arg_a, FLO_type arg_b)
11621debfc3dSmrg {
11631debfc3dSmrg fp_number_type a;
11641debfc3dSmrg fp_number_type b;
11651debfc3dSmrg FLO_union_type au, bu;
11661debfc3dSmrg
11671debfc3dSmrg au.value = arg_a;
11681debfc3dSmrg bu.value = arg_b;
11691debfc3dSmrg
11701debfc3dSmrg unpack_d (&au, &a);
11711debfc3dSmrg unpack_d (&bu, &b);
11721debfc3dSmrg
11731debfc3dSmrg if (isnan (&a) || isnan (&b))
11741debfc3dSmrg return 1; /* false, truth == 0 */
11751debfc3dSmrg
11761debfc3dSmrg return __fpcmp_parts (&a, &b) ;
11771debfc3dSmrg }
11781debfc3dSmrg #endif /* L_eq_sf || L_eq_df */
11791debfc3dSmrg
11801debfc3dSmrg #if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
11811debfc3dSmrg CMPtype
11821debfc3dSmrg _ne_f2 (FLO_type arg_a, FLO_type arg_b)
11831debfc3dSmrg {
11841debfc3dSmrg fp_number_type a;
11851debfc3dSmrg fp_number_type b;
11861debfc3dSmrg FLO_union_type au, bu;
11871debfc3dSmrg
11881debfc3dSmrg au.value = arg_a;
11891debfc3dSmrg bu.value = arg_b;
11901debfc3dSmrg
11911debfc3dSmrg unpack_d (&au, &a);
11921debfc3dSmrg unpack_d (&bu, &b);
11931debfc3dSmrg
11941debfc3dSmrg if (isnan (&a) || isnan (&b))
11951debfc3dSmrg return 1; /* true, truth != 0 */
11961debfc3dSmrg
11971debfc3dSmrg return __fpcmp_parts (&a, &b) ;
11981debfc3dSmrg }
11991debfc3dSmrg #endif /* L_ne_sf || L_ne_df */
12001debfc3dSmrg
12011debfc3dSmrg #if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
12021debfc3dSmrg CMPtype
12031debfc3dSmrg _gt_f2 (FLO_type arg_a, FLO_type arg_b)
12041debfc3dSmrg {
12051debfc3dSmrg fp_number_type a;
12061debfc3dSmrg fp_number_type b;
12071debfc3dSmrg FLO_union_type au, bu;
12081debfc3dSmrg
12091debfc3dSmrg au.value = arg_a;
12101debfc3dSmrg bu.value = arg_b;
12111debfc3dSmrg
12121debfc3dSmrg unpack_d (&au, &a);
12131debfc3dSmrg unpack_d (&bu, &b);
12141debfc3dSmrg
12151debfc3dSmrg if (isnan (&a) || isnan (&b))
12161debfc3dSmrg return -1; /* false, truth > 0 */
12171debfc3dSmrg
12181debfc3dSmrg return __fpcmp_parts (&a, &b);
12191debfc3dSmrg }
12201debfc3dSmrg #endif /* L_gt_sf || L_gt_df */
12211debfc3dSmrg
12221debfc3dSmrg #if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
12231debfc3dSmrg CMPtype
12241debfc3dSmrg _ge_f2 (FLO_type arg_a, FLO_type arg_b)
12251debfc3dSmrg {
12261debfc3dSmrg fp_number_type a;
12271debfc3dSmrg fp_number_type b;
12281debfc3dSmrg FLO_union_type au, bu;
12291debfc3dSmrg
12301debfc3dSmrg au.value = arg_a;
12311debfc3dSmrg bu.value = arg_b;
12321debfc3dSmrg
12331debfc3dSmrg unpack_d (&au, &a);
12341debfc3dSmrg unpack_d (&bu, &b);
12351debfc3dSmrg
12361debfc3dSmrg if (isnan (&a) || isnan (&b))
12371debfc3dSmrg return -1; /* false, truth >= 0 */
12381debfc3dSmrg return __fpcmp_parts (&a, &b) ;
12391debfc3dSmrg }
12401debfc3dSmrg #endif /* L_ge_sf || L_ge_df */
12411debfc3dSmrg
12421debfc3dSmrg #if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
12431debfc3dSmrg CMPtype
12441debfc3dSmrg _lt_f2 (FLO_type arg_a, FLO_type arg_b)
12451debfc3dSmrg {
12461debfc3dSmrg fp_number_type a;
12471debfc3dSmrg fp_number_type b;
12481debfc3dSmrg FLO_union_type au, bu;
12491debfc3dSmrg
12501debfc3dSmrg au.value = arg_a;
12511debfc3dSmrg bu.value = arg_b;
12521debfc3dSmrg
12531debfc3dSmrg unpack_d (&au, &a);
12541debfc3dSmrg unpack_d (&bu, &b);
12551debfc3dSmrg
12561debfc3dSmrg if (isnan (&a) || isnan (&b))
12571debfc3dSmrg return 1; /* false, truth < 0 */
12581debfc3dSmrg
12591debfc3dSmrg return __fpcmp_parts (&a, &b);
12601debfc3dSmrg }
12611debfc3dSmrg #endif /* L_lt_sf || L_lt_df */
12621debfc3dSmrg
12631debfc3dSmrg #if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
12641debfc3dSmrg CMPtype
12651debfc3dSmrg _le_f2 (FLO_type arg_a, FLO_type arg_b)
12661debfc3dSmrg {
12671debfc3dSmrg fp_number_type a;
12681debfc3dSmrg fp_number_type b;
12691debfc3dSmrg FLO_union_type au, bu;
12701debfc3dSmrg
12711debfc3dSmrg au.value = arg_a;
12721debfc3dSmrg bu.value = arg_b;
12731debfc3dSmrg
12741debfc3dSmrg unpack_d (&au, &a);
12751debfc3dSmrg unpack_d (&bu, &b);
12761debfc3dSmrg
12771debfc3dSmrg if (isnan (&a) || isnan (&b))
12781debfc3dSmrg return 1; /* false, truth <= 0 */
12791debfc3dSmrg
12801debfc3dSmrg return __fpcmp_parts (&a, &b) ;
12811debfc3dSmrg }
12821debfc3dSmrg #endif /* L_le_sf || L_le_df */
12831debfc3dSmrg
12841debfc3dSmrg #if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
12851debfc3dSmrg CMPtype
12861debfc3dSmrg _unord_f2 (FLO_type arg_a, FLO_type arg_b)
12871debfc3dSmrg {
12881debfc3dSmrg fp_number_type a;
12891debfc3dSmrg fp_number_type b;
12901debfc3dSmrg FLO_union_type au, bu;
12911debfc3dSmrg
12921debfc3dSmrg au.value = arg_a;
12931debfc3dSmrg bu.value = arg_b;
12941debfc3dSmrg
12951debfc3dSmrg unpack_d (&au, &a);
12961debfc3dSmrg unpack_d (&bu, &b);
12971debfc3dSmrg
12981debfc3dSmrg return (isnan (&a) || isnan (&b));
12991debfc3dSmrg }
13001debfc3dSmrg #endif /* L_unord_sf || L_unord_df */
13011debfc3dSmrg
13021debfc3dSmrg #if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
13031debfc3dSmrg FLO_type
13041debfc3dSmrg si_to_float (SItype arg_a)
13051debfc3dSmrg {
13061debfc3dSmrg fp_number_type in;
13071debfc3dSmrg
13081debfc3dSmrg in.class = CLASS_NUMBER;
13091debfc3dSmrg in.sign = arg_a < 0;
13101debfc3dSmrg if (!arg_a)
13111debfc3dSmrg {
13121debfc3dSmrg in.class = CLASS_ZERO;
13131debfc3dSmrg }
13141debfc3dSmrg else
13151debfc3dSmrg {
13161debfc3dSmrg USItype uarg;
13171debfc3dSmrg int shift;
13181debfc3dSmrg in.normal_exp = FRACBITS + NGARDS;
13191debfc3dSmrg if (in.sign)
13201debfc3dSmrg {
13211debfc3dSmrg /* Special case for minint, since there is no +ve integer
13221debfc3dSmrg representation for it */
13231debfc3dSmrg if (arg_a == (- MAX_SI_INT - 1))
13241debfc3dSmrg {
13251debfc3dSmrg return (FLO_type)(- MAX_SI_INT - 1);
13261debfc3dSmrg }
13271debfc3dSmrg uarg = (-arg_a);
13281debfc3dSmrg }
13291debfc3dSmrg else
13301debfc3dSmrg uarg = arg_a;
13311debfc3dSmrg
13321debfc3dSmrg in.fraction.ll = uarg;
13331debfc3dSmrg shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
13341debfc3dSmrg if (shift > 0)
13351debfc3dSmrg {
13361debfc3dSmrg in.fraction.ll <<= shift;
13371debfc3dSmrg in.normal_exp -= shift;
13381debfc3dSmrg }
13391debfc3dSmrg }
13401debfc3dSmrg return pack_d (&in);
13411debfc3dSmrg }
13421debfc3dSmrg #endif /* L_si_to_sf || L_si_to_df */
13431debfc3dSmrg
13441debfc3dSmrg #if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
13451debfc3dSmrg FLO_type
13461debfc3dSmrg usi_to_float (USItype arg_a)
13471debfc3dSmrg {
13481debfc3dSmrg fp_number_type in;
13491debfc3dSmrg
13501debfc3dSmrg in.sign = 0;
13511debfc3dSmrg if (!arg_a)
13521debfc3dSmrg {
13531debfc3dSmrg in.class = CLASS_ZERO;
13541debfc3dSmrg }
13551debfc3dSmrg else
13561debfc3dSmrg {
13571debfc3dSmrg int shift;
13581debfc3dSmrg in.class = CLASS_NUMBER;
13591debfc3dSmrg in.normal_exp = FRACBITS + NGARDS;
13601debfc3dSmrg in.fraction.ll = arg_a;
13611debfc3dSmrg
13621debfc3dSmrg shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
13631debfc3dSmrg if (shift < 0)
13641debfc3dSmrg {
13651debfc3dSmrg fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1);
13661debfc3dSmrg in.fraction.ll >>= -shift;
13671debfc3dSmrg in.fraction.ll |= (guard != 0);
13681debfc3dSmrg in.normal_exp -= shift;
13691debfc3dSmrg }
13701debfc3dSmrg else if (shift > 0)
13711debfc3dSmrg {
13721debfc3dSmrg in.fraction.ll <<= shift;
13731debfc3dSmrg in.normal_exp -= shift;
13741debfc3dSmrg }
13751debfc3dSmrg }
13761debfc3dSmrg return pack_d (&in);
13771debfc3dSmrg }
13781debfc3dSmrg #endif
13791debfc3dSmrg
13801debfc3dSmrg #if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
13811debfc3dSmrg SItype
13821debfc3dSmrg float_to_si (FLO_type arg_a)
13831debfc3dSmrg {
13841debfc3dSmrg fp_number_type a;
13851debfc3dSmrg SItype tmp;
13861debfc3dSmrg FLO_union_type au;
13871debfc3dSmrg
13881debfc3dSmrg au.value = arg_a;
13891debfc3dSmrg unpack_d (&au, &a);
13901debfc3dSmrg
13911debfc3dSmrg if (iszero (&a))
13921debfc3dSmrg return 0;
13931debfc3dSmrg if (isnan (&a))
13941debfc3dSmrg return 0;
13951debfc3dSmrg /* get reasonable MAX_SI_INT... */
13961debfc3dSmrg if (isinf (&a))
13971debfc3dSmrg return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
13981debfc3dSmrg /* it is a number, but a small one */
13991debfc3dSmrg if (a.normal_exp < 0)
14001debfc3dSmrg return 0;
14011debfc3dSmrg if (a.normal_exp > BITS_PER_SI - 2)
14021debfc3dSmrg return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
14031debfc3dSmrg tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
14041debfc3dSmrg return a.sign ? (-tmp) : (tmp);
14051debfc3dSmrg }
14061debfc3dSmrg #endif /* L_sf_to_si || L_df_to_si */
14071debfc3dSmrg
14081debfc3dSmrg #if defined(L_tf_to_usi)
14091debfc3dSmrg USItype
14101debfc3dSmrg float_to_usi (FLO_type arg_a)
14111debfc3dSmrg {
14121debfc3dSmrg fp_number_type a;
14131debfc3dSmrg FLO_union_type au;
14141debfc3dSmrg
14151debfc3dSmrg au.value = arg_a;
14161debfc3dSmrg unpack_d (&au, &a);
14171debfc3dSmrg
14181debfc3dSmrg if (iszero (&a))
14191debfc3dSmrg return 0;
14201debfc3dSmrg if (isnan (&a))
14211debfc3dSmrg return 0;
14221debfc3dSmrg /* it is a negative number */
14231debfc3dSmrg if (a.sign)
14241debfc3dSmrg return 0;
14251debfc3dSmrg /* get reasonable MAX_USI_INT... */
14261debfc3dSmrg if (isinf (&a))
14271debfc3dSmrg return MAX_USI_INT;
14281debfc3dSmrg /* it is a number, but a small one */
14291debfc3dSmrg if (a.normal_exp < 0)
14301debfc3dSmrg return 0;
14311debfc3dSmrg if (a.normal_exp > BITS_PER_SI - 1)
14321debfc3dSmrg return MAX_USI_INT;
14331debfc3dSmrg else if (a.normal_exp > (FRACBITS + NGARDS))
14341debfc3dSmrg return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
14351debfc3dSmrg else
14361debfc3dSmrg return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
14371debfc3dSmrg }
14381debfc3dSmrg #endif /* L_tf_to_usi */
14391debfc3dSmrg
14401debfc3dSmrg #if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
14411debfc3dSmrg FLO_type
14421debfc3dSmrg negate (FLO_type arg_a)
14431debfc3dSmrg {
14441debfc3dSmrg fp_number_type a;
14451debfc3dSmrg FLO_union_type au;
14461debfc3dSmrg
14471debfc3dSmrg au.value = arg_a;
14481debfc3dSmrg unpack_d (&au, &a);
14491debfc3dSmrg
14501debfc3dSmrg flip_sign (&a);
14511debfc3dSmrg return pack_d (&a);
14521debfc3dSmrg }
14531debfc3dSmrg #endif /* L_negate_sf || L_negate_df */
14541debfc3dSmrg
14551debfc3dSmrg #ifdef FLOAT
14561debfc3dSmrg
14571debfc3dSmrg #if defined(L_make_sf)
14581debfc3dSmrg SFtype
14591debfc3dSmrg __make_fp(fp_class_type class,
14601debfc3dSmrg unsigned int sign,
14611debfc3dSmrg int exp,
14621debfc3dSmrg USItype frac)
14631debfc3dSmrg {
14641debfc3dSmrg fp_number_type in;
14651debfc3dSmrg
14661debfc3dSmrg in.class = class;
14671debfc3dSmrg in.sign = sign;
14681debfc3dSmrg in.normal_exp = exp;
14691debfc3dSmrg in.fraction.ll = frac;
14701debfc3dSmrg return pack_d (&in);
14711debfc3dSmrg }
14721debfc3dSmrg #endif /* L_make_sf */
14731debfc3dSmrg
14741debfc3dSmrg #ifndef FLOAT_ONLY
14751debfc3dSmrg
14761debfc3dSmrg /* This enables one to build an fp library that supports float but not double.
14771debfc3dSmrg Otherwise, we would get an undefined reference to __make_dp.
14781debfc3dSmrg This is needed for some 8-bit ports that can't handle well values that
14791debfc3dSmrg are 8-bytes in size, so we just don't support double for them at all. */
14801debfc3dSmrg
14811debfc3dSmrg #if defined(L_sf_to_df)
14821debfc3dSmrg DFtype
14831debfc3dSmrg sf_to_df (SFtype arg_a)
14841debfc3dSmrg {
14851debfc3dSmrg fp_number_type in;
14861debfc3dSmrg FLO_union_type au;
14871debfc3dSmrg
14881debfc3dSmrg au.value = arg_a;
14891debfc3dSmrg unpack_d (&au, &in);
14901debfc3dSmrg
14911debfc3dSmrg return __make_dp (in.class, in.sign, in.normal_exp,
14921debfc3dSmrg ((UDItype) in.fraction.ll) << F_D_BITOFF);
14931debfc3dSmrg }
14941debfc3dSmrg #endif /* L_sf_to_df */
14951debfc3dSmrg
14961debfc3dSmrg #if defined(L_sf_to_tf) && defined(TMODES)
14971debfc3dSmrg TFtype
14981debfc3dSmrg sf_to_tf (SFtype arg_a)
14991debfc3dSmrg {
15001debfc3dSmrg fp_number_type in;
15011debfc3dSmrg FLO_union_type au;
15021debfc3dSmrg
15031debfc3dSmrg au.value = arg_a;
15041debfc3dSmrg unpack_d (&au, &in);
15051debfc3dSmrg
15061debfc3dSmrg return __make_tp (in.class, in.sign, in.normal_exp,
15071debfc3dSmrg ((UTItype) in.fraction.ll) << F_T_BITOFF);
15081debfc3dSmrg }
15091debfc3dSmrg #endif /* L_sf_to_df */
15101debfc3dSmrg
15111debfc3dSmrg #endif /* ! FLOAT_ONLY */
15121debfc3dSmrg #endif /* FLOAT */
15131debfc3dSmrg
15141debfc3dSmrg #ifndef FLOAT
15151debfc3dSmrg
15161debfc3dSmrg extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
15171debfc3dSmrg
15181debfc3dSmrg #if defined(L_make_df)
15191debfc3dSmrg DFtype
15201debfc3dSmrg __make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
15211debfc3dSmrg {
15221debfc3dSmrg fp_number_type in;
15231debfc3dSmrg
15241debfc3dSmrg in.class = class;
15251debfc3dSmrg in.sign = sign;
15261debfc3dSmrg in.normal_exp = exp;
15271debfc3dSmrg in.fraction.ll = frac;
15281debfc3dSmrg return pack_d (&in);
15291debfc3dSmrg }
15301debfc3dSmrg #endif /* L_make_df */
15311debfc3dSmrg
15321debfc3dSmrg #if defined(L_df_to_sf)
15331debfc3dSmrg SFtype
15341debfc3dSmrg df_to_sf (DFtype arg_a)
15351debfc3dSmrg {
15361debfc3dSmrg fp_number_type in;
15371debfc3dSmrg USItype sffrac;
15381debfc3dSmrg FLO_union_type au;
15391debfc3dSmrg
15401debfc3dSmrg au.value = arg_a;
15411debfc3dSmrg unpack_d (&au, &in);
15421debfc3dSmrg
15431debfc3dSmrg sffrac = in.fraction.ll >> F_D_BITOFF;
15441debfc3dSmrg
15451debfc3dSmrg /* We set the lowest guard bit in SFFRAC if we discarded any non
15461debfc3dSmrg zero bits. */
15471debfc3dSmrg if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
15481debfc3dSmrg sffrac |= 1;
15491debfc3dSmrg
15501debfc3dSmrg return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
15511debfc3dSmrg }
15521debfc3dSmrg #endif /* L_df_to_sf */
15531debfc3dSmrg
15541debfc3dSmrg #if defined(L_df_to_tf) && defined(TMODES) \
15551debfc3dSmrg && !defined(FLOAT) && !defined(TFLOAT)
15561debfc3dSmrg TFtype
15571debfc3dSmrg df_to_tf (DFtype arg_a)
15581debfc3dSmrg {
15591debfc3dSmrg fp_number_type in;
15601debfc3dSmrg FLO_union_type au;
15611debfc3dSmrg
15621debfc3dSmrg au.value = arg_a;
15631debfc3dSmrg unpack_d (&au, &in);
15641debfc3dSmrg
15651debfc3dSmrg return __make_tp (in.class, in.sign, in.normal_exp,
15661debfc3dSmrg ((UTItype) in.fraction.ll) << D_T_BITOFF);
15671debfc3dSmrg }
15681debfc3dSmrg #endif /* L_sf_to_df */
15691debfc3dSmrg
15701debfc3dSmrg #ifdef TFLOAT
15711debfc3dSmrg #if defined(L_make_tf)
15721debfc3dSmrg TFtype
15731debfc3dSmrg __make_tp(fp_class_type class,
15741debfc3dSmrg unsigned int sign,
15751debfc3dSmrg int exp,
15761debfc3dSmrg UTItype frac)
15771debfc3dSmrg {
15781debfc3dSmrg fp_number_type in;
15791debfc3dSmrg
15801debfc3dSmrg in.class = class;
15811debfc3dSmrg in.sign = sign;
15821debfc3dSmrg in.normal_exp = exp;
15831debfc3dSmrg in.fraction.ll = frac;
15841debfc3dSmrg return pack_d (&in);
15851debfc3dSmrg }
15861debfc3dSmrg #endif /* L_make_tf */
15871debfc3dSmrg
15881debfc3dSmrg #if defined(L_tf_to_df)
15891debfc3dSmrg DFtype
15901debfc3dSmrg tf_to_df (TFtype arg_a)
15911debfc3dSmrg {
15921debfc3dSmrg fp_number_type in;
15931debfc3dSmrg UDItype sffrac;
15941debfc3dSmrg FLO_union_type au;
15951debfc3dSmrg
15961debfc3dSmrg au.value = arg_a;
15971debfc3dSmrg unpack_d (&au, &in);
15981debfc3dSmrg
15991debfc3dSmrg sffrac = in.fraction.ll >> D_T_BITOFF;
16001debfc3dSmrg
16011debfc3dSmrg /* We set the lowest guard bit in SFFRAC if we discarded any non
16021debfc3dSmrg zero bits. */
16031debfc3dSmrg if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
16041debfc3dSmrg sffrac |= 1;
16051debfc3dSmrg
16061debfc3dSmrg return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
16071debfc3dSmrg }
16081debfc3dSmrg #endif /* L_tf_to_df */
16091debfc3dSmrg
16101debfc3dSmrg #if defined(L_tf_to_sf)
16111debfc3dSmrg SFtype
16121debfc3dSmrg tf_to_sf (TFtype arg_a)
16131debfc3dSmrg {
16141debfc3dSmrg fp_number_type in;
16151debfc3dSmrg USItype sffrac;
16161debfc3dSmrg FLO_union_type au;
16171debfc3dSmrg
16181debfc3dSmrg au.value = arg_a;
16191debfc3dSmrg unpack_d (&au, &in);
16201debfc3dSmrg
16211debfc3dSmrg sffrac = in.fraction.ll >> F_T_BITOFF;
16221debfc3dSmrg
16231debfc3dSmrg /* We set the lowest guard bit in SFFRAC if we discarded any non
16241debfc3dSmrg zero bits. */
16251debfc3dSmrg if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
16261debfc3dSmrg sffrac |= 1;
16271debfc3dSmrg
16281debfc3dSmrg return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
16291debfc3dSmrg }
16301debfc3dSmrg #endif /* L_tf_to_sf */
16311debfc3dSmrg #endif /* TFLOAT */
16321debfc3dSmrg
16331debfc3dSmrg #endif /* ! FLOAT */
16341debfc3dSmrg #endif /* !EXTENDED_FLOAT_STUBS */
1635