1 /* atof_ieee.c - turn a Flonum into an IEEE floating point number
2 Copyright (C) 1987, 92, 93, 94, 95, 96, 97, 1998
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
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)
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.
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, 59 Temple Place - Suite 330, Boston, MA
24 /* Flonums returned here. */
25 extern FLONUM_TYPE generic_floating_point_number;
27 static int next_bits PARAMS ((int));
28 static void unget_bits PARAMS ((int));
29 static void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
31 extern const char EXP_CHARS[];
32 /* Precision in LittleNums. */
33 /* Don't count the gap in the m68k extended precision format. */
34 #define MAX_PRECISION (5)
35 #define F_PRECISION (2)
36 #define D_PRECISION (4)
37 #define X_PRECISION (5)
38 #define P_PRECISION (5)
40 /* Length in LittleNums of guard bits. */
43 static const unsigned long mask[] =
81 static int bits_left_in_littlenum;
82 static int littlenums_left;
83 static LITTLENUM_TYPE *littlenum_pointer;
86 next_bits (number_of_bits)
93 if (number_of_bits >= bits_left_in_littlenum)
95 return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
96 number_of_bits -= bits_left_in_littlenum;
97 return_value <<= number_of_bits;
99 if (--littlenums_left)
101 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
103 return_value |= (*littlenum_pointer >> bits_left_in_littlenum) & mask[number_of_bits];
108 bits_left_in_littlenum -= number_of_bits;
109 return_value = mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
111 return (return_value);
114 /* Num had better be less than LITTLENUM_NUMBER_OF_BITS */
119 if (!littlenums_left)
123 bits_left_in_littlenum = num;
125 else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
127 bits_left_in_littlenum = num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
132 bits_left_in_littlenum += num;
136 make_invalid_floating_point_number (words)
137 LITTLENUM_TYPE *words;
139 as_bad (_("cannot create floating-point number"));
140 words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; /* Zero the leftmost bit */
141 words[1] = (LITTLENUM_TYPE) -1;
142 words[2] = (LITTLENUM_TYPE) -1;
143 words[3] = (LITTLENUM_TYPE) -1;
144 words[4] = (LITTLENUM_TYPE) -1;
145 words[5] = (LITTLENUM_TYPE) -1;
148 /************************************************************************\
149 * Warning: this returns 16-bit LITTLENUMs. It is up to the caller *
150 * to figure out any alignment problems and to conspire for the *
151 * bytes/word to be emitted in the right order. Bigendians beware! *
153 \************************************************************************/
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
159 /* Returns pointer past text consumed. */
161 atof_ieee (str, what_kind, words)
162 char *str; /* Text to convert to binary. */
163 char what_kind; /* 'd', 'f', 'g', 'h' */
164 LITTLENUM_TYPE *words; /* Build the binary here. */
166 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
167 zeroed, the last contain flonum bits. */
168 static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
170 /* Number of 16-bit words in the format. */
173 FLONUM_TYPE save_gen_flonum;
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;
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';
188 /* Use more LittleNums than seems necessary: the highest flonum may
189 have 15 leading 0 bits, so could be useless. */
191 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
199 precision = F_PRECISION;
207 precision = D_PRECISION;
215 precision = X_PRECISION;
222 precision = P_PRECISION;
227 make_invalid_floating_point_number (words);
231 generic_floating_point_number.high
232 = generic_floating_point_number.low + precision - 1 + GUARD;
234 if (atof_generic (&return_value, ".", EXP_CHARS,
235 &generic_floating_point_number))
237 make_invalid_floating_point_number (words);
240 gen_to_words (words, precision, exponent_bits);
242 /* Restore the generic_floating_point_number's storage alloc (and
244 generic_floating_point_number = save_gen_flonum;
249 /* Turn generic_floating_point_number into a real float/double/extended. */
251 gen_to_words (words, precision, exponent_bits)
252 LITTLENUM_TYPE *words;
256 int return_value = 0;
262 int exponent_skippage;
263 LITTLENUM_TYPE word1;
265 LITTLENUM_TYPE *words_end;
267 words_end = words + precision;
269 if (precision == X_PRECISION)
270 /* On the m68k the extended precision format has a gap of 16 bits
271 between the exponent and the mantissa. */
275 if (generic_floating_point_number.low > generic_floating_point_number.leader)
278 if (generic_floating_point_number.sign == '+')
282 memset (&words[1], '\0',
283 (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
284 return (return_value);
287 /* NaN: Do the right thing */
288 if (generic_floating_point_number.sign == 0)
290 if (precision == F_PRECISION)
295 else if (precision == X_PRECISION)
304 #else /* ! TC_M68K */
311 #else /* ! TC_I386 */
313 #endif /* ! TC_I386 */
314 #endif /* ! TC_M68K */
325 else if (generic_floating_point_number.sign == 'P')
327 /* +INF: Do the right thing */
328 if (precision == F_PRECISION)
333 else if (precision == X_PRECISION)
342 #else /* ! TC_M68K */
349 #else /* ! TC_I386 */
351 #endif /* ! TC_I386 */
352 #endif /* ! TC_M68K */
361 return (return_value);
363 else if (generic_floating_point_number.sign == 'N')
366 if (precision == F_PRECISION)
371 else if (precision == X_PRECISION)
380 #else /* ! TC_M68K */
387 #else /* ! TC_I386 */
389 #endif /* ! TC_I386 */
390 #endif /* ! TC_M68K */
399 return (return_value);
402 * The floating point formats we support have:
403 * Bit 15 is sign bit.
404 * Bits 14:n are excess-whatever exponent.
405 * Bits n-1:0 (if any) are most significant bits of fraction.
406 * Bits 15:0 of the next word(s) are the next most significant bits.
408 * So we need: number of bits of exponent, number of bits of
411 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
412 littlenum_pointer = generic_floating_point_number.leader;
414 + generic_floating_point_number.leader
415 - generic_floating_point_number.low);
416 /* Seek (and forget) 1st significant bit */
417 for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);;
418 exponent_1 = (generic_floating_point_number.exponent
419 + generic_floating_point_number.leader
421 - generic_floating_point_number.low);
422 /* Radix LITTLENUM_RADIX, point just higher than
423 generic_floating_point_number.leader. */
424 exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
426 exponent_3 = exponent_2 - exponent_skippage;
427 /* Forget leading zeros, forget 1st bit. */
428 exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
429 /* Offset exponent. */
433 /* Word 1. Sign, exponent and perhaps high bits. */
434 word1 = ((generic_floating_point_number.sign == '+')
436 : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
438 /* Assume 2's complement integers. */
445 num_bits = -exponent_4;
446 prec_bits = LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
448 if (precision == X_PRECISION && exponent_bits == 15)
450 /* On the i386 a denormalized extended precision float is
451 shifted down by one, effectively decreasing the exponent
458 if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
460 /* Bigger than one littlenum */
461 num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
463 if (num_bits + exponent_bits + 1 >= precision * LITTLENUM_NUMBER_OF_BITS)
465 /* Exponent overflow */
466 make_invalid_floating_point_number (words);
467 return (return_value);
470 if (precision == X_PRECISION && exponent_bits == 15)
473 while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
475 num_bits -= LITTLENUM_NUMBER_OF_BITS;
479 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
483 if (precision == X_PRECISION && exponent_bits == 15)
489 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
493 word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - (exponent_bits + num_bits));
497 while (lp < words_end)
498 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
500 /* Round the mantissa up, but don't change the number */
504 if (prec_bits > LITTLENUM_NUMBER_OF_BITS)
510 tmp_bits = prec_bits;
511 while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
513 if (lp[n] != (LITTLENUM_TYPE) - 1)
516 tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
518 if (tmp_bits > LITTLENUM_NUMBER_OF_BITS || (lp[n] & mask[tmp_bits]) != mask[tmp_bits])
522 for (carry = 1; carry && (lp >= words); lp--)
526 carry >>= LITTLENUM_NUMBER_OF_BITS;
531 /* This is an overflow of the denormal numbers. We
532 need to forget what we have produced, and instead
533 generate the smallest normalized number. */
535 word1 = ((generic_floating_point_number.sign == '+')
537 : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
539 << ((LITTLENUM_NUMBER_OF_BITS - 1)
542 while (lp < words_end)
546 else if ((*lp & mask[prec_bits]) != mask[prec_bits])
552 else if ((unsigned long) exponent_4 >= mask[exponent_bits])
555 * Exponent overflow. Lose immediately.
559 * We leave return_value alone: admit we read the
560 * number, but return a floating exception
561 * because we can't encode the number.
563 make_invalid_floating_point_number (words);
568 word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
569 | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
574 /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
575 middle. Either way, it is then followed by a 1 bit. */
576 if (exponent_bits == 15 && precision == X_PRECISION)
581 *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
582 | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
585 /* The rest of the words are just mantissa bits. */
586 while (lp < words_end)
587 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
593 * Since the NEXT bit is a 1, round UP the mantissa.
594 * The cunning design of these hidden-1 floats permits
595 * us to let the mantissa overflow into the exponent, and
596 * it 'does the right thing'. However, we lose if the
597 * highest-order bit of the lowest-order word flips.
601 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
602 Please allow at least 1 more bit in carry than is in a LITTLENUM.
603 We need that extra bit to hold a carry during a LITTLENUM carry
604 propagation. Another extra bit (kept 0) will assure us that we
605 don't get a sticky sign bit after shifting right, and that
606 permits us to propagate the carry without any masking of bits.
608 for (carry = 1, lp--; carry && (lp >= words); lp--)
612 carry >>= LITTLENUM_NUMBER_OF_BITS;
614 if (precision == X_PRECISION && exponent_bits == 15)
616 /* Extended precision numbers have an explicit integer bit
617 that we may have to restore. */
621 /* On the m68k there is a gap of 16 bits. We must
622 explicitly propagate the carry into the exponent. */
623 words[0] += words[1];
627 /* Put back the integer bit. */
628 lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
631 if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
633 /* We leave return_value alone: admit we read the
634 * number, but return a floating exception
635 * because we can't encode the number.
637 *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
638 /* make_invalid_floating_point_number (words); */
639 /* return return_value; */
642 return (return_value);
646 /* This routine is a real kludge. Someone really should do it better,
647 but I'm too lazy, and I don't understand this stuff all too well
656 sprintf (buf, "%ld", x);
658 if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number))
659 as_bad (_("Error converting number to floating point (Exponent overflow?)"));
669 LITTLENUM_TYPE arr[10];
672 static char sbuf[40];
676 f = generic_floating_point_number;
677 generic_floating_point_number = *gen;
679 gen_to_words (&arr[0], 4, 11);
680 memcpy (&dv, &arr[0], sizeof (double));
681 sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv);
682 gen_to_words (&arr[0], 2, 8);
683 memcpy (&fv, &arr[0], sizeof (float));
684 sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
688 generic_floating_point_number = f;
696 /* end of atof-ieee.c */