1 /* atof_ieee.c - turn a Flonum into an IEEE floating point number
2 Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001
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
22 /* Some float formats are based on the IEEE standard, but use the
23 largest exponent for normal numbers instead of NaNs and infinites.
24 The macro TC_LARGEST_EXPONENT_IS_NORMAL should evaluate to true
25 if the target machine uses such a format. The macro can depend on
26 command line flags if necessary. There is no need to define the
27 macro if it would always be 0. */
31 /* Flonums returned here. */
32 extern FLONUM_TYPE generic_floating_point_number
;
34 static int next_bits
PARAMS ((int));
35 static void unget_bits
PARAMS ((int));
36 static void make_invalid_floating_point_number
PARAMS ((LITTLENUM_TYPE
*));
38 extern const char EXP_CHARS
[];
39 /* Precision in LittleNums. */
40 /* Don't count the gap in the m68k extended precision format. */
41 #define MAX_PRECISION (5)
42 #define F_PRECISION (2)
43 #define D_PRECISION (4)
44 #define X_PRECISION (5)
45 #define P_PRECISION (5)
47 /* Length in LittleNums of guard bits. */
50 #ifndef TC_LARGEST_EXPONENT_IS_NORMAL
51 #define TC_LARGEST_EXPONENT_IS_NORMAL 0
54 static const unsigned long mask
[] =
91 static int bits_left_in_littlenum
;
92 static int littlenums_left
;
93 static LITTLENUM_TYPE
*littlenum_pointer
;
96 next_bits (number_of_bits
)
101 if (!littlenums_left
)
103 if (number_of_bits
>= bits_left_in_littlenum
)
105 return_value
= mask
[bits_left_in_littlenum
] & *littlenum_pointer
;
106 number_of_bits
-= bits_left_in_littlenum
;
107 return_value
<<= number_of_bits
;
109 if (--littlenums_left
)
111 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
- number_of_bits
;
114 (*littlenum_pointer
>> bits_left_in_littlenum
)
115 & mask
[number_of_bits
];
120 bits_left_in_littlenum
-= number_of_bits
;
122 mask
[number_of_bits
] & (*littlenum_pointer
>> bits_left_in_littlenum
);
127 /* Num had better be less than LITTLENUM_NUMBER_OF_BITS. */
133 if (!littlenums_left
)
137 bits_left_in_littlenum
= num
;
139 else if (bits_left_in_littlenum
+ num
> LITTLENUM_NUMBER_OF_BITS
)
141 bits_left_in_littlenum
=
142 num
- (LITTLENUM_NUMBER_OF_BITS
- bits_left_in_littlenum
);
147 bits_left_in_littlenum
+= num
;
151 make_invalid_floating_point_number (words
)
152 LITTLENUM_TYPE
*words
;
154 as_bad (_("cannot create floating-point number"));
155 /* Zero the leftmost bit. */
156 words
[0] = (LITTLENUM_TYPE
) ((unsigned) -1) >> 1;
157 words
[1] = (LITTLENUM_TYPE
) -1;
158 words
[2] = (LITTLENUM_TYPE
) -1;
159 words
[3] = (LITTLENUM_TYPE
) -1;
160 words
[4] = (LITTLENUM_TYPE
) -1;
161 words
[5] = (LITTLENUM_TYPE
) -1;
164 /* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to
165 figure out any alignment problems and to conspire for the
166 bytes/word to be emitted in the right order. Bigendians beware! */
168 /* Note that atof-ieee always has X and P precisions enabled. it is up
169 to md_atof to filter them out if the target machine does not support
172 /* Returns pointer past text consumed. */
175 atof_ieee (str
, what_kind
, words
)
176 char *str
; /* Text to convert to binary. */
177 int what_kind
; /* 'd', 'f', 'g', 'h'. */
178 LITTLENUM_TYPE
*words
; /* Build the binary here. */
180 /* Extra bits for zeroed low-order bits.
181 The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */
182 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
184 /* Number of 16-bit words in the format. */
187 FLONUM_TYPE save_gen_flonum
;
189 /* We have to save the generic_floating_point_number because it
190 contains storage allocation about the array of LITTLENUMs where
191 the value is actually stored. We will allocate our own array of
192 littlenums below, but have to restore the global one on exit. */
193 save_gen_flonum
= generic_floating_point_number
;
196 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
197 generic_floating_point_number
.high
= NULL
;
198 generic_floating_point_number
.leader
= NULL
;
199 generic_floating_point_number
.exponent
= 0;
200 generic_floating_point_number
.sign
= '\0';
202 /* Use more LittleNums than seems necessary: the highest flonum may
203 have 15 leading 0 bits, so could be useless. */
205 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
213 precision
= F_PRECISION
;
221 precision
= D_PRECISION
;
229 precision
= X_PRECISION
;
236 precision
= P_PRECISION
;
241 make_invalid_floating_point_number (words
);
245 generic_floating_point_number
.high
246 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
248 if (atof_generic (&return_value
, ".", EXP_CHARS
,
249 &generic_floating_point_number
))
251 make_invalid_floating_point_number (words
);
254 gen_to_words (words
, precision
, exponent_bits
);
256 /* Restore the generic_floating_point_number's storage alloc (and
258 generic_floating_point_number
= save_gen_flonum
;
263 /* Turn generic_floating_point_number into a real float/double/extended. */
266 gen_to_words (words
, precision
, exponent_bits
)
267 LITTLENUM_TYPE
*words
;
271 int return_value
= 0;
277 int exponent_skippage
;
278 LITTLENUM_TYPE word1
;
280 LITTLENUM_TYPE
*words_end
;
282 words_end
= words
+ precision
;
284 if (precision
== X_PRECISION
)
285 /* On the m68k the extended precision format has a gap of 16 bits
286 between the exponent and the mantissa. */
290 if (generic_floating_point_number
.low
> generic_floating_point_number
.leader
)
293 if (generic_floating_point_number
.sign
== '+')
297 memset (&words
[1], '\0',
298 (words_end
- words
- 1) * sizeof (LITTLENUM_TYPE
));
302 /* NaN: Do the right thing. */
303 if (generic_floating_point_number
.sign
== 0)
305 if (TC_LARGEST_EXPONENT_IS_NORMAL
)
306 as_warn ("NaNs are not supported by this target\n");
307 if (precision
== F_PRECISION
)
312 else if (precision
== X_PRECISION
)
321 #else /* ! TC_M68K */
328 #else /* ! TC_I386 */
330 #endif /* ! TC_I386 */
331 #endif /* ! TC_M68K */
342 else if (generic_floating_point_number
.sign
== 'P')
344 if (TC_LARGEST_EXPONENT_IS_NORMAL
)
345 as_warn ("Infinities are not supported by this target\n");
347 /* +INF: Do the right thing. */
348 if (precision
== F_PRECISION
)
353 else if (precision
== X_PRECISION
)
362 #else /* ! TC_M68K */
369 #else /* ! TC_I386 */
371 #endif /* ! TC_I386 */
372 #endif /* ! TC_M68K */
383 else if (generic_floating_point_number
.sign
== 'N')
385 if (TC_LARGEST_EXPONENT_IS_NORMAL
)
386 as_warn ("Infinities are not supported by this target\n");
389 if (precision
== F_PRECISION
)
394 else if (precision
== X_PRECISION
)
403 #else /* ! TC_M68K */
410 #else /* ! TC_I386 */
412 #endif /* ! TC_I386 */
413 #endif /* ! TC_M68K */
425 /* The floating point formats we support have:
427 Bits 14:n are excess-whatever exponent.
428 Bits n-1:0 (if any) are most significant bits of fraction.
429 Bits 15:0 of the next word(s) are the next most significant bits.
431 So we need: number of bits of exponent, number of bits of
433 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
;
434 littlenum_pointer
= generic_floating_point_number
.leader
;
436 + generic_floating_point_number
.leader
437 - generic_floating_point_number
.low
);
439 /* Seek (and forget) 1st significant bit. */
440 for (exponent_skippage
= 0; !next_bits (1); ++exponent_skippage
);;
441 exponent_1
= (generic_floating_point_number
.exponent
442 + generic_floating_point_number
.leader
444 - generic_floating_point_number
.low
);
446 /* Radix LITTLENUM_RADIX, point just higher than
447 generic_floating_point_number.leader. */
448 exponent_2
= exponent_1
* LITTLENUM_NUMBER_OF_BITS
;
451 exponent_3
= exponent_2
- exponent_skippage
;
453 /* Forget leading zeros, forget 1st bit. */
454 exponent_4
= exponent_3
+ ((1 << (exponent_bits
- 1)) - 2);
456 /* Offset exponent. */
459 /* Word 1. Sign, exponent and perhaps high bits. */
460 word1
= ((generic_floating_point_number
.sign
== '+')
462 : (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)));
464 /* Assume 2's complement integers. */
471 num_bits
= -exponent_4
;
473 LITTLENUM_NUMBER_OF_BITS
* precision
- (exponent_bits
+ 1 + num_bits
);
475 if (precision
== X_PRECISION
&& exponent_bits
== 15)
477 /* On the i386 a denormalized extended precision float is
478 shifted down by one, effectively decreasing the exponent
485 if (num_bits
>= LITTLENUM_NUMBER_OF_BITS
- exponent_bits
)
487 /* Bigger than one littlenum. */
488 num_bits
-= (LITTLENUM_NUMBER_OF_BITS
- 1) - exponent_bits
;
490 if (num_bits
+ exponent_bits
+ 1
491 > precision
* LITTLENUM_NUMBER_OF_BITS
)
493 /* Exponent overflow. */
494 make_invalid_floating_point_number (words
);
498 if (precision
== X_PRECISION
&& exponent_bits
== 15)
501 while (num_bits
>= LITTLENUM_NUMBER_OF_BITS
)
503 num_bits
-= LITTLENUM_NUMBER_OF_BITS
;
507 *lp
++ = next_bits (LITTLENUM_NUMBER_OF_BITS
- (num_bits
));
511 if (precision
== X_PRECISION
&& exponent_bits
== 15)
517 *lp
++ = next_bits (LITTLENUM_NUMBER_OF_BITS
- num_bits
);
521 word1
|= next_bits ((LITTLENUM_NUMBER_OF_BITS
- 1)
522 - (exponent_bits
+ num_bits
));
526 while (lp
< words_end
)
527 *lp
++ = next_bits (LITTLENUM_NUMBER_OF_BITS
);
529 /* Round the mantissa up, but don't change the number. */
533 if (prec_bits
>= LITTLENUM_NUMBER_OF_BITS
)
539 tmp_bits
= prec_bits
;
540 while (tmp_bits
> LITTLENUM_NUMBER_OF_BITS
)
542 if (lp
[n
] != (LITTLENUM_TYPE
) - 1)
545 tmp_bits
-= LITTLENUM_NUMBER_OF_BITS
;
547 if (tmp_bits
> LITTLENUM_NUMBER_OF_BITS
548 || (lp
[n
] & mask
[tmp_bits
]) != mask
[tmp_bits
]
549 || (prec_bits
!= (precision
* LITTLENUM_NUMBER_OF_BITS
552 /* An extended precision float with only the integer
553 bit set would be invalid. That must be converted
554 to the smallest normalized number. */
555 && !(precision
== X_PRECISION
556 && prec_bits
== (precision
* LITTLENUM_NUMBER_OF_BITS
557 - exponent_bits
- 2))
563 for (carry
= 1; carry
&& (lp
>= words
); lp
--)
567 carry
>>= LITTLENUM_NUMBER_OF_BITS
;
572 /* This is an overflow of the denormal numbers. We
573 need to forget what we have produced, and instead
574 generate the smallest normalized number. */
576 word1
= ((generic_floating_point_number
.sign
== '+')
578 : (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)));
580 << ((LITTLENUM_NUMBER_OF_BITS
- 1)
584 /* Set the integer bit in the extended precision format.
585 This cannot happen on the m68k where the mantissa
586 just overflows into the integer bit above. */
587 if (precision
== X_PRECISION
)
588 *lp
++ = 1 << (LITTLENUM_NUMBER_OF_BITS
- 1);
590 while (lp
< words_end
)
600 else if ((unsigned long) exponent_4
> mask
[exponent_bits
]
601 || (! TC_LARGEST_EXPONENT_IS_NORMAL
602 && (unsigned long) exponent_4
== mask
[exponent_bits
]))
604 /* Exponent overflow. Lose immediately. */
606 /* We leave return_value alone: admit we read the
607 number, but return a floating exception
608 because we can't encode the number. */
609 make_invalid_floating_point_number (words
);
614 word1
|= (exponent_4
<< ((LITTLENUM_NUMBER_OF_BITS
- 1) - exponent_bits
))
615 | next_bits ((LITTLENUM_NUMBER_OF_BITS
- 1) - exponent_bits
);
620 /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
621 middle. Either way, it is then followed by a 1 bit. */
622 if (exponent_bits
== 15 && precision
== X_PRECISION
)
627 *lp
++ = (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)
628 | next_bits (LITTLENUM_NUMBER_OF_BITS
- 1));
631 /* The rest of the words are just mantissa bits. */
632 while (lp
< words_end
)
633 *lp
++ = next_bits (LITTLENUM_NUMBER_OF_BITS
);
638 /* Since the NEXT bit is a 1, round UP the mantissa.
639 The cunning design of these hidden-1 floats permits
640 us to let the mantissa overflow into the exponent, and
641 it 'does the right thing'. However, we lose if the
642 highest-order bit of the lowest-order word flips.
645 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
646 Please allow at least 1 more bit in carry than is in a LITTLENUM.
647 We need that extra bit to hold a carry during a LITTLENUM carry
648 propagation. Another extra bit (kept 0) will assure us that we
649 don't get a sticky sign bit after shifting right, and that
650 permits us to propagate the carry without any masking of bits.
652 for (carry
= 1, lp
--; carry
; lp
--)
656 carry
>>= LITTLENUM_NUMBER_OF_BITS
;
660 if (precision
== X_PRECISION
&& exponent_bits
== 15)
662 /* Extended precision numbers have an explicit integer bit
663 that we may have to restore. */
667 /* On the m68k there is a gap of 16 bits. We must
668 explicitly propagate the carry into the exponent. */
669 words
[0] += words
[1];
673 /* Put back the integer bit. */
674 lp
[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS
- 1);
677 if ((word1
^ *words
) & (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)))
679 /* We leave return_value alone: admit we read the number,
680 but return a floating exception because we can't encode
682 *words
&= ~(1 << (LITTLENUM_NUMBER_OF_BITS
- 1));
684 make_invalid_floating_point_number (words
);
694 /* This routine is a real kludge. Someone really should do it better,
695 but I'm too lazy, and I don't understand this stuff all too well
705 sprintf (buf
, "%ld", x
);
707 if (atof_generic (&bufp
, ".", EXP_CHARS
, &generic_floating_point_number
))
708 as_bad (_("Error converting number to floating point (Exponent overflow?)"));
718 LITTLENUM_TYPE arr
[10];
721 static char sbuf
[40];
725 f
= generic_floating_point_number
;
726 generic_floating_point_number
= *gen
;
728 gen_to_words (&arr
[0], 4, 11);
729 memcpy (&dv
, &arr
[0], sizeof (double));
730 sprintf (sbuf
, "%x %x %x %x %.14G ", arr
[0], arr
[1], arr
[2], arr
[3], dv
);
731 gen_to_words (&arr
[0], 2, 8);
732 memcpy (&fv
, &arr
[0], sizeof (float));
733 sprintf (sbuf
+ strlen (sbuf
), "%x %x %.12g\n", arr
[0], arr
[1], fv
);
736 generic_floating_point_number
= f
;