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