190075Sobrien/* This is a software floating point library which can be used
290075Sobrien   for targets without hardware floating point.
3169689Skan   Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003,
4169689Skan   2004, 2005 Free Software Foundation, Inc.
518334Speter
6169689SkanThis file is part of GCC.
718334Speter
8169689SkanGCC is free software; you can redistribute it and/or modify it under
9169689Skanthe terms of the GNU General Public License as published by the Free
10169689SkanSoftware Foundation; either version 2, or (at your option) any later
11169689Skanversion.
12169689Skan
1318334SpeterIn addition to the permissions in the GNU General Public License, the
1418334SpeterFree Software Foundation gives you unlimited permission to link the
15169689Skancompiled version of this file into combinations with other programs,
16169689Skanand to distribute those combinations without any restriction coming
17169689Skanfrom the use of this file.  (The General Public License restrictions
18169689Skando apply in other respects; for example, they cover modification of
19169689Skanthe file, and distribution when not linked into a combine
20169689Skanexecutable.)
2118334Speter
22169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
23169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
24169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25169689Skanfor more details.
2618334Speter
2718334SpeterYou should have received a copy of the GNU General Public License
28169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
29169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
30169689Skan02110-1301, USA.  */
3118334Speter
3218334Speter/* This implements IEEE 754 format arithmetic, but does not provide a
3318334Speter   mechanism for setting the rounding mode, or for generating or handling
3418334Speter   exceptions.
3518334Speter
3618334Speter   The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
3718334Speter   Wilson, all of Cygnus Support.  */
3818334Speter
3918334Speter/* The intended way to use this file is to make two copies, add `#define FLOAT'
4018334Speter   to one copy, then compile both copies and add them to libgcc.a.  */
4118334Speter
4290075Sobrien#include "tconfig.h"
43132718Skan#include "coretypes.h"
44132718Skan#include "tm.h"
45132718Skan#include "config/fp-bit.h"
4650397Sobrien
47117395Skan/* The following macros can be defined to change the behavior of this file:
4818334Speter   FLOAT: Implement a `float', aka SFmode, fp library.  If this is not
4918334Speter     defined, then this file implements a `double', aka DFmode, fp library.
5018334Speter   FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
5118334Speter     don't include float->double conversion which requires the double library.
5218334Speter     This is useful only for machines which can't support doubles, e.g. some
5318334Speter     8-bit processors.
5418334Speter   CMPtype: Specify the type that floating point compares should return.
5518334Speter     This defaults to SItype, aka int.
5618334Speter   US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
5790075Sobrien     US Software goFast library.
5818334Speter   _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
5990075Sobrien     two integers to the FLO_union_type.
6090075Sobrien   NO_DENORMALS: Disable handling of denormals.
6118334Speter   NO_NANS: Disable nan and infinity handling
6218334Speter   SMALL_MACHINE: Useful when operations on QIs and HIs are faster
6318334Speter     than on an SI */
6418334Speter
6550397Sobrien/* We don't currently support extended floats (long doubles) on machines
6650397Sobrien   without hardware to deal with them.
6750397Sobrien
6850397Sobrien   These stubs are just to keep the linker from complaining about unresolved
6950397Sobrien   references which can be pulled in from libio & libstdc++, even if the
7050397Sobrien   user isn't using long doubles.  However, they may generate an unresolved
7150397Sobrien   external to abort if abort is not used by the function, and the stubs
7250397Sobrien   are referenced from within libc, since libgcc goes before and after the
7350397Sobrien   system library.  */
7450397Sobrien
75117395Skan#ifdef DECLARE_LIBRARY_RENAMES
76117395Skan  DECLARE_LIBRARY_RENAMES
77117395Skan#endif
78117395Skan
7950397Sobrien#ifdef EXTENDED_FLOAT_STUBS
80117395Skanextern void abort (void);
81117395Skanvoid __extendsfxf2 (void) { abort(); }
82117395Skanvoid __extenddfxf2 (void) { abort(); }
83117395Skanvoid __truncxfdf2 (void) { abort(); }
84117395Skanvoid __truncxfsf2 (void) { abort(); }
85117395Skanvoid __fixxfsi (void) { abort(); }
86117395Skanvoid __floatsixf (void) { abort(); }
87117395Skanvoid __addxf3 (void) { abort(); }
88117395Skanvoid __subxf3 (void) { abort(); }
89117395Skanvoid __mulxf3 (void) { abort(); }
90117395Skanvoid __divxf3 (void) { abort(); }
91117395Skanvoid __negxf2 (void) { abort(); }
92117395Skanvoid __eqxf2 (void) { abort(); }
93117395Skanvoid __nexf2 (void) { abort(); }
94117395Skanvoid __gtxf2 (void) { abort(); }
95117395Skanvoid __gexf2 (void) { abort(); }
96117395Skanvoid __lexf2 (void) { abort(); }
97117395Skanvoid __ltxf2 (void) { abort(); }
9850397Sobrien
99117395Skanvoid __extendsftf2 (void) { abort(); }
100117395Skanvoid __extenddftf2 (void) { abort(); }
101117395Skanvoid __trunctfdf2 (void) { abort(); }
102117395Skanvoid __trunctfsf2 (void) { abort(); }
103117395Skanvoid __fixtfsi (void) { abort(); }
104117395Skanvoid __floatsitf (void) { abort(); }
105117395Skanvoid __addtf3 (void) { abort(); }
106117395Skanvoid __subtf3 (void) { abort(); }
107117395Skanvoid __multf3 (void) { abort(); }
108117395Skanvoid __divtf3 (void) { abort(); }
109117395Skanvoid __negtf2 (void) { abort(); }
110117395Skanvoid __eqtf2 (void) { abort(); }
111117395Skanvoid __netf2 (void) { abort(); }
112117395Skanvoid __gttf2 (void) { abort(); }
113117395Skanvoid __getf2 (void) { abort(); }
114117395Skanvoid __letf2 (void) { abort(); }
115117395Skanvoid __lttf2 (void) { abort(); }
11650397Sobrien#else	/* !EXTENDED_FLOAT_STUBS, rest of file */
11750397Sobrien
11818334Speter/* IEEE "special" number predicates */
11918334Speter
12018334Speter#ifdef NO_NANS
12118334Speter
12218334Speter#define nan() 0
12318334Speter#define isnan(x) 0
12418334Speter#define isinf(x) 0
12518334Speter#else
12618334Speter
12790075Sobrien#if   defined L_thenan_sf
12890075Sobrienconst fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
12990075Sobrien#elif defined L_thenan_df
13090075Sobrienconst fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
131117395Skan#elif defined L_thenan_tf
132117395Skanconst fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
133117395Skan#elif defined TFLOAT
134117395Skanextern const fp_number_type __thenan_tf;
13590075Sobrien#elif defined FLOAT
13690075Sobrienextern const fp_number_type __thenan_sf;
13790075Sobrien#else
13890075Sobrienextern const fp_number_type __thenan_df;
13990075Sobrien#endif
14090075Sobrien
14118334SpeterINLINE
14218334Speterstatic fp_number_type *
14390075Sobriennan (void)
14418334Speter{
145117395Skan  /* Discard the const qualifier...  */
146117395Skan#ifdef TFLOAT
147117395Skan  return (fp_number_type *) (& __thenan_tf);
148117395Skan#elif defined FLOAT
14990075Sobrien  return (fp_number_type *) (& __thenan_sf);
15090075Sobrien#else
15190075Sobrien  return (fp_number_type *) (& __thenan_df);
15290075Sobrien#endif
15318334Speter}
15418334Speter
15518334SpeterINLINE
15618334Speterstatic int
15718334Speterisnan ( fp_number_type *  x)
15818334Speter{
159169689Skan  return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN,
160169689Skan			   0);
16118334Speter}
16218334Speter
16318334SpeterINLINE
16418334Speterstatic int
16518334Speterisinf ( fp_number_type *  x)
16618334Speter{
167169689Skan  return __builtin_expect (x->class == CLASS_INFINITY, 0);
16818334Speter}
16918334Speter
17090075Sobrien#endif /* NO_NANS */
17118334Speter
17218334SpeterINLINE
17318334Speterstatic int
17418334Speteriszero ( fp_number_type *  x)
17518334Speter{
17618334Speter  return x->class == CLASS_ZERO;
17718334Speter}
17818334Speter
17918334SpeterINLINE
18018334Speterstatic void
18118334Speterflip_sign ( fp_number_type *  x)
18218334Speter{
18318334Speter  x->sign = !x->sign;
18418334Speter}
18518334Speter
186169689Skan/* Count leading zeroes in N.  */
187169689SkanINLINE
188169689Skanstatic int
189169689Skanclzusi (USItype n)
190169689Skan{
191169689Skan  extern int __clzsi2 (USItype);
192169689Skan  if (sizeof (USItype) == sizeof (unsigned int))
193169689Skan    return __builtin_clz (n);
194169689Skan  else if (sizeof (USItype) == sizeof (unsigned long))
195169689Skan    return __builtin_clzl (n);
196169689Skan  else if (sizeof (USItype) == sizeof (unsigned long long))
197169689Skan    return __builtin_clzll (n);
198169689Skan  else
199169689Skan    return __clzsi2 (n);
200169689Skan}
201169689Skan
20250397Sobrienextern FLO_type pack_d ( fp_number_type * );
20350397Sobrien
204117395Skan#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
20550397SobrienFLO_type
20618334Speterpack_d ( fp_number_type *  src)
20718334Speter{
20818334Speter  FLO_union_type dst;
20918334Speter  fractype fraction = src->fraction.ll;	/* wasn't unsigned before? */
21018334Speter  int sign = src->sign;
21118334Speter  int exp = 0;
21218334Speter
213117395Skan  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
21418334Speter    {
215117395Skan      /* We can't represent these values accurately.  By using the
216117395Skan	 largest possible magnitude, we guarantee that the conversion
217117395Skan	 of infinity is at least as big as any finite number.  */
21818334Speter      exp = EXPMAX;
219117395Skan      fraction = ((fractype) 1 << FRACBITS) - 1;
220117395Skan    }
221117395Skan  else if (isnan (src))
222117395Skan    {
223117395Skan      exp = EXPMAX;
22418334Speter      if (src->class == CLASS_QNAN || 1)
22518334Speter	{
226132718Skan#ifdef QUIET_NAN_NEGATED
227132718Skan	  fraction |= QUIET_NAN - 1;
228132718Skan#else
22918334Speter	  fraction |= QUIET_NAN;
230132718Skan#endif
23118334Speter	}
23218334Speter    }
23318334Speter  else if (isinf (src))
23418334Speter    {
23518334Speter      exp = EXPMAX;
23618334Speter      fraction = 0;
23718334Speter    }
23818334Speter  else if (iszero (src))
23918334Speter    {
24018334Speter      exp = 0;
24118334Speter      fraction = 0;
24218334Speter    }
24318334Speter  else if (fraction == 0)
24418334Speter    {
24518334Speter      exp = 0;
24618334Speter    }
24718334Speter  else
24818334Speter    {
249169689Skan      if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0))
25018334Speter	{
251117395Skan#ifdef NO_DENORMALS
252117395Skan	  /* Go straight to a zero representation if denormals are not
253117395Skan 	     supported.  The denormal handling would be harmless but
254117395Skan 	     isn't unnecessary.  */
255117395Skan	  exp = 0;
256117395Skan	  fraction = 0;
257117395Skan#else /* NO_DENORMALS */
25818334Speter	  /* This number's exponent is too low to fit into the bits
25918334Speter	     available in the number, so we'll store 0 in the exponent and
26018334Speter	     shift the fraction to the right to make up for it.  */
26118334Speter
26218334Speter	  int shift = NORMAL_EXPMIN - src->normal_exp;
26318334Speter
26418334Speter	  exp = 0;
26518334Speter
26618334Speter	  if (shift > FRAC_NBITS - NGARDS)
26718334Speter	    {
26818334Speter	      /* No point shifting, since it's more that 64 out.  */
26918334Speter	      fraction = 0;
27018334Speter	    }
27118334Speter	  else
27218334Speter	    {
27390075Sobrien	      int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
27490075Sobrien	      fraction = (fraction >> shift) | lowbit;
27518334Speter	    }
27690075Sobrien	  if ((fraction & GARDMASK) == GARDMSB)
27790075Sobrien	    {
27890075Sobrien	      if ((fraction & (1 << NGARDS)))
27990075Sobrien		fraction += GARDROUND + 1;
28090075Sobrien	    }
28190075Sobrien	  else
28290075Sobrien	    {
28390075Sobrien	      /* Add to the guards to round up.  */
28490075Sobrien	      fraction += GARDROUND;
28590075Sobrien	    }
28690075Sobrien	  /* Perhaps the rounding means we now need to change the
28790075Sobrien             exponent, because the fraction is no longer denormal.  */
28890075Sobrien	  if (fraction >= IMPLICIT_1)
28990075Sobrien	    {
29090075Sobrien	      exp += 1;
29190075Sobrien	    }
29218334Speter	  fraction >>= NGARDS;
293117395Skan#endif /* NO_DENORMALS */
29418334Speter	}
295117395Skan      else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
296169689Skan	       && __builtin_expect (src->normal_exp > EXPBIAS, 0))
29718334Speter	{
29818334Speter	  exp = EXPMAX;
29918334Speter	  fraction = 0;
30018334Speter	}
30118334Speter      else
30218334Speter	{
30318334Speter	  exp = src->normal_exp + EXPBIAS;
304117395Skan	  if (!ROUND_TOWARDS_ZERO)
30518334Speter	    {
306117395Skan	      /* IF the gard bits are the all zero, but the first, then we're
307117395Skan		 half way between two numbers, choose the one which makes the
308117395Skan		 lsb of the answer 0.  */
309117395Skan	      if ((fraction & GARDMASK) == GARDMSB)
310117395Skan		{
311117395Skan		  if (fraction & (1 << NGARDS))
312117395Skan		    fraction += GARDROUND + 1;
313117395Skan		}
314117395Skan	      else
315117395Skan		{
316117395Skan		  /* Add a one to the guards to round up */
317117395Skan		  fraction += GARDROUND;
318117395Skan		}
319117395Skan	      if (fraction >= IMPLICIT_2)
320117395Skan		{
321117395Skan		  fraction >>= 1;
322117395Skan		  exp += 1;
323117395Skan		}
32418334Speter	    }
325117395Skan	  fraction >>= NGARDS;
326117395Skan
327117395Skan	  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
32818334Speter	    {
329117395Skan	      /* Saturate on overflow.  */
330117395Skan	      exp = EXPMAX;
331117395Skan	      fraction = ((fractype) 1 << FRACBITS) - 1;
33218334Speter	    }
33318334Speter	}
33418334Speter    }
33518334Speter
33618334Speter  /* We previously used bitfields to store the number, but this doesn't
33750397Sobrien     handle little/big endian systems conveniently, so use shifts and
33818334Speter     masks */
33918334Speter#ifdef FLOAT_BIT_ORDER_MISMATCH
34018334Speter  dst.bits.fraction = fraction;
34118334Speter  dst.bits.exp = exp;
34218334Speter  dst.bits.sign = sign;
34318334Speter#else
344117395Skan# if defined TFLOAT && defined HALFFRACBITS
345117395Skan {
346132718Skan   halffractype high, low, unity;
347132718Skan   int lowsign, lowexp;
348117395Skan
349132718Skan   unity = (halffractype) 1 << HALFFRACBITS;
350117395Skan
351132718Skan   /* Set HIGH to the high double's significand, masking out the implicit 1.
352132718Skan      Set LOW to the low double's full significand.  */
353132718Skan   high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
354132718Skan   low = fraction & (unity * 2 - 1);
355117395Skan
356132718Skan   /* Get the initial sign and exponent of the low double.  */
357132718Skan   lowexp = exp - HALFFRACBITS - 1;
358132718Skan   lowsign = sign;
359132718Skan
360132718Skan   /* HIGH should be rounded like a normal double, making |LOW| <=
361132718Skan      0.5 ULP of HIGH.  Assume round-to-nearest.  */
362132718Skan   if (exp < EXPMAX)
363132718Skan     if (low > unity || (low == unity && (high & 1) == 1))
364132718Skan       {
365132718Skan	 /* Round HIGH up and adjust LOW to match.  */
366132718Skan	 high++;
367132718Skan	 if (high == unity)
368132718Skan	   {
369132718Skan	     /* May make it infinite, but that's OK.  */
370132718Skan	     high = 0;
371132718Skan	     exp++;
372132718Skan	   }
373132718Skan	 low = unity * 2 - low;
374132718Skan	 lowsign ^= 1;
375132718Skan       }
376132718Skan
377132718Skan   high |= (halffractype) exp << HALFFRACBITS;
378132718Skan   high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
379132718Skan
380117395Skan   if (exp == EXPMAX || exp == 0 || low == 0)
381117395Skan     low = 0;
382117395Skan   else
383117395Skan     {
384132718Skan       while (lowexp > 0 && low < unity)
385117395Skan	 {
386117395Skan	   low <<= 1;
387132718Skan	   lowexp--;
388117395Skan	 }
389117395Skan
390132718Skan       if (lowexp <= 0)
391117395Skan	 {
392117395Skan	   halffractype roundmsb, round;
393132718Skan	   int shift;
394117395Skan
395132718Skan	   shift = 1 - lowexp;
396132718Skan	   roundmsb = (1 << (shift - 1));
397117395Skan	   round = low & ((roundmsb << 1) - 1);
398117395Skan
399132718Skan	   low >>= shift;
400132718Skan	   lowexp = 0;
401117395Skan
402132718Skan	   if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
403117395Skan	     {
404117395Skan	       low++;
405132718Skan	       if (low == unity)
406132718Skan		 /* LOW rounds up to the smallest normal number.  */
407132718Skan		 lowexp++;
408117395Skan	     }
409117395Skan	 }
410117395Skan
411132718Skan       low &= unity - 1;
412132718Skan       low |= (halffractype) lowexp << HALFFRACBITS;
413132718Skan       low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
414117395Skan     }
415132718Skan   dst.value_raw = ((fractype) high << HALFSHIFT) | low;
416117395Skan }
417117395Skan# else
41818334Speter  dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
41918334Speter  dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
42018334Speter  dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
421117395Skan# endif
42218334Speter#endif
42318334Speter
42418334Speter#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
425117395Skan#ifdef TFLOAT
42618334Speter  {
427117395Skan    qrtrfractype tmp1 = dst.words[0];
428117395Skan    qrtrfractype tmp2 = dst.words[1];
429117395Skan    dst.words[0] = dst.words[3];
430117395Skan    dst.words[1] = dst.words[2];
431117395Skan    dst.words[2] = tmp2;
432117395Skan    dst.words[3] = tmp1;
433117395Skan  }
434117395Skan#else
435117395Skan  {
43618334Speter    halffractype tmp = dst.words[0];
43718334Speter    dst.words[0] = dst.words[1];
43818334Speter    dst.words[1] = tmp;
43918334Speter  }
44018334Speter#endif
441117395Skan#endif
44218334Speter
44318334Speter  return dst.value;
44418334Speter}
44550397Sobrien#endif
44618334Speter
447117395Skan#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
44850397Sobrienvoid
44918334Speterunpack_d (FLO_union_type * src, fp_number_type * dst)
45018334Speter{
45118334Speter  /* We previously used bitfields to store the number, but this doesn't
45250397Sobrien     handle little/big endian systems conveniently, so use shifts and
45318334Speter     masks */
45418334Speter  fractype fraction;
45518334Speter  int exp;
45618334Speter  int sign;
45718334Speter
45818334Speter#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
45918334Speter  FLO_union_type swapped;
46018334Speter
461117395Skan#ifdef TFLOAT
462117395Skan  swapped.words[0] = src->words[3];
463117395Skan  swapped.words[1] = src->words[2];
464117395Skan  swapped.words[2] = src->words[1];
465117395Skan  swapped.words[3] = src->words[0];
466117395Skan#else
46718334Speter  swapped.words[0] = src->words[1];
46818334Speter  swapped.words[1] = src->words[0];
469117395Skan#endif
47018334Speter  src = &swapped;
47118334Speter#endif
47218334Speter
47318334Speter#ifdef FLOAT_BIT_ORDER_MISMATCH
47418334Speter  fraction = src->bits.fraction;
47518334Speter  exp = src->bits.exp;
47618334Speter  sign = src->bits.sign;
47718334Speter#else
478117395Skan# if defined TFLOAT && defined HALFFRACBITS
479117395Skan {
480117395Skan   halffractype high, low;
481117395Skan
482117395Skan   high = src->value_raw >> HALFSHIFT;
483117395Skan   low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
484117395Skan
485117395Skan   fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
486117395Skan   fraction <<= FRACBITS - HALFFRACBITS;
487117395Skan   exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
488117395Skan   sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
489117395Skan
490117395Skan   if (exp != EXPMAX && exp != 0 && low != 0)
491117395Skan     {
492117395Skan       int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
493117395Skan       int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
494117395Skan       int shift;
495117395Skan       fractype xlow;
496117395Skan
497117395Skan       xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
498117395Skan       if (lowexp)
499117395Skan	 xlow |= (((halffractype)1) << HALFFRACBITS);
500117395Skan       else
501117395Skan	 lowexp = 1;
502117395Skan       shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
503117395Skan       if (shift > 0)
504117395Skan	 xlow <<= shift;
505117395Skan       else if (shift < 0)
506117395Skan	 xlow >>= -shift;
507117395Skan       if (sign == lowsign)
508117395Skan	 fraction += xlow;
509132718Skan       else if (fraction >= xlow)
510132718Skan	 fraction -= xlow;
511117395Skan       else
512132718Skan	 {
513132718Skan	   /* The high part is a power of two but the full number is lower.
514132718Skan	      This code will leave the implicit 1 in FRACTION, but we'd
515132718Skan	      have added that below anyway.  */
516132718Skan	   fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
517132718Skan	   exp--;
518132718Skan	 }
519117395Skan     }
520117395Skan }
521117395Skan# else
522117395Skan  fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
52318334Speter  exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
52418334Speter  sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
525117395Skan# endif
52618334Speter#endif
52718334Speter
52818334Speter  dst->sign = sign;
52918334Speter  if (exp == 0)
53018334Speter    {
53118334Speter      /* Hmm.  Looks like 0 */
53290075Sobrien      if (fraction == 0
53390075Sobrien#ifdef NO_DENORMALS
53490075Sobrien	  || 1
53590075Sobrien#endif
53690075Sobrien	  )
53718334Speter	{
53818334Speter	  /* tastes like zero */
53918334Speter	  dst->class = CLASS_ZERO;
54018334Speter	}
54118334Speter      else
54218334Speter	{
543117395Skan	  /* Zero exponent with nonzero fraction - it's denormalized,
54418334Speter	     so there isn't a leading implicit one - we'll shift it so
54518334Speter	     it gets one.  */
54618334Speter	  dst->normal_exp = exp - EXPBIAS + 1;
54718334Speter	  fraction <<= NGARDS;
54818334Speter
54918334Speter	  dst->class = CLASS_NUMBER;
55018334Speter#if 1
55118334Speter	  while (fraction < IMPLICIT_1)
55218334Speter	    {
55318334Speter	      fraction <<= 1;
55418334Speter	      dst->normal_exp--;
55518334Speter	    }
55618334Speter#endif
55718334Speter	  dst->fraction.ll = fraction;
55818334Speter	}
55918334Speter    }
560169689Skan  else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
561169689Skan	   && __builtin_expect (exp == EXPMAX, 0))
56218334Speter    {
56318334Speter      /* Huge exponent*/
56418334Speter      if (fraction == 0)
56518334Speter	{
56618334Speter	  /* Attached to a zero fraction - means infinity */
56718334Speter	  dst->class = CLASS_INFINITY;
56818334Speter	}
56918334Speter      else
57018334Speter	{
571117395Skan	  /* Nonzero fraction, means nan */
572132718Skan#ifdef QUIET_NAN_NEGATED
573132718Skan	  if ((fraction & QUIET_NAN) == 0)
574132718Skan#else
57550397Sobrien	  if (fraction & QUIET_NAN)
576132718Skan#endif
57718334Speter	    {
57850397Sobrien	      dst->class = CLASS_QNAN;
57918334Speter	    }
58018334Speter	  else
58118334Speter	    {
58250397Sobrien	      dst->class = CLASS_SNAN;
58318334Speter	    }
58418334Speter	  /* Keep the fraction part as the nan number */
58518334Speter	  dst->fraction.ll = fraction;
58618334Speter	}
58718334Speter    }
58818334Speter  else
58918334Speter    {
59018334Speter      /* Nothing strange about this number */
59118334Speter      dst->normal_exp = exp - EXPBIAS;
59218334Speter      dst->class = CLASS_NUMBER;
59318334Speter      dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
59418334Speter    }
59518334Speter}
59690075Sobrien#endif /* L_unpack_df || L_unpack_sf */
59718334Speter
598117395Skan#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
59918334Speterstatic fp_number_type *
60018334Speter_fpadd_parts (fp_number_type * a,
60118334Speter	      fp_number_type * b,
60218334Speter	      fp_number_type * tmp)
60318334Speter{
60418334Speter  intfrac tfraction;
60518334Speter
60618334Speter  /* Put commonly used fields in local variables.  */
60718334Speter  int a_normal_exp;
60818334Speter  int b_normal_exp;
60918334Speter  fractype a_fraction;
61018334Speter  fractype b_fraction;
61118334Speter
61218334Speter  if (isnan (a))
61318334Speter    {
61418334Speter      return a;
61518334Speter    }
61618334Speter  if (isnan (b))
61718334Speter    {
61818334Speter      return b;
61918334Speter    }
62018334Speter  if (isinf (a))
62118334Speter    {
62218334Speter      /* Adding infinities with opposite signs yields a NaN.  */
62318334Speter      if (isinf (b) && a->sign != b->sign)
62418334Speter	return nan ();
62518334Speter      return a;
62618334Speter    }
62718334Speter  if (isinf (b))
62818334Speter    {
62918334Speter      return b;
63018334Speter    }
63118334Speter  if (iszero (b))
63218334Speter    {
63350397Sobrien      if (iszero (a))
63450397Sobrien	{
63550397Sobrien	  *tmp = *a;
63650397Sobrien	  tmp->sign = a->sign & b->sign;
63750397Sobrien	  return tmp;
63850397Sobrien	}
63918334Speter      return a;
64018334Speter    }
64118334Speter  if (iszero (a))
64218334Speter    {
64318334Speter      return b;
64418334Speter    }
64518334Speter
64618334Speter  /* Got two numbers. shift the smaller and increment the exponent till
64718334Speter     they're the same */
64818334Speter  {
64918334Speter    int diff;
650169689Skan    int sdiff;
65118334Speter
65218334Speter    a_normal_exp = a->normal_exp;
65318334Speter    b_normal_exp = b->normal_exp;
65418334Speter    a_fraction = a->fraction.ll;
65518334Speter    b_fraction = b->fraction.ll;
65618334Speter
65718334Speter    diff = a_normal_exp - b_normal_exp;
658169689Skan    sdiff = diff;
65918334Speter
66018334Speter    if (diff < 0)
66118334Speter      diff = -diff;
66218334Speter    if (diff < FRAC_NBITS)
66318334Speter      {
664169689Skan	if (sdiff > 0)
66518334Speter	  {
666169689Skan	    b_normal_exp += diff;
667169689Skan	    LSHIFT (b_fraction, diff);
66818334Speter	  }
669169689Skan	else if (sdiff < 0)
67018334Speter	  {
671169689Skan	    a_normal_exp += diff;
672169689Skan	    LSHIFT (a_fraction, diff);
67318334Speter	  }
67418334Speter      }
67518334Speter    else
67618334Speter      {
67718334Speter	/* Somethings's up.. choose the biggest */
67818334Speter	if (a_normal_exp > b_normal_exp)
67918334Speter	  {
68018334Speter	    b_normal_exp = a_normal_exp;
68118334Speter	    b_fraction = 0;
68218334Speter	  }
68318334Speter	else
68418334Speter	  {
68518334Speter	    a_normal_exp = b_normal_exp;
68618334Speter	    a_fraction = 0;
68718334Speter	  }
68818334Speter      }
68918334Speter  }
69018334Speter
69118334Speter  if (a->sign != b->sign)
69218334Speter    {
69318334Speter      if (a->sign)
69418334Speter	{
69518334Speter	  tfraction = -a_fraction + b_fraction;
69618334Speter	}
69718334Speter      else
69818334Speter	{
69918334Speter	  tfraction = a_fraction - b_fraction;
70018334Speter	}
70152284Sobrien      if (tfraction >= 0)
70218334Speter	{
70318334Speter	  tmp->sign = 0;
70418334Speter	  tmp->normal_exp = a_normal_exp;
70518334Speter	  tmp->fraction.ll = tfraction;
70618334Speter	}
70718334Speter      else
70818334Speter	{
70918334Speter	  tmp->sign = 1;
71018334Speter	  tmp->normal_exp = a_normal_exp;
71118334Speter	  tmp->fraction.ll = -tfraction;
71218334Speter	}
71318334Speter      /* and renormalize it */
71418334Speter
71518334Speter      while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
71618334Speter	{
71718334Speter	  tmp->fraction.ll <<= 1;
71818334Speter	  tmp->normal_exp--;
71918334Speter	}
72018334Speter    }
72118334Speter  else
72218334Speter    {
72318334Speter      tmp->sign = a->sign;
72418334Speter      tmp->normal_exp = a_normal_exp;
72518334Speter      tmp->fraction.ll = a_fraction + b_fraction;
72618334Speter    }
72718334Speter  tmp->class = CLASS_NUMBER;
72818334Speter  /* Now the fraction is added, we have to shift down to renormalize the
72918334Speter     number */
73018334Speter
73118334Speter  if (tmp->fraction.ll >= IMPLICIT_2)
73218334Speter    {
733169689Skan      LSHIFT (tmp->fraction.ll, 1);
73418334Speter      tmp->normal_exp++;
73518334Speter    }
73618334Speter  return tmp;
73718334Speter
73818334Speter}
73918334Speter
74018334SpeterFLO_type
74118334Speteradd (FLO_type arg_a, FLO_type arg_b)
74218334Speter{
74318334Speter  fp_number_type a;
74418334Speter  fp_number_type b;
74518334Speter  fp_number_type tmp;
74618334Speter  fp_number_type *res;
74790075Sobrien  FLO_union_type au, bu;
74818334Speter
74990075Sobrien  au.value = arg_a;
75090075Sobrien  bu.value = arg_b;
75118334Speter
75290075Sobrien  unpack_d (&au, &a);
75390075Sobrien  unpack_d (&bu, &b);
75490075Sobrien
75518334Speter  res = _fpadd_parts (&a, &b, &tmp);
75618334Speter
75718334Speter  return pack_d (res);
75818334Speter}
75918334Speter
76018334SpeterFLO_type
76118334Spetersub (FLO_type arg_a, FLO_type arg_b)
76218334Speter{
76318334Speter  fp_number_type a;
76418334Speter  fp_number_type b;
76518334Speter  fp_number_type tmp;
76618334Speter  fp_number_type *res;
76790075Sobrien  FLO_union_type au, bu;
76818334Speter
76990075Sobrien  au.value = arg_a;
77090075Sobrien  bu.value = arg_b;
77118334Speter
77290075Sobrien  unpack_d (&au, &a);
77390075Sobrien  unpack_d (&bu, &b);
77490075Sobrien
77518334Speter  b.sign ^= 1;
77618334Speter
77718334Speter  res = _fpadd_parts (&a, &b, &tmp);
77818334Speter
77918334Speter  return pack_d (res);
78018334Speter}
78190075Sobrien#endif /* L_addsub_sf || L_addsub_df */
78218334Speter
783117395Skan#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
784117395Skanstatic inline __attribute__ ((__always_inline__)) fp_number_type *
78518334Speter_fpmul_parts ( fp_number_type *  a,
78618334Speter	       fp_number_type *  b,
78718334Speter	       fp_number_type * tmp)
78818334Speter{
78918334Speter  fractype low = 0;
79018334Speter  fractype high = 0;
79118334Speter
79218334Speter  if (isnan (a))
79318334Speter    {
79418334Speter      a->sign = a->sign != b->sign;
79518334Speter      return a;
79618334Speter    }
79718334Speter  if (isnan (b))
79818334Speter    {
79918334Speter      b->sign = a->sign != b->sign;
80018334Speter      return b;
80118334Speter    }
80218334Speter  if (isinf (a))
80318334Speter    {
80418334Speter      if (iszero (b))
80518334Speter	return nan ();
80618334Speter      a->sign = a->sign != b->sign;
80718334Speter      return a;
80818334Speter    }
80918334Speter  if (isinf (b))
81018334Speter    {
81118334Speter      if (iszero (a))
81218334Speter	{
81318334Speter	  return nan ();
81418334Speter	}
81518334Speter      b->sign = a->sign != b->sign;
81618334Speter      return b;
81718334Speter    }
81818334Speter  if (iszero (a))
81918334Speter    {
82018334Speter      a->sign = a->sign != b->sign;
82118334Speter      return a;
82218334Speter    }
82318334Speter  if (iszero (b))
82418334Speter    {
82518334Speter      b->sign = a->sign != b->sign;
82618334Speter      return b;
82718334Speter    }
82818334Speter
82990075Sobrien  /* Calculate the mantissa by multiplying both numbers to get a
83090075Sobrien     twice-as-wide number.  */
83118334Speter  {
832117395Skan#if defined(NO_DI_MODE) || defined(TFLOAT)
83318334Speter    {
83450397Sobrien      fractype x = a->fraction.ll;
83550397Sobrien      fractype ylow = b->fraction.ll;
83650397Sobrien      fractype yhigh = 0;
83750397Sobrien      int bit;
83850397Sobrien
83918334Speter      /* ??? This does multiplies one bit at a time.  Optimize.  */
84018334Speter      for (bit = 0; bit < FRAC_NBITS; bit++)
84118334Speter	{
84218334Speter	  int carry;
84318334Speter
84418334Speter	  if (x & 1)
84518334Speter	    {
84618334Speter	      carry = (low += ylow) < ylow;
84718334Speter	      high += yhigh + carry;
84818334Speter	    }
84918334Speter	  yhigh <<= 1;
85018334Speter	  if (ylow & FRACHIGH)
85118334Speter	    {
85218334Speter	      yhigh |= 1;
85318334Speter	    }
85418334Speter	  ylow <<= 1;
85518334Speter	  x >>= 1;
85618334Speter	}
85718334Speter    }
85818334Speter#elif defined(FLOAT)
85990075Sobrien    /* Multiplying two USIs to get a UDI, we're safe.  */
86018334Speter    {
86190075Sobrien      UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
86218334Speter
86390075Sobrien      high = answer >> BITS_PER_SI;
86418334Speter      low = answer;
86518334Speter    }
86618334Speter#else
86790075Sobrien    /* fractype is DImode, but we need the result to be twice as wide.
86890075Sobrien       Assuming a widening multiply from DImode to TImode is not
86990075Sobrien       available, build one by hand.  */
87018334Speter    {
87190075Sobrien      USItype nl = a->fraction.ll;
87290075Sobrien      USItype nh = a->fraction.ll >> BITS_PER_SI;
87390075Sobrien      USItype ml = b->fraction.ll;
87490075Sobrien      USItype mh = b->fraction.ll >> BITS_PER_SI;
87590075Sobrien      UDItype pp_ll = (UDItype) ml * nl;
87690075Sobrien      UDItype pp_hl = (UDItype) mh * nl;
87790075Sobrien      UDItype pp_lh = (UDItype) ml * nh;
87890075Sobrien      UDItype pp_hh = (UDItype) mh * nh;
87918334Speter      UDItype res2 = 0;
88018334Speter      UDItype res0 = 0;
88118334Speter      UDItype ps_hh__ = pp_hl + pp_lh;
88218334Speter      if (ps_hh__ < pp_hl)
88390075Sobrien	res2 += (UDItype)1 << BITS_PER_SI;
88490075Sobrien      pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
88518334Speter      res0 = pp_ll + pp_hl;
88618334Speter      if (res0 < pp_ll)
88718334Speter	res2++;
88890075Sobrien      res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
88918334Speter      high = res2;
89018334Speter      low = res0;
89118334Speter    }
89218334Speter#endif
89318334Speter  }
89418334Speter
895117395Skan  tmp->normal_exp = a->normal_exp + b->normal_exp
896117395Skan    + FRAC_NBITS - (FRACBITS + NGARDS);
89718334Speter  tmp->sign = a->sign != b->sign;
89818334Speter  while (high >= IMPLICIT_2)
89918334Speter    {
90018334Speter      tmp->normal_exp++;
90118334Speter      if (high & 1)
90218334Speter	{
90318334Speter	  low >>= 1;
90418334Speter	  low |= FRACHIGH;
90518334Speter	}
90618334Speter      high >>= 1;
90718334Speter    }
90818334Speter  while (high < IMPLICIT_1)
90918334Speter    {
91018334Speter      tmp->normal_exp--;
91118334Speter
91218334Speter      high <<= 1;
91318334Speter      if (low & FRACHIGH)
91418334Speter	high |= 1;
91518334Speter      low <<= 1;
91618334Speter    }
917169689Skan
918117395Skan  if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
91918334Speter    {
92018334Speter      if (high & (1 << NGARDS))
92118334Speter	{
922169689Skan	  /* Because we're half way, we would round to even by adding
923169689Skan	     GARDROUND + 1, except that's also done in the packing
924169689Skan	     function, and rounding twice will lose precision and cause
925169689Skan	     the result to be too far off.  Example: 32-bit floats with
926169689Skan	     bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp
927169689Skan	     off), not 0x1000 (more than 0.5ulp off).  */
92818334Speter	}
92918334Speter      else if (low)
93018334Speter	{
931169689Skan	  /* We're a further than half way by a small amount corresponding
932169689Skan	     to the bits set in "low".  Knowing that, we round here and
933169689Skan	     not in pack_d, because there we don't have "low" available
934169689Skan	     anymore.  */
93518334Speter	  high += GARDROUND + 1;
936169689Skan
937169689Skan	  /* Avoid further rounding in pack_d.  */
938169689Skan	  high &= ~(fractype) GARDMASK;
93918334Speter	}
94018334Speter    }
94118334Speter  tmp->fraction.ll = high;
94218334Speter  tmp->class = CLASS_NUMBER;
94318334Speter  return tmp;
94418334Speter}
94518334Speter
94618334SpeterFLO_type
94718334Spetermultiply (FLO_type arg_a, FLO_type arg_b)
94818334Speter{
94918334Speter  fp_number_type a;
95018334Speter  fp_number_type b;
95118334Speter  fp_number_type tmp;
95218334Speter  fp_number_type *res;
95390075Sobrien  FLO_union_type au, bu;
95418334Speter
95590075Sobrien  au.value = arg_a;
95690075Sobrien  bu.value = arg_b;
95718334Speter
95890075Sobrien  unpack_d (&au, &a);
95990075Sobrien  unpack_d (&bu, &b);
96090075Sobrien
96118334Speter  res = _fpmul_parts (&a, &b, &tmp);
96218334Speter
96318334Speter  return pack_d (res);
96418334Speter}
965169689Skan#endif /* L_mul_sf || L_mul_df || L_mul_tf */
96618334Speter
967117395Skan#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
968117395Skanstatic inline __attribute__ ((__always_inline__)) fp_number_type *
96918334Speter_fpdiv_parts (fp_number_type * a,
97052284Sobrien	      fp_number_type * b)
97118334Speter{
97250397Sobrien  fractype bit;
97318334Speter  fractype numerator;
97418334Speter  fractype denominator;
97518334Speter  fractype quotient;
97618334Speter
97718334Speter  if (isnan (a))
97818334Speter    {
97918334Speter      return a;
98018334Speter    }
98118334Speter  if (isnan (b))
98218334Speter    {
98318334Speter      return b;
98418334Speter    }
98550397Sobrien
98650397Sobrien  a->sign = a->sign ^ b->sign;
98750397Sobrien
98818334Speter  if (isinf (a) || iszero (a))
98918334Speter    {
99018334Speter      if (a->class == b->class)
99118334Speter	return nan ();
99218334Speter      return a;
99318334Speter    }
99418334Speter
99518334Speter  if (isinf (b))
99618334Speter    {
99718334Speter      a->fraction.ll = 0;
99818334Speter      a->normal_exp = 0;
99918334Speter      return a;
100018334Speter    }
100118334Speter  if (iszero (b))
100218334Speter    {
100318334Speter      a->class = CLASS_INFINITY;
100450397Sobrien      return a;
100518334Speter    }
100618334Speter
100718334Speter  /* Calculate the mantissa by multiplying both 64bit numbers to get a
100818334Speter     128 bit number */
100918334Speter  {
101018334Speter    /* quotient =
101118334Speter       ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)
101218334Speter     */
101318334Speter
101418334Speter    a->normal_exp = a->normal_exp - b->normal_exp;
101518334Speter    numerator = a->fraction.ll;
101618334Speter    denominator = b->fraction.ll;
101718334Speter
101818334Speter    if (numerator < denominator)
101918334Speter      {
102018334Speter	/* Fraction will be less than 1.0 */
102118334Speter	numerator *= 2;
102218334Speter	a->normal_exp--;
102318334Speter      }
102418334Speter    bit = IMPLICIT_1;
102518334Speter    quotient = 0;
102618334Speter    /* ??? Does divide one bit at a time.  Optimize.  */
102718334Speter    while (bit)
102818334Speter      {
102918334Speter	if (numerator >= denominator)
103018334Speter	  {
103118334Speter	    quotient |= bit;
103218334Speter	    numerator -= denominator;
103318334Speter	  }
103418334Speter	bit >>= 1;
103518334Speter	numerator *= 2;
103618334Speter      }
103718334Speter
1038117395Skan    if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
103918334Speter      {
104018334Speter	if (quotient & (1 << NGARDS))
104118334Speter	  {
1042169689Skan	    /* Because we're half way, we would round to even by adding
1043169689Skan	       GARDROUND + 1, except that's also done in the packing
1044169689Skan	       function, and rounding twice will lose precision and cause
1045169689Skan	       the result to be too far off.  */
104618334Speter	  }
104718334Speter	else if (numerator)
104818334Speter	  {
1049169689Skan	    /* We're a further than half way by the small amount
1050169689Skan	       corresponding to the bits set in "numerator".  Knowing
1051169689Skan	       that, we round here and not in pack_d, because there we
1052169689Skan	       don't have "numerator" available anymore.  */
105318334Speter	    quotient += GARDROUND + 1;
1054169689Skan
1055169689Skan	    /* Avoid further rounding in pack_d.  */
1056169689Skan	    quotient &= ~(fractype) GARDMASK;
105718334Speter	  }
105818334Speter      }
105918334Speter
106018334Speter    a->fraction.ll = quotient;
106118334Speter    return (a);
106218334Speter  }
106318334Speter}
106418334Speter
106518334SpeterFLO_type
106618334Speterdivide (FLO_type arg_a, FLO_type arg_b)
106718334Speter{
106818334Speter  fp_number_type a;
106918334Speter  fp_number_type b;
107018334Speter  fp_number_type *res;
107190075Sobrien  FLO_union_type au, bu;
107218334Speter
107390075Sobrien  au.value = arg_a;
107490075Sobrien  bu.value = arg_b;
107518334Speter
107690075Sobrien  unpack_d (&au, &a);
107790075Sobrien  unpack_d (&bu, &b);
107890075Sobrien
107952284Sobrien  res = _fpdiv_parts (&a, &b);
108018334Speter
108118334Speter  return pack_d (res);
108218334Speter}
108390075Sobrien#endif /* L_div_sf || L_div_df */
108418334Speter
1085117395Skan#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
1086117395Skan    || defined(L_fpcmp_parts_tf)
108718334Speter/* according to the demo, fpcmp returns a comparison with 0... thus
108818334Speter   a<b -> -1
108918334Speter   a==b -> 0
109018334Speter   a>b -> +1
109118334Speter */
109218334Speter
109350397Sobrienint
109450397Sobrien__fpcmp_parts (fp_number_type * a, fp_number_type * b)
109518334Speter{
109618334Speter#if 0
1097117395Skan  /* either nan -> unordered. Must be checked outside of this routine.  */
109818334Speter  if (isnan (a) && isnan (b))
109918334Speter    {
110018334Speter      return 1;			/* still unordered! */
110118334Speter    }
110218334Speter#endif
110318334Speter
110418334Speter  if (isnan (a) || isnan (b))
110518334Speter    {
110618334Speter      return 1;			/* how to indicate unordered compare? */
110718334Speter    }
110818334Speter  if (isinf (a) && isinf (b))
110918334Speter    {
111018334Speter      /* +inf > -inf, but +inf != +inf */
111118334Speter      /* b    \a| +inf(0)| -inf(1)
111218334Speter       ______\+--------+--------
111318334Speter       +inf(0)| a==b(0)| a<b(-1)
111418334Speter       -------+--------+--------
111518334Speter       -inf(1)| a>b(1) | a==b(0)
111618334Speter       -------+--------+--------
1117117395Skan       So since unordered must be nonzero, just line up the columns...
111818334Speter       */
111918334Speter      return b->sign - a->sign;
112018334Speter    }
1121117395Skan  /* but not both...  */
112218334Speter  if (isinf (a))
112318334Speter    {
112418334Speter      return a->sign ? -1 : 1;
112518334Speter    }
112618334Speter  if (isinf (b))
112718334Speter    {
112818334Speter      return b->sign ? 1 : -1;
112918334Speter    }
113018334Speter  if (iszero (a) && iszero (b))
113118334Speter    {
113218334Speter      return 0;
113318334Speter    }
113418334Speter  if (iszero (a))
113518334Speter    {
113618334Speter      return b->sign ? 1 : -1;
113718334Speter    }
113818334Speter  if (iszero (b))
113918334Speter    {
114018334Speter      return a->sign ? -1 : 1;
114118334Speter    }
1142117395Skan  /* now both are "normal".  */
114318334Speter  if (a->sign != b->sign)
114418334Speter    {
114518334Speter      /* opposite signs */
114618334Speter      return a->sign ? -1 : 1;
114718334Speter    }
114818334Speter  /* same sign; exponents? */
114918334Speter  if (a->normal_exp > b->normal_exp)
115018334Speter    {
115118334Speter      return a->sign ? -1 : 1;
115218334Speter    }
115318334Speter  if (a->normal_exp < b->normal_exp)
115418334Speter    {
115518334Speter      return a->sign ? 1 : -1;
115618334Speter    }
1157117395Skan  /* same exponents; check size.  */
115818334Speter  if (a->fraction.ll > b->fraction.ll)
115918334Speter    {
116018334Speter      return a->sign ? -1 : 1;
116118334Speter    }
116218334Speter  if (a->fraction.ll < b->fraction.ll)
116318334Speter    {
116418334Speter      return a->sign ? 1 : -1;
116518334Speter    }
1166117395Skan  /* after all that, they're equal.  */
116718334Speter  return 0;
116818334Speter}
116950397Sobrien#endif
117018334Speter
1171117395Skan#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
117218334SpeterCMPtype
117318334Spetercompare (FLO_type arg_a, FLO_type arg_b)
117418334Speter{
117518334Speter  fp_number_type a;
117618334Speter  fp_number_type b;
117790075Sobrien  FLO_union_type au, bu;
117818334Speter
117990075Sobrien  au.value = arg_a;
118090075Sobrien  bu.value = arg_b;
118118334Speter
118290075Sobrien  unpack_d (&au, &a);
118390075Sobrien  unpack_d (&bu, &b);
118490075Sobrien
118550397Sobrien  return __fpcmp_parts (&a, &b);
118618334Speter}
118790075Sobrien#endif /* L_compare_sf || L_compare_df */
118818334Speter
118918334Speter#ifndef US_SOFTWARE_GOFAST
119018334Speter
119118334Speter/* These should be optimized for their specific tasks someday.  */
119218334Speter
1193117395Skan#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
119418334SpeterCMPtype
119518334Speter_eq_f2 (FLO_type arg_a, FLO_type arg_b)
119618334Speter{
119718334Speter  fp_number_type a;
119818334Speter  fp_number_type b;
119990075Sobrien  FLO_union_type au, bu;
120018334Speter
120190075Sobrien  au.value = arg_a;
120290075Sobrien  bu.value = arg_b;
120318334Speter
120490075Sobrien  unpack_d (&au, &a);
120590075Sobrien  unpack_d (&bu, &b);
120690075Sobrien
120718334Speter  if (isnan (&a) || isnan (&b))
120818334Speter    return 1;			/* false, truth == 0 */
120918334Speter
121050397Sobrien  return __fpcmp_parts (&a, &b) ;
121118334Speter}
121290075Sobrien#endif /* L_eq_sf || L_eq_df */
121318334Speter
1214117395Skan#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
121518334SpeterCMPtype
121618334Speter_ne_f2 (FLO_type arg_a, FLO_type arg_b)
121718334Speter{
121818334Speter  fp_number_type a;
121918334Speter  fp_number_type b;
122090075Sobrien  FLO_union_type au, bu;
122118334Speter
122290075Sobrien  au.value = arg_a;
122390075Sobrien  bu.value = arg_b;
122418334Speter
122590075Sobrien  unpack_d (&au, &a);
122690075Sobrien  unpack_d (&bu, &b);
122790075Sobrien
122818334Speter  if (isnan (&a) || isnan (&b))
122918334Speter    return 1;			/* true, truth != 0 */
123018334Speter
123150397Sobrien  return  __fpcmp_parts (&a, &b) ;
123218334Speter}
123390075Sobrien#endif /* L_ne_sf || L_ne_df */
123418334Speter
1235117395Skan#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
123618334SpeterCMPtype
123718334Speter_gt_f2 (FLO_type arg_a, FLO_type arg_b)
123818334Speter{
123918334Speter  fp_number_type a;
124018334Speter  fp_number_type b;
124190075Sobrien  FLO_union_type au, bu;
124218334Speter
124390075Sobrien  au.value = arg_a;
124490075Sobrien  bu.value = arg_b;
124518334Speter
124690075Sobrien  unpack_d (&au, &a);
124790075Sobrien  unpack_d (&bu, &b);
124890075Sobrien
124918334Speter  if (isnan (&a) || isnan (&b))
125018334Speter    return -1;			/* false, truth > 0 */
125118334Speter
125250397Sobrien  return __fpcmp_parts (&a, &b);
125318334Speter}
125490075Sobrien#endif /* L_gt_sf || L_gt_df */
125518334Speter
1256117395Skan#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
125718334SpeterCMPtype
125818334Speter_ge_f2 (FLO_type arg_a, FLO_type arg_b)
125918334Speter{
126018334Speter  fp_number_type a;
126118334Speter  fp_number_type b;
126290075Sobrien  FLO_union_type au, bu;
126318334Speter
126490075Sobrien  au.value = arg_a;
126590075Sobrien  bu.value = arg_b;
126618334Speter
126790075Sobrien  unpack_d (&au, &a);
126890075Sobrien  unpack_d (&bu, &b);
126990075Sobrien
127018334Speter  if (isnan (&a) || isnan (&b))
127118334Speter    return -1;			/* false, truth >= 0 */
127250397Sobrien  return __fpcmp_parts (&a, &b) ;
127318334Speter}
127490075Sobrien#endif /* L_ge_sf || L_ge_df */
127518334Speter
1276117395Skan#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
127718334SpeterCMPtype
127818334Speter_lt_f2 (FLO_type arg_a, FLO_type arg_b)
127918334Speter{
128018334Speter  fp_number_type a;
128118334Speter  fp_number_type b;
128290075Sobrien  FLO_union_type au, bu;
128318334Speter
128490075Sobrien  au.value = arg_a;
128590075Sobrien  bu.value = arg_b;
128618334Speter
128790075Sobrien  unpack_d (&au, &a);
128890075Sobrien  unpack_d (&bu, &b);
128990075Sobrien
129018334Speter  if (isnan (&a) || isnan (&b))
129118334Speter    return 1;			/* false, truth < 0 */
129218334Speter
129350397Sobrien  return __fpcmp_parts (&a, &b);
129418334Speter}
129590075Sobrien#endif /* L_lt_sf || L_lt_df */
129618334Speter
1297117395Skan#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
129818334SpeterCMPtype
129918334Speter_le_f2 (FLO_type arg_a, FLO_type arg_b)
130018334Speter{
130118334Speter  fp_number_type a;
130218334Speter  fp_number_type b;
130390075Sobrien  FLO_union_type au, bu;
130418334Speter
130590075Sobrien  au.value = arg_a;
130690075Sobrien  bu.value = arg_b;
130718334Speter
130890075Sobrien  unpack_d (&au, &a);
130990075Sobrien  unpack_d (&bu, &b);
131090075Sobrien
131118334Speter  if (isnan (&a) || isnan (&b))
131218334Speter    return 1;			/* false, truth <= 0 */
131318334Speter
131450397Sobrien  return __fpcmp_parts (&a, &b) ;
131518334Speter}
131690075Sobrien#endif /* L_le_sf || L_le_df */
131718334Speter
1318117395Skan#endif /* ! US_SOFTWARE_GOFAST */
1319117395Skan
1320117395Skan#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
132190075SobrienCMPtype
132290075Sobrien_unord_f2 (FLO_type arg_a, FLO_type arg_b)
132390075Sobrien{
132490075Sobrien  fp_number_type a;
132590075Sobrien  fp_number_type b;
132690075Sobrien  FLO_union_type au, bu;
132790075Sobrien
132890075Sobrien  au.value = arg_a;
132990075Sobrien  bu.value = arg_b;
133090075Sobrien
133190075Sobrien  unpack_d (&au, &a);
133290075Sobrien  unpack_d (&bu, &b);
133390075Sobrien
133490075Sobrien  return (isnan (&a) || isnan (&b));
133590075Sobrien}
133690075Sobrien#endif /* L_unord_sf || L_unord_df */
133790075Sobrien
1338117395Skan#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
133918334SpeterFLO_type
134018334Spetersi_to_float (SItype arg_a)
134118334Speter{
134218334Speter  fp_number_type in;
134318334Speter
134418334Speter  in.class = CLASS_NUMBER;
134518334Speter  in.sign = arg_a < 0;
134618334Speter  if (!arg_a)
134718334Speter    {
134818334Speter      in.class = CLASS_ZERO;
134918334Speter    }
135018334Speter  else
135118334Speter    {
1352169689Skan      USItype uarg;
1353169689Skan      int shift;
135418334Speter      in.normal_exp = FRACBITS + NGARDS;
135518334Speter      if (in.sign)
135618334Speter	{
135718334Speter	  /* Special case for minint, since there is no +ve integer
135818334Speter	     representation for it */
135990075Sobrien	  if (arg_a == (- MAX_SI_INT - 1))
136018334Speter	    {
136190075Sobrien	      return (FLO_type)(- MAX_SI_INT - 1);
136218334Speter	    }
1363169689Skan	  uarg = (-arg_a);
136418334Speter	}
136518334Speter      else
1366169689Skan	uarg = arg_a;
136718334Speter
1368169689Skan      in.fraction.ll = uarg;
1369169689Skan      shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
1370169689Skan      if (shift > 0)
137118334Speter	{
1372169689Skan	  in.fraction.ll <<= shift;
1373169689Skan	  in.normal_exp -= shift;
137418334Speter	}
137518334Speter    }
137618334Speter  return pack_d (&in);
137718334Speter}
137890075Sobrien#endif /* L_si_to_sf || L_si_to_df */
137990075Sobrien
1380117395Skan#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
138190075SobrienFLO_type
138290075Sobrienusi_to_float (USItype arg_a)
138390075Sobrien{
138490075Sobrien  fp_number_type in;
138590075Sobrien
138690075Sobrien  in.sign = 0;
138790075Sobrien  if (!arg_a)
138890075Sobrien    {
138990075Sobrien      in.class = CLASS_ZERO;
139090075Sobrien    }
139190075Sobrien  else
139290075Sobrien    {
1393169689Skan      int shift;
139490075Sobrien      in.class = CLASS_NUMBER;
139590075Sobrien      in.normal_exp = FRACBITS + NGARDS;
139690075Sobrien      in.fraction.ll = arg_a;
139790075Sobrien
1398169689Skan      shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
1399169689Skan      if (shift < 0)
140090075Sobrien	{
1401169689Skan	  fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1);
1402169689Skan	  in.fraction.ll >>= -shift;
1403169689Skan	  in.fraction.ll |= (guard != 0);
1404169689Skan	  in.normal_exp -= shift;
140590075Sobrien	}
1406169689Skan      else if (shift > 0)
1407169689Skan	{
1408169689Skan	  in.fraction.ll <<= shift;
1409169689Skan	  in.normal_exp -= shift;
1410169689Skan	}
141190075Sobrien    }
141290075Sobrien  return pack_d (&in);
141390075Sobrien}
141450397Sobrien#endif
141518334Speter
1416117395Skan#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
141718334SpeterSItype
141818334Speterfloat_to_si (FLO_type arg_a)
141918334Speter{
142018334Speter  fp_number_type a;
142118334Speter  SItype tmp;
142290075Sobrien  FLO_union_type au;
142318334Speter
142490075Sobrien  au.value = arg_a;
142590075Sobrien  unpack_d (&au, &a);
142690075Sobrien
142718334Speter  if (iszero (&a))
142818334Speter    return 0;
142918334Speter  if (isnan (&a))
143018334Speter    return 0;
1431117395Skan  /* get reasonable MAX_SI_INT...  */
143218334Speter  if (isinf (&a))
143350397Sobrien    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
143418334Speter  /* it is a number, but a small one */
143518334Speter  if (a.normal_exp < 0)
143618334Speter    return 0;
143790075Sobrien  if (a.normal_exp > BITS_PER_SI - 2)
143818334Speter    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
143918334Speter  tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
144018334Speter  return a.sign ? (-tmp) : (tmp);
144118334Speter}
144290075Sobrien#endif /* L_sf_to_si || L_df_to_si */
144318334Speter
1444117395Skan#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
1445117395Skan#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
144618334Speter/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
144718334Speter   we also define them for GOFAST because the ones in libgcc2.c have the
144818334Speter   wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
144918334Speter   out of libgcc2.c.  We can't define these here if not GOFAST because then
145018334Speter   there'd be duplicate copies.  */
145118334Speter
145218334SpeterUSItype
145318334Speterfloat_to_usi (FLO_type arg_a)
145418334Speter{
145518334Speter  fp_number_type a;
145690075Sobrien  FLO_union_type au;
145718334Speter
145890075Sobrien  au.value = arg_a;
145990075Sobrien  unpack_d (&au, &a);
146090075Sobrien
146118334Speter  if (iszero (&a))
146218334Speter    return 0;
146318334Speter  if (isnan (&a))
146418334Speter    return 0;
146518334Speter  /* it is a negative number */
146618334Speter  if (a.sign)
146718334Speter    return 0;
1468117395Skan  /* get reasonable MAX_USI_INT...  */
146950397Sobrien  if (isinf (&a))
147050397Sobrien    return MAX_USI_INT;
147118334Speter  /* it is a number, but a small one */
147218334Speter  if (a.normal_exp < 0)
147318334Speter    return 0;
147490075Sobrien  if (a.normal_exp > BITS_PER_SI - 1)
147518334Speter    return MAX_USI_INT;
147618334Speter  else if (a.normal_exp > (FRACBITS + NGARDS))
147750397Sobrien    return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
147818334Speter  else
147918334Speter    return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
148018334Speter}
148190075Sobrien#endif /* US_SOFTWARE_GOFAST */
148290075Sobrien#endif /* L_sf_to_usi || L_df_to_usi */
148318334Speter
1484117395Skan#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
148518334SpeterFLO_type
148618334Speternegate (FLO_type arg_a)
148718334Speter{
148818334Speter  fp_number_type a;
148990075Sobrien  FLO_union_type au;
149018334Speter
149190075Sobrien  au.value = arg_a;
149290075Sobrien  unpack_d (&au, &a);
149390075Sobrien
149418334Speter  flip_sign (&a);
149518334Speter  return pack_d (&a);
149618334Speter}
149790075Sobrien#endif /* L_negate_sf || L_negate_df */
149818334Speter
149918334Speter#ifdef FLOAT
150018334Speter
150150397Sobrien#if defined(L_make_sf)
150218334SpeterSFtype
150318334Speter__make_fp(fp_class_type class,
150418334Speter	     unsigned int sign,
150518334Speter	     int exp,
150618334Speter	     USItype frac)
150718334Speter{
150818334Speter  fp_number_type in;
150918334Speter
151018334Speter  in.class = class;
151118334Speter  in.sign = sign;
151218334Speter  in.normal_exp = exp;
151318334Speter  in.fraction.ll = frac;
151418334Speter  return pack_d (&in);
151518334Speter}
151690075Sobrien#endif /* L_make_sf */
151718334Speter
151818334Speter#ifndef FLOAT_ONLY
151918334Speter
152018334Speter/* This enables one to build an fp library that supports float but not double.
152118334Speter   Otherwise, we would get an undefined reference to __make_dp.
152218334Speter   This is needed for some 8-bit ports that can't handle well values that
152318334Speter   are 8-bytes in size, so we just don't support double for them at all.  */
152418334Speter
152550397Sobrien#if defined(L_sf_to_df)
152618334SpeterDFtype
152718334Spetersf_to_df (SFtype arg_a)
152818334Speter{
152918334Speter  fp_number_type in;
153090075Sobrien  FLO_union_type au;
153118334Speter
153290075Sobrien  au.value = arg_a;
153390075Sobrien  unpack_d (&au, &in);
153490075Sobrien
153518334Speter  return __make_dp (in.class, in.sign, in.normal_exp,
153618334Speter		    ((UDItype) in.fraction.ll) << F_D_BITOFF);
153718334Speter}
153890075Sobrien#endif /* L_sf_to_df */
153918334Speter
1540117395Skan#if defined(L_sf_to_tf) && defined(TMODES)
1541117395SkanTFtype
1542117395Skansf_to_tf (SFtype arg_a)
1543117395Skan{
1544117395Skan  fp_number_type in;
1545117395Skan  FLO_union_type au;
1546117395Skan
1547117395Skan  au.value = arg_a;
1548117395Skan  unpack_d (&au, &in);
1549117395Skan
1550117395Skan  return __make_tp (in.class, in.sign, in.normal_exp,
1551117395Skan		    ((UTItype) in.fraction.ll) << F_T_BITOFF);
1552117395Skan}
1553117395Skan#endif /* L_sf_to_df */
1554117395Skan
155590075Sobrien#endif /* ! FLOAT_ONLY */
155690075Sobrien#endif /* FLOAT */
155718334Speter
155818334Speter#ifndef FLOAT
155918334Speter
156018334Speterextern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
156118334Speter
156250397Sobrien#if defined(L_make_df)
156318334SpeterDFtype
156418334Speter__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
156518334Speter{
156618334Speter  fp_number_type in;
156718334Speter
156818334Speter  in.class = class;
156918334Speter  in.sign = sign;
157018334Speter  in.normal_exp = exp;
157118334Speter  in.fraction.ll = frac;
157218334Speter  return pack_d (&in);
157318334Speter}
157490075Sobrien#endif /* L_make_df */
157518334Speter
157650397Sobrien#if defined(L_df_to_sf)
157718334SpeterSFtype
157818334Speterdf_to_sf (DFtype arg_a)
157918334Speter{
158018334Speter  fp_number_type in;
158150397Sobrien  USItype sffrac;
158290075Sobrien  FLO_union_type au;
158318334Speter
158490075Sobrien  au.value = arg_a;
158590075Sobrien  unpack_d (&au, &in);
158650397Sobrien
158750397Sobrien  sffrac = in.fraction.ll >> F_D_BITOFF;
158850397Sobrien
158950397Sobrien  /* We set the lowest guard bit in SFFRAC if we discarded any non
159050397Sobrien     zero bits.  */
159150397Sobrien  if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
159250397Sobrien    sffrac |= 1;
159350397Sobrien
159450397Sobrien  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
159518334Speter}
159690075Sobrien#endif /* L_df_to_sf */
159718334Speter
1598117395Skan#if defined(L_df_to_tf) && defined(TMODES) \
1599117395Skan    && !defined(FLOAT) && !defined(TFLOAT)
1600117395SkanTFtype
1601117395Skandf_to_tf (DFtype arg_a)
1602117395Skan{
1603117395Skan  fp_number_type in;
1604117395Skan  FLO_union_type au;
1605117395Skan
1606117395Skan  au.value = arg_a;
1607117395Skan  unpack_d (&au, &in);
1608117395Skan
1609117395Skan  return __make_tp (in.class, in.sign, in.normal_exp,
1610117395Skan		    ((UTItype) in.fraction.ll) << D_T_BITOFF);
1611117395Skan}
1612117395Skan#endif /* L_sf_to_df */
1613117395Skan
1614117395Skan#ifdef TFLOAT
1615117395Skan#if defined(L_make_tf)
1616117395SkanTFtype
1617117395Skan__make_tp(fp_class_type class,
1618117395Skan	     unsigned int sign,
1619117395Skan	     int exp,
1620117395Skan	     UTItype frac)
1621117395Skan{
1622117395Skan  fp_number_type in;
1623117395Skan
1624117395Skan  in.class = class;
1625117395Skan  in.sign = sign;
1626117395Skan  in.normal_exp = exp;
1627117395Skan  in.fraction.ll = frac;
1628117395Skan  return pack_d (&in);
1629117395Skan}
1630117395Skan#endif /* L_make_tf */
1631117395Skan
1632117395Skan#if defined(L_tf_to_df)
1633117395SkanDFtype
1634117395Skantf_to_df (TFtype arg_a)
1635117395Skan{
1636117395Skan  fp_number_type in;
1637117395Skan  UDItype sffrac;
1638117395Skan  FLO_union_type au;
1639117395Skan
1640117395Skan  au.value = arg_a;
1641117395Skan  unpack_d (&au, &in);
1642117395Skan
1643117395Skan  sffrac = in.fraction.ll >> D_T_BITOFF;
1644117395Skan
1645117395Skan  /* We set the lowest guard bit in SFFRAC if we discarded any non
1646117395Skan     zero bits.  */
1647117395Skan  if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
1648117395Skan    sffrac |= 1;
1649117395Skan
1650117395Skan  return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
1651117395Skan}
1652117395Skan#endif /* L_tf_to_df */
1653117395Skan
1654117395Skan#if defined(L_tf_to_sf)
1655117395SkanSFtype
1656117395Skantf_to_sf (TFtype arg_a)
1657117395Skan{
1658117395Skan  fp_number_type in;
1659117395Skan  USItype sffrac;
1660117395Skan  FLO_union_type au;
1661117395Skan
1662117395Skan  au.value = arg_a;
1663117395Skan  unpack_d (&au, &in);
1664117395Skan
1665117395Skan  sffrac = in.fraction.ll >> F_T_BITOFF;
1666117395Skan
1667117395Skan  /* We set the lowest guard bit in SFFRAC if we discarded any non
1668117395Skan     zero bits.  */
1669117395Skan  if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
1670117395Skan    sffrac |= 1;
1671117395Skan
1672117395Skan  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
1673117395Skan}
1674117395Skan#endif /* L_tf_to_sf */
1675117395Skan#endif /* TFLOAT */
1676117395Skan
167790075Sobrien#endif /* ! FLOAT */
167850397Sobrien#endif /* !EXTENDED_FLOAT_STUBS */
1679