xref: /NextBSD/contrib/binutils/gas/config/atof-ieee.c (revision 5e568154a01fb6be74908baed265f265a56f002f)
1 /* atof_ieee.c - turn a Flonum into an IEEE floating point number
2    Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2005
3    Free Software Foundation, Inc.
4 
5    This file is part of GAS, the GNU Assembler.
6 
7    GAS is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11 
12    GAS is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with GAS; see the file COPYING.  If not, write to the Free
19    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, USA.  */
21 
22 #include "as.h"
23 
24 /* Flonums returned here.  */
25 extern FLONUM_TYPE generic_floating_point_number;
26 
27 extern const char EXP_CHARS[];
28 /* Precision in LittleNums.  */
29 /* Don't count the gap in the m68k extended precision format.  */
30 #define MAX_PRECISION  5
31 #define F_PRECISION    2
32 #define D_PRECISION    4
33 #define X_PRECISION    5
34 #define P_PRECISION    5
35 
36 /* Length in LittleNums of guard bits.  */
37 #define GUARD          2
38 
39 #ifndef TC_LARGEST_EXPONENT_IS_NORMAL
40 #define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) 0
41 #endif
42 
43 static const unsigned long mask[] =
44 {
45   0x00000000,
46   0x00000001,
47   0x00000003,
48   0x00000007,
49   0x0000000f,
50   0x0000001f,
51   0x0000003f,
52   0x0000007f,
53   0x000000ff,
54   0x000001ff,
55   0x000003ff,
56   0x000007ff,
57   0x00000fff,
58   0x00001fff,
59   0x00003fff,
60   0x00007fff,
61   0x0000ffff,
62   0x0001ffff,
63   0x0003ffff,
64   0x0007ffff,
65   0x000fffff,
66   0x001fffff,
67   0x003fffff,
68   0x007fffff,
69   0x00ffffff,
70   0x01ffffff,
71   0x03ffffff,
72   0x07ffffff,
73   0x0fffffff,
74   0x1fffffff,
75   0x3fffffff,
76   0x7fffffff,
77   0xffffffff,
78 };
79 
80 static int bits_left_in_littlenum;
81 static int littlenums_left;
82 static LITTLENUM_TYPE *littlenum_pointer;
83 
84 static int
next_bits(int number_of_bits)85 next_bits (int number_of_bits)
86 {
87   int return_value;
88 
89   if (!littlenums_left)
90     return 0;
91 
92   if (number_of_bits >= bits_left_in_littlenum)
93     {
94       return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
95       number_of_bits -= bits_left_in_littlenum;
96       return_value <<= number_of_bits;
97 
98       if (--littlenums_left)
99 	{
100 	  bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
101 	  --littlenum_pointer;
102 	  return_value |=
103 	    (*littlenum_pointer >> bits_left_in_littlenum)
104 	    & mask[number_of_bits];
105 	}
106     }
107   else
108     {
109       bits_left_in_littlenum -= number_of_bits;
110       return_value =
111 	mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
112     }
113   return return_value;
114 }
115 
116 /* Num had better be less than LITTLENUM_NUMBER_OF_BITS.  */
117 
118 static void
unget_bits(int num)119 unget_bits (int num)
120 {
121   if (!littlenums_left)
122     {
123       ++littlenum_pointer;
124       ++littlenums_left;
125       bits_left_in_littlenum = num;
126     }
127   else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
128     {
129       bits_left_in_littlenum =
130 	num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
131       ++littlenum_pointer;
132       ++littlenums_left;
133     }
134   else
135     bits_left_in_littlenum += num;
136 }
137 
138 static void
make_invalid_floating_point_number(LITTLENUM_TYPE * words)139 make_invalid_floating_point_number (LITTLENUM_TYPE *words)
140 {
141   as_bad (_("cannot create floating-point number"));
142   /* Zero the leftmost bit.  */
143   words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1;
144   words[1] = (LITTLENUM_TYPE) -1;
145   words[2] = (LITTLENUM_TYPE) -1;
146   words[3] = (LITTLENUM_TYPE) -1;
147   words[4] = (LITTLENUM_TYPE) -1;
148   words[5] = (LITTLENUM_TYPE) -1;
149 }
150 
151 /* Warning: This returns 16-bit LITTLENUMs.  It is up to the caller to
152    figure out any alignment problems and to conspire for the
153    bytes/word to be emitted in the right order.  Bigendians beware!  */
154 
155 /* Note that atof-ieee always has X and P precisions enabled.  it is up
156    to md_atof to filter them out if the target machine does not support
157    them.  */
158 
159 /* Returns pointer past text consumed.  */
160 
161 char *
atof_ieee(char * str,int what_kind,LITTLENUM_TYPE * words)162 atof_ieee (char *str,			/* Text to convert to binary.  */
163 	   int what_kind,		/* 'd', 'f', 'g', 'h'.  */
164 	   LITTLENUM_TYPE *words)	/* Build the binary here.  */
165 {
166   /* Extra bits for zeroed low-order bits.
167      The 1st MAX_PRECISION are zeroed, the last contain flonum bits.  */
168   static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
169   char *return_value;
170   /* Number of 16-bit words in the format.  */
171   int precision;
172   long exponent_bits;
173   FLONUM_TYPE save_gen_flonum;
174 
175   /* We have to save the generic_floating_point_number because it
176      contains storage allocation about the array of LITTLENUMs where
177      the value is actually stored.  We will allocate our own array of
178      littlenums below, but have to restore the global one on exit.  */
179   save_gen_flonum = generic_floating_point_number;
180 
181   return_value = str;
182   generic_floating_point_number.low = bits + MAX_PRECISION;
183   generic_floating_point_number.high = NULL;
184   generic_floating_point_number.leader = NULL;
185   generic_floating_point_number.exponent = 0;
186   generic_floating_point_number.sign = '\0';
187 
188   /* Use more LittleNums than seems necessary: the highest flonum may
189      have 15 leading 0 bits, so could be useless.  */
190 
191   memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
192 
193   switch (what_kind)
194     {
195     case 'f':
196     case 'F':
197     case 's':
198     case 'S':
199       precision = F_PRECISION;
200       exponent_bits = 8;
201       break;
202 
203     case 'd':
204     case 'D':
205     case 'r':
206     case 'R':
207       precision = D_PRECISION;
208       exponent_bits = 11;
209       break;
210 
211     case 'x':
212     case 'X':
213     case 'e':
214     case 'E':
215       precision = X_PRECISION;
216       exponent_bits = 15;
217       break;
218 
219     case 'p':
220     case 'P':
221 
222       precision = P_PRECISION;
223       exponent_bits = -1;
224       break;
225 
226     default:
227       make_invalid_floating_point_number (words);
228       return (NULL);
229     }
230 
231   generic_floating_point_number.high
232     = generic_floating_point_number.low + precision - 1 + GUARD;
233 
234   if (atof_generic (&return_value, ".", EXP_CHARS,
235 		    &generic_floating_point_number))
236     {
237       make_invalid_floating_point_number (words);
238       return NULL;
239     }
240   gen_to_words (words, precision, exponent_bits);
241 
242   /* Restore the generic_floating_point_number's storage alloc (and
243      everything else).  */
244   generic_floating_point_number = save_gen_flonum;
245 
246   return return_value;
247 }
248 
249 /* Turn generic_floating_point_number into a real float/double/extended.  */
250 
251 int
gen_to_words(LITTLENUM_TYPE * words,int precision,long exponent_bits)252 gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
253 {
254   int return_value = 0;
255 
256   long exponent_1;
257   long exponent_2;
258   long exponent_3;
259   long exponent_4;
260   int exponent_skippage;
261   LITTLENUM_TYPE word1;
262   LITTLENUM_TYPE *lp;
263   LITTLENUM_TYPE *words_end;
264 
265   words_end = words + precision;
266 #ifdef TC_M68K
267   if (precision == X_PRECISION)
268     /* On the m68k the extended precision format has a gap of 16 bits
269        between the exponent and the mantissa.  */
270     words_end++;
271 #endif
272 
273   if (generic_floating_point_number.low > generic_floating_point_number.leader)
274     {
275       /* 0.0e0 seen.  */
276       if (generic_floating_point_number.sign == '+')
277 	words[0] = 0x0000;
278       else
279 	words[0] = 0x8000;
280       memset (&words[1], '\0',
281 	      (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
282       return return_value;
283     }
284 
285   /* NaN:  Do the right thing.  */
286   if (generic_floating_point_number.sign == 0)
287     {
288       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
289 	as_warn ("NaNs are not supported by this target\n");
290       if (precision == F_PRECISION)
291 	{
292 	  words[0] = 0x7fff;
293 	  words[1] = 0xffff;
294 	}
295       else if (precision == X_PRECISION)
296 	{
297 #ifdef TC_M68K
298 	  words[0] = 0x7fff;
299 	  words[1] = 0;
300 	  words[2] = 0xffff;
301 	  words[3] = 0xffff;
302 	  words[4] = 0xffff;
303 	  words[5] = 0xffff;
304 #else /* ! TC_M68K  */
305 #ifdef TC_I386
306 	  words[0] = 0xffff;
307 	  words[1] = 0xc000;
308 	  words[2] = 0;
309 	  words[3] = 0;
310 	  words[4] = 0;
311 #else /* ! TC_I386  */
312 	  abort ();
313 #endif /* ! TC_I386  */
314 #endif /* ! TC_M68K  */
315 	}
316       else
317 	{
318 	  words[0] = 0x7fff;
319 	  words[1] = 0xffff;
320 	  words[2] = 0xffff;
321 	  words[3] = 0xffff;
322 	}
323       return return_value;
324     }
325   else if (generic_floating_point_number.sign == 'P')
326     {
327       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
328 	as_warn ("Infinities are not supported by this target\n");
329 
330       /* +INF:  Do the right thing.  */
331       if (precision == F_PRECISION)
332 	{
333 	  words[0] = 0x7f80;
334 	  words[1] = 0;
335 	}
336       else if (precision == X_PRECISION)
337 	{
338 #ifdef TC_M68K
339 	  words[0] = 0x7fff;
340 	  words[1] = 0;
341 	  words[2] = 0;
342 	  words[3] = 0;
343 	  words[4] = 0;
344 	  words[5] = 0;
345 #else /* ! TC_M68K  */
346 #ifdef TC_I386
347 	  words[0] = 0x7fff;
348 	  words[1] = 0x8000;
349 	  words[2] = 0;
350 	  words[3] = 0;
351 	  words[4] = 0;
352 #else /* ! TC_I386  */
353 	  abort ();
354 #endif /* ! TC_I386  */
355 #endif /* ! TC_M68K  */
356 	}
357       else
358 	{
359 	  words[0] = 0x7ff0;
360 	  words[1] = 0;
361 	  words[2] = 0;
362 	  words[3] = 0;
363 	}
364       return return_value;
365     }
366   else if (generic_floating_point_number.sign == 'N')
367     {
368       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
369 	as_warn ("Infinities are not supported by this target\n");
370 
371       /* Negative INF.  */
372       if (precision == F_PRECISION)
373 	{
374 	  words[0] = 0xff80;
375 	  words[1] = 0x0;
376 	}
377       else if (precision == X_PRECISION)
378 	{
379 #ifdef TC_M68K
380 	  words[0] = 0xffff;
381 	  words[1] = 0;
382 	  words[2] = 0;
383 	  words[3] = 0;
384 	  words[4] = 0;
385 	  words[5] = 0;
386 #else /* ! TC_M68K  */
387 #ifdef TC_I386
388 	  words[0] = 0xffff;
389 	  words[1] = 0x8000;
390 	  words[2] = 0;
391 	  words[3] = 0;
392 	  words[4] = 0;
393 #else /* ! TC_I386  */
394 	  abort ();
395 #endif /* ! TC_I386  */
396 #endif /* ! TC_M68K  */
397 	}
398       else
399 	{
400 	  words[0] = 0xfff0;
401 	  words[1] = 0x0;
402 	  words[2] = 0x0;
403 	  words[3] = 0x0;
404 	}
405       return return_value;
406     }
407 
408   /* The floating point formats we support have:
409      Bit 15 is sign bit.
410      Bits 14:n are excess-whatever exponent.
411      Bits n-1:0 (if any) are most significant bits of fraction.
412      Bits 15:0 of the next word(s) are the next most significant bits.
413 
414      So we need: number of bits of exponent, number of bits of
415      mantissa.  */
416   bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
417   littlenum_pointer = generic_floating_point_number.leader;
418   littlenums_left = (1
419 		     + generic_floating_point_number.leader
420 		     - generic_floating_point_number.low);
421 
422   /* Seek (and forget) 1st significant bit.  */
423   for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage)
424 	;;
425   exponent_1 = (generic_floating_point_number.exponent
426 		+ generic_floating_point_number.leader
427 		+ 1
428 		- generic_floating_point_number.low);
429 
430   /* Radix LITTLENUM_RADIX, point just higher than
431      generic_floating_point_number.leader.  */
432   exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
433 
434   /* Radix 2.  */
435   exponent_3 = exponent_2 - exponent_skippage;
436 
437   /* Forget leading zeros, forget 1st bit.  */
438   exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
439 
440   /* Offset exponent.  */
441   lp = words;
442 
443   /* Word 1.  Sign, exponent and perhaps high bits.  */
444   word1 = ((generic_floating_point_number.sign == '+')
445 	   ? 0
446 	   : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
447 
448   /* Assume 2's complement integers.  */
449   if (exponent_4 <= 0)
450     {
451       int prec_bits;
452       int num_bits;
453 
454       unget_bits (1);
455       num_bits = -exponent_4;
456       prec_bits =
457 	LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
458 #ifdef TC_I386
459       if (precision == X_PRECISION && exponent_bits == 15)
460 	{
461 	  /* On the i386 a denormalized extended precision float is
462 	     shifted down by one, effectively decreasing the exponent
463 	     bias by one.  */
464 	  prec_bits -= 1;
465 	  num_bits += 1;
466 	}
467 #endif
468 
469       if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
470 	{
471 	  /* Bigger than one littlenum.  */
472 	  num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
473 	  *lp++ = word1;
474 	  if (num_bits + exponent_bits + 1
475 	      > precision * LITTLENUM_NUMBER_OF_BITS)
476 	    {
477 	      /* Exponent overflow.  */
478 	      make_invalid_floating_point_number (words);
479 	      return return_value;
480 	    }
481 #ifdef TC_M68K
482 	  if (precision == X_PRECISION && exponent_bits == 15)
483 	    *lp++ = 0;
484 #endif
485 	  while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
486 	    {
487 	      num_bits -= LITTLENUM_NUMBER_OF_BITS;
488 	      *lp++ = 0;
489 	    }
490 	  if (num_bits)
491 	    *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
492 	}
493       else
494 	{
495 	  if (precision == X_PRECISION && exponent_bits == 15)
496 	    {
497 	      *lp++ = word1;
498 #ifdef TC_M68K
499 	      *lp++ = 0;
500 #endif
501 	      *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
502 	    }
503 	  else
504 	    {
505 	      word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1)
506 				  - (exponent_bits + num_bits));
507 	      *lp++ = word1;
508 	    }
509 	}
510       while (lp < words_end)
511 	*lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
512 
513       /* Round the mantissa up, but don't change the number.  */
514       if (next_bits (1))
515 	{
516 	  --lp;
517 	  if (prec_bits >= LITTLENUM_NUMBER_OF_BITS)
518 	    {
519 	      int n = 0;
520 	      int tmp_bits;
521 
522 	      n = 0;
523 	      tmp_bits = prec_bits;
524 	      while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
525 		{
526 		  if (lp[n] != (LITTLENUM_TYPE) - 1)
527 		    break;
528 		  --n;
529 		  tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
530 		}
531 	      if (tmp_bits > LITTLENUM_NUMBER_OF_BITS
532 		  || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]
533 		  || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS
534 				    - exponent_bits - 1)
535 #ifdef TC_I386
536 		      /* An extended precision float with only the integer
537 			 bit set would be invalid.  That must be converted
538 			 to the smallest normalized number.  */
539 		      && !(precision == X_PRECISION
540 			   && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS
541 					    - exponent_bits - 2))
542 #endif
543 		      ))
544 		{
545 		  unsigned long carry;
546 
547 		  for (carry = 1; carry && (lp >= words); lp--)
548 		    {
549 		      carry = *lp + carry;
550 		      *lp = carry;
551 		      carry >>= LITTLENUM_NUMBER_OF_BITS;
552 		    }
553 		}
554 	      else
555 		{
556 		  /* This is an overflow of the denormal numbers.  We
557                      need to forget what we have produced, and instead
558                      generate the smallest normalized number.  */
559 		  lp = words;
560 		  word1 = ((generic_floating_point_number.sign == '+')
561 			   ? 0
562 			   : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
563 		  word1 |= (1
564 			    << ((LITTLENUM_NUMBER_OF_BITS - 1)
565 				- exponent_bits));
566 		  *lp++ = word1;
567 #ifdef TC_I386
568 		  /* Set the integer bit in the extended precision format.
569 		     This cannot happen on the m68k where the mantissa
570 		     just overflows into the integer bit above.  */
571 		  if (precision == X_PRECISION)
572 		    *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
573 #endif
574 		  while (lp < words_end)
575 		    *lp++ = 0;
576 		}
577 	    }
578 	  else
579 	    *lp += 1;
580 	}
581 
582       return return_value;
583     }
584   else if ((unsigned long) exponent_4 > mask[exponent_bits]
585 	   || (! TC_LARGEST_EXPONENT_IS_NORMAL (precision)
586 	       && (unsigned long) exponent_4 == mask[exponent_bits]))
587     {
588       /* Exponent overflow.  Lose immediately.  */
589 
590       /* We leave return_value alone: admit we read the
591 	 number, but return a floating exception
592 	 because we can't encode the number.  */
593       make_invalid_floating_point_number (words);
594       return return_value;
595     }
596   else
597     {
598       word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
599 	| next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
600     }
601 
602   *lp++ = word1;
603 
604   /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
605      middle.  Either way, it is then followed by a 1 bit.  */
606   if (exponent_bits == 15 && precision == X_PRECISION)
607     {
608 #ifdef TC_M68K
609       *lp++ = 0;
610 #endif
611       *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
612 	       | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
613     }
614 
615   /* The rest of the words are just mantissa bits.  */
616   while (lp < words_end)
617     *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
618 
619   if (next_bits (1))
620     {
621       unsigned long carry;
622       /* Since the NEXT bit is a 1, round UP the mantissa.
623 	 The cunning design of these hidden-1 floats permits
624 	 us to let the mantissa overflow into the exponent, and
625 	 it 'does the right thing'. However, we lose if the
626 	 highest-order bit of the lowest-order word flips.
627 	 Is that clear?  */
628 
629       /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
630 	 Please allow at least 1 more bit in carry than is in a LITTLENUM.
631 	 We need that extra bit to hold a carry during a LITTLENUM carry
632 	 propagation. Another extra bit (kept 0) will assure us that we
633 	 don't get a sticky sign bit after shifting right, and that
634 	 permits us to propagate the carry without any masking of bits.
635 	 #endif */
636       for (carry = 1, lp--; carry; lp--)
637 	{
638 	  carry = *lp + carry;
639 	  *lp = carry;
640 	  carry >>= LITTLENUM_NUMBER_OF_BITS;
641 	  if (lp == words)
642 	    break;
643 	}
644       if (precision == X_PRECISION && exponent_bits == 15)
645 	{
646 	  /* Extended precision numbers have an explicit integer bit
647 	     that we may have to restore.  */
648 	  if (lp == words)
649 	    {
650 #ifdef TC_M68K
651 	      /* On the m68k there is a gap of 16 bits.  We must
652 		 explicitly propagate the carry into the exponent.  */
653 	      words[0] += words[1];
654 	      words[1] = 0;
655 	      lp++;
656 #endif
657 	      /* Put back the integer bit.  */
658 	      lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
659 	    }
660 	}
661       if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
662 	{
663 	  /* We leave return_value alone: admit we read the number,
664 	     but return a floating exception because we can't encode
665 	     the number.  */
666 	  *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
667 	}
668     }
669   return return_value;
670 }
671 
672 #ifdef TEST
673 char *
print_gen(gen)674 print_gen (gen)
675      FLONUM_TYPE *gen;
676 {
677   FLONUM_TYPE f;
678   LITTLENUM_TYPE arr[10];
679   double dv;
680   float fv;
681   static char sbuf[40];
682 
683   if (gen)
684     {
685       f = generic_floating_point_number;
686       generic_floating_point_number = *gen;
687     }
688   gen_to_words (&arr[0], 4, 11);
689   memcpy (&dv, &arr[0], sizeof (double));
690   sprintf (sbuf, "%x %x %x %x %.14G   ", arr[0], arr[1], arr[2], arr[3], dv);
691   gen_to_words (&arr[0], 2, 8);
692   memcpy (&fv, &arr[0], sizeof (float));
693   sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
694 
695   if (gen)
696     generic_floating_point_number = f;
697 
698   return (sbuf);
699 }
700 
701 #endif
702