Back to index

cell-binutils  2.17cvs20070401
atof-ieee.c
Go to the documentation of this file.
00001 /* atof_ieee.c - turn a Flonum into an IEEE floating point number
00002    Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2005
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of GAS, the GNU Assembler.
00006 
00007    GAS is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2, or (at your option)
00010    any later version.
00011 
00012    GAS is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with GAS; see the file COPYING.  If not, write to the Free
00019    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00020    02110-1301, USA.  */
00021 
00022 #include "as.h"
00023 
00024 /* Flonums returned here.  */
00025 extern FLONUM_TYPE generic_floating_point_number;
00026 
00027 extern const char EXP_CHARS[];
00028 /* Precision in LittleNums.  */
00029 /* Don't count the gap in the m68k extended precision format.  */
00030 #define MAX_PRECISION  5
00031 #define F_PRECISION    2
00032 #define D_PRECISION    4
00033 #define X_PRECISION    5
00034 #define P_PRECISION    5
00035 
00036 /* Length in LittleNums of guard bits.  */
00037 #define GUARD          2
00038 
00039 #ifndef TC_LARGEST_EXPONENT_IS_NORMAL
00040 #define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) 0
00041 #endif
00042 
00043 static const unsigned long mask[] =
00044 {
00045   0x00000000,
00046   0x00000001,
00047   0x00000003,
00048   0x00000007,
00049   0x0000000f,
00050   0x0000001f,
00051   0x0000003f,
00052   0x0000007f,
00053   0x000000ff,
00054   0x000001ff,
00055   0x000003ff,
00056   0x000007ff,
00057   0x00000fff,
00058   0x00001fff,
00059   0x00003fff,
00060   0x00007fff,
00061   0x0000ffff,
00062   0x0001ffff,
00063   0x0003ffff,
00064   0x0007ffff,
00065   0x000fffff,
00066   0x001fffff,
00067   0x003fffff,
00068   0x007fffff,
00069   0x00ffffff,
00070   0x01ffffff,
00071   0x03ffffff,
00072   0x07ffffff,
00073   0x0fffffff,
00074   0x1fffffff,
00075   0x3fffffff,
00076   0x7fffffff,
00077   0xffffffff,
00078 };
00079 
00080 static int bits_left_in_littlenum;
00081 static int littlenums_left;
00082 static LITTLENUM_TYPE *littlenum_pointer;
00083 
00084 static int
00085 next_bits (int number_of_bits)
00086 {
00087   int return_value;
00088 
00089   if (!littlenums_left)
00090     return 0;
00091 
00092   if (number_of_bits >= bits_left_in_littlenum)
00093     {
00094       return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
00095       number_of_bits -= bits_left_in_littlenum;
00096       return_value <<= number_of_bits;
00097 
00098       if (--littlenums_left)
00099        {
00100          bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
00101          --littlenum_pointer;
00102          return_value |=
00103            (*littlenum_pointer >> bits_left_in_littlenum)
00104            & mask[number_of_bits];
00105        }
00106     }
00107   else
00108     {
00109       bits_left_in_littlenum -= number_of_bits;
00110       return_value =
00111        mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
00112     }
00113   return return_value;
00114 }
00115 
00116 /* Num had better be less than LITTLENUM_NUMBER_OF_BITS.  */
00117 
00118 static void
00119 unget_bits (int num)
00120 {
00121   if (!littlenums_left)
00122     {
00123       ++littlenum_pointer;
00124       ++littlenums_left;
00125       bits_left_in_littlenum = num;
00126     }
00127   else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
00128     {
00129       bits_left_in_littlenum =
00130        num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
00131       ++littlenum_pointer;
00132       ++littlenums_left;
00133     }
00134   else
00135     bits_left_in_littlenum += num;
00136 }
00137 
00138 static void
00139 make_invalid_floating_point_number (LITTLENUM_TYPE *words)
00140 {
00141   as_bad (_("cannot create floating-point number"));
00142   /* Zero the leftmost bit.  */
00143   words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1;
00144   words[1] = (LITTLENUM_TYPE) -1;
00145   words[2] = (LITTLENUM_TYPE) -1;
00146   words[3] = (LITTLENUM_TYPE) -1;
00147   words[4] = (LITTLENUM_TYPE) -1;
00148   words[5] = (LITTLENUM_TYPE) -1;
00149 }
00150 
00151 /* Warning: This returns 16-bit LITTLENUMs.  It is up to the caller to
00152    figure out any alignment problems and to conspire for the
00153    bytes/word to be emitted in the right order.  Bigendians beware!  */
00154 
00155 /* Note that atof-ieee always has X and P precisions enabled.  it is up
00156    to md_atof to filter them out if the target machine does not support
00157    them.  */
00158 
00159 /* Returns pointer past text consumed.  */
00160 
00161 char *
00162 atof_ieee (char *str,                     /* Text to convert to binary.  */
00163           int what_kind,           /* 'd', 'f', 'g', 'h'.  */
00164           LITTLENUM_TYPE *words)   /* Build the binary here.  */
00165 {
00166   /* Extra bits for zeroed low-order bits.
00167      The 1st MAX_PRECISION are zeroed, the last contain flonum bits.  */
00168   static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
00169   char *return_value;
00170   /* Number of 16-bit words in the format.  */
00171   int precision;
00172   long exponent_bits;
00173   FLONUM_TYPE save_gen_flonum;
00174 
00175   /* We have to save the generic_floating_point_number because it
00176      contains storage allocation about the array of LITTLENUMs where
00177      the value is actually stored.  We will allocate our own array of
00178      littlenums below, but have to restore the global one on exit.  */
00179   save_gen_flonum = generic_floating_point_number;
00180 
00181   return_value = str;
00182   generic_floating_point_number.low = bits + MAX_PRECISION;
00183   generic_floating_point_number.high = NULL;
00184   generic_floating_point_number.leader = NULL;
00185   generic_floating_point_number.exponent = 0;
00186   generic_floating_point_number.sign = '\0';
00187 
00188   /* Use more LittleNums than seems necessary: the highest flonum may
00189      have 15 leading 0 bits, so could be useless.  */
00190 
00191   memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
00192 
00193   switch (what_kind)
00194     {
00195     case 'f':
00196     case 'F':
00197     case 's':
00198     case 'S':
00199       precision = F_PRECISION;
00200       exponent_bits = 8;
00201       break;
00202 
00203     case 'd':
00204     case 'D':
00205     case 'r':
00206     case 'R':
00207       precision = D_PRECISION;
00208       exponent_bits = 11;
00209       break;
00210 
00211     case 'x':
00212     case 'X':
00213     case 'e':
00214     case 'E':
00215       precision = X_PRECISION;
00216       exponent_bits = 15;
00217       break;
00218 
00219     case 'p':
00220     case 'P':
00221 
00222       precision = P_PRECISION;
00223       exponent_bits = -1;
00224       break;
00225 
00226     default:
00227       make_invalid_floating_point_number (words);
00228       return (NULL);
00229     }
00230 
00231   generic_floating_point_number.high
00232     = generic_floating_point_number.low + precision - 1 + GUARD;
00233 
00234   if (atof_generic (&return_value, ".", EXP_CHARS,
00235                   &generic_floating_point_number))
00236     {
00237       make_invalid_floating_point_number (words);
00238       return NULL;
00239     }
00240   gen_to_words (words, precision, exponent_bits);
00241 
00242   /* Restore the generic_floating_point_number's storage alloc (and
00243      everything else).  */
00244   generic_floating_point_number = save_gen_flonum;
00245 
00246   return return_value;
00247 }
00248 
00249 /* Turn generic_floating_point_number into a real float/double/extended.  */
00250 
00251 int
00252 gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
00253 {
00254   int return_value = 0;
00255 
00256   long exponent_1;
00257   long exponent_2;
00258   long exponent_3;
00259   long exponent_4;
00260   int exponent_skippage;
00261   LITTLENUM_TYPE word1;
00262   LITTLENUM_TYPE *lp;
00263   LITTLENUM_TYPE *words_end;
00264 
00265   words_end = words + precision;
00266 #ifdef TC_M68K
00267   if (precision == X_PRECISION)
00268     /* On the m68k the extended precision format has a gap of 16 bits
00269        between the exponent and the mantissa.  */
00270     words_end++;
00271 #endif
00272 
00273   if (generic_floating_point_number.low > generic_floating_point_number.leader)
00274     {
00275       /* 0.0e0 seen.  */
00276       if (generic_floating_point_number.sign == '+')
00277        words[0] = 0x0000;
00278       else
00279        words[0] = 0x8000;
00280       memset (&words[1], '\0',
00281              (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
00282       return return_value;
00283     }
00284 
00285   /* NaN:  Do the right thing.  */
00286   if (generic_floating_point_number.sign == 0)
00287     {
00288       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
00289        as_warn ("NaNs are not supported by this target\n");
00290       if (precision == F_PRECISION)
00291        {
00292          words[0] = 0x7fff;
00293          words[1] = 0xffff;
00294        }
00295       else if (precision == X_PRECISION)
00296        {
00297 #ifdef TC_M68K
00298          words[0] = 0x7fff;
00299          words[1] = 0;
00300          words[2] = 0xffff;
00301          words[3] = 0xffff;
00302          words[4] = 0xffff;
00303          words[5] = 0xffff;
00304 #else /* ! TC_M68K  */
00305 #ifdef TC_I386
00306          words[0] = 0xffff;
00307          words[1] = 0xc000;
00308          words[2] = 0;
00309          words[3] = 0;
00310          words[4] = 0;
00311 #else /* ! TC_I386  */
00312          abort ();
00313 #endif /* ! TC_I386  */
00314 #endif /* ! TC_M68K  */
00315        }
00316       else
00317        {
00318          words[0] = 0x7fff;
00319          words[1] = 0xffff;
00320          words[2] = 0xffff;
00321          words[3] = 0xffff;
00322        }
00323       return return_value;
00324     }
00325   else if (generic_floating_point_number.sign == 'P')
00326     {
00327       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
00328        as_warn ("Infinities are not supported by this target\n");
00329 
00330       /* +INF:  Do the right thing.  */
00331       if (precision == F_PRECISION)
00332        {
00333          words[0] = 0x7f80;
00334          words[1] = 0;
00335        }
00336       else if (precision == X_PRECISION)
00337        {
00338 #ifdef TC_M68K
00339          words[0] = 0x7fff;
00340          words[1] = 0;
00341          words[2] = 0;
00342          words[3] = 0;
00343          words[4] = 0;
00344          words[5] = 0;
00345 #else /* ! TC_M68K  */
00346 #ifdef TC_I386
00347          words[0] = 0x7fff;
00348          words[1] = 0x8000;
00349          words[2] = 0;
00350          words[3] = 0;
00351          words[4] = 0;
00352 #else /* ! TC_I386  */
00353          abort ();
00354 #endif /* ! TC_I386  */
00355 #endif /* ! TC_M68K  */
00356        }
00357       else
00358        {
00359          words[0] = 0x7ff0;
00360          words[1] = 0;
00361          words[2] = 0;
00362          words[3] = 0;
00363        }
00364       return return_value;
00365     }
00366   else if (generic_floating_point_number.sign == 'N')
00367     {
00368       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
00369        as_warn ("Infinities are not supported by this target\n");
00370 
00371       /* Negative INF.  */
00372       if (precision == F_PRECISION)
00373        {
00374          words[0] = 0xff80;
00375          words[1] = 0x0;
00376        }
00377       else if (precision == X_PRECISION)
00378        {
00379 #ifdef TC_M68K
00380          words[0] = 0xffff;
00381          words[1] = 0;
00382          words[2] = 0;
00383          words[3] = 0;
00384          words[4] = 0;
00385          words[5] = 0;
00386 #else /* ! TC_M68K  */
00387 #ifdef TC_I386
00388          words[0] = 0xffff;
00389          words[1] = 0x8000;
00390          words[2] = 0;
00391          words[3] = 0;
00392          words[4] = 0;
00393 #else /* ! TC_I386  */
00394          abort ();
00395 #endif /* ! TC_I386  */
00396 #endif /* ! TC_M68K  */
00397        }
00398       else
00399        {
00400          words[0] = 0xfff0;
00401          words[1] = 0x0;
00402          words[2] = 0x0;
00403          words[3] = 0x0;
00404        }
00405       return return_value;
00406     }
00407 
00408   /* The floating point formats we support have:
00409      Bit 15 is sign bit.
00410      Bits 14:n are excess-whatever exponent.
00411      Bits n-1:0 (if any) are most significant bits of fraction.
00412      Bits 15:0 of the next word(s) are the next most significant bits.
00413 
00414      So we need: number of bits of exponent, number of bits of
00415      mantissa.  */
00416   bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
00417   littlenum_pointer = generic_floating_point_number.leader;
00418   littlenums_left = (1
00419                    + generic_floating_point_number.leader
00420                    - generic_floating_point_number.low);
00421 
00422   /* Seek (and forget) 1st significant bit.  */
00423   for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);;
00424   exponent_1 = (generic_floating_point_number.exponent
00425               + generic_floating_point_number.leader
00426               + 1
00427               - generic_floating_point_number.low);
00428 
00429   /* Radix LITTLENUM_RADIX, point just higher than
00430      generic_floating_point_number.leader.  */
00431   exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
00432 
00433   /* Radix 2.  */
00434   exponent_3 = exponent_2 - exponent_skippage;
00435 
00436   /* Forget leading zeros, forget 1st bit.  */
00437   exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
00438 
00439   /* Offset exponent.  */
00440   lp = words;
00441 
00442   /* Word 1.  Sign, exponent and perhaps high bits.  */
00443   word1 = ((generic_floating_point_number.sign == '+')
00444           ? 0
00445           : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
00446 
00447   /* Assume 2's complement integers.  */
00448   if (exponent_4 <= 0)
00449     {
00450       int prec_bits;
00451       int num_bits;
00452 
00453       unget_bits (1);
00454       num_bits = -exponent_4;
00455       prec_bits =
00456        LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
00457 #ifdef TC_I386
00458       if (precision == X_PRECISION && exponent_bits == 15)
00459        {
00460          /* On the i386 a denormalized extended precision float is
00461             shifted down by one, effectively decreasing the exponent
00462             bias by one.  */
00463          prec_bits -= 1;
00464          num_bits += 1;
00465        }
00466 #endif
00467 
00468       if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
00469        {
00470          /* Bigger than one littlenum.  */
00471          num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
00472          *lp++ = word1;
00473          if (num_bits + exponent_bits + 1
00474              > precision * LITTLENUM_NUMBER_OF_BITS)
00475            {
00476              /* Exponent overflow.  */
00477              make_invalid_floating_point_number (words);
00478              return return_value;
00479            }
00480 #ifdef TC_M68K
00481          if (precision == X_PRECISION && exponent_bits == 15)
00482            *lp++ = 0;
00483 #endif
00484          while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
00485            {
00486              num_bits -= LITTLENUM_NUMBER_OF_BITS;
00487              *lp++ = 0;
00488            }
00489          if (num_bits)
00490            *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
00491        }
00492       else
00493        {
00494          if (precision == X_PRECISION && exponent_bits == 15)
00495            {
00496              *lp++ = word1;
00497 #ifdef TC_M68K
00498              *lp++ = 0;
00499 #endif
00500              *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
00501            }
00502          else
00503            {
00504              word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1)
00505                               - (exponent_bits + num_bits));
00506              *lp++ = word1;
00507            }
00508        }
00509       while (lp < words_end)
00510        *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
00511 
00512       /* Round the mantissa up, but don't change the number.  */
00513       if (next_bits (1))
00514        {
00515          --lp;
00516          if (prec_bits >= LITTLENUM_NUMBER_OF_BITS)
00517            {
00518              int n = 0;
00519              int tmp_bits;
00520 
00521              n = 0;
00522              tmp_bits = prec_bits;
00523              while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
00524               {
00525                 if (lp[n] != (LITTLENUM_TYPE) - 1)
00526                   break;
00527                 --n;
00528                 tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
00529               }
00530              if (tmp_bits > LITTLENUM_NUMBER_OF_BITS
00531                 || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]
00532                 || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS
00533                                 - exponent_bits - 1)
00534 #ifdef TC_I386
00535                     /* An extended precision float with only the integer
00536                       bit set would be invalid.  That must be converted
00537                       to the smallest normalized number.  */
00538                     && !(precision == X_PRECISION
00539                         && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS
00540                                        - exponent_bits - 2))
00541 #endif
00542                     ))
00543               {
00544                 unsigned long carry;
00545 
00546                 for (carry = 1; carry && (lp >= words); lp--)
00547                   {
00548                     carry = *lp + carry;
00549                     *lp = carry;
00550                     carry >>= LITTLENUM_NUMBER_OF_BITS;
00551                   }
00552               }
00553              else
00554               {
00555                 /* This is an overflow of the denormal numbers.  We
00556                      need to forget what we have produced, and instead
00557                      generate the smallest normalized number.  */
00558                 lp = words;
00559                 word1 = ((generic_floating_point_number.sign == '+')
00560                         ? 0
00561                         : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
00562                 word1 |= (1
00563                          << ((LITTLENUM_NUMBER_OF_BITS - 1)
00564                             - exponent_bits));
00565                 *lp++ = word1;
00566 #ifdef TC_I386
00567                 /* Set the integer bit in the extended precision format.
00568                    This cannot happen on the m68k where the mantissa
00569                    just overflows into the integer bit above.  */
00570                 if (precision == X_PRECISION)
00571                   *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
00572 #endif
00573                 while (lp < words_end)
00574                   *lp++ = 0;
00575               }
00576            }
00577          else
00578            *lp += 1;
00579        }
00580 
00581       return return_value;
00582     }
00583   else if ((unsigned long) exponent_4 > mask[exponent_bits]
00584           || (! TC_LARGEST_EXPONENT_IS_NORMAL (precision)
00585               && (unsigned long) exponent_4 == mask[exponent_bits]))
00586     {
00587       /* Exponent overflow.  Lose immediately.  */
00588 
00589       /* We leave return_value alone: admit we read the
00590         number, but return a floating exception
00591         because we can't encode the number.  */
00592       make_invalid_floating_point_number (words);
00593       return return_value;
00594     }
00595   else
00596     {
00597       word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
00598        | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
00599     }
00600 
00601   *lp++ = word1;
00602 
00603   /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
00604      middle.  Either way, it is then followed by a 1 bit.  */
00605   if (exponent_bits == 15 && precision == X_PRECISION)
00606     {
00607 #ifdef TC_M68K
00608       *lp++ = 0;
00609 #endif
00610       *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
00611               | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
00612     }
00613 
00614   /* The rest of the words are just mantissa bits.  */
00615   while (lp < words_end)
00616     *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
00617 
00618   if (next_bits (1))
00619     {
00620       unsigned long carry;
00621       /* Since the NEXT bit is a 1, round UP the mantissa.
00622         The cunning design of these hidden-1 floats permits
00623         us to let the mantissa overflow into the exponent, and
00624         it 'does the right thing'. However, we lose if the
00625         highest-order bit of the lowest-order word flips.
00626         Is that clear?  */
00627 
00628       /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
00629         Please allow at least 1 more bit in carry than is in a LITTLENUM.
00630         We need that extra bit to hold a carry during a LITTLENUM carry
00631         propagation. Another extra bit (kept 0) will assure us that we
00632         don't get a sticky sign bit after shifting right, and that
00633         permits us to propagate the carry without any masking of bits.
00634         #endif */
00635       for (carry = 1, lp--; carry; lp--)
00636        {
00637          carry = *lp + carry;
00638          *lp = carry;
00639          carry >>= LITTLENUM_NUMBER_OF_BITS;
00640          if (lp == words)
00641            break;
00642        }
00643       if (precision == X_PRECISION && exponent_bits == 15)
00644        {
00645          /* Extended precision numbers have an explicit integer bit
00646             that we may have to restore.  */
00647          if (lp == words)
00648            {
00649 #ifdef TC_M68K
00650              /* On the m68k there is a gap of 16 bits.  We must
00651                explicitly propagate the carry into the exponent.  */
00652              words[0] += words[1];
00653              words[1] = 0;
00654              lp++;
00655 #endif
00656              /* Put back the integer bit.  */
00657              lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
00658            }
00659        }
00660       if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
00661        {
00662          /* We leave return_value alone: admit we read the number,
00663             but return a floating exception because we can't encode
00664             the number.  */
00665          *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
00666        }
00667     }
00668   return return_value;
00669 }
00670 
00671 #ifdef TEST
00672 char *
00673 print_gen (gen)
00674      FLONUM_TYPE *gen;
00675 {
00676   FLONUM_TYPE f;
00677   LITTLENUM_TYPE arr[10];
00678   double dv;
00679   float fv;
00680   static char sbuf[40];
00681 
00682   if (gen)
00683     {
00684       f = generic_floating_point_number;
00685       generic_floating_point_number = *gen;
00686     }
00687   gen_to_words (&arr[0], 4, 11);
00688   memcpy (&dv, &arr[0], sizeof (double));
00689   sprintf (sbuf, "%x %x %x %x %.14G   ", arr[0], arr[1], arr[2], arr[3], dv);
00690   gen_to_words (&arr[0], 2, 8);
00691   memcpy (&fv, &arr[0], sizeof (float));
00692   sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
00693 
00694   if (gen)
00695     generic_floating_point_number = f;
00696 
00697   return (sbuf);
00698 }
00699 
00700 #endif