/src/binutils-gdb/gas/config/atof-ieee.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* atof_ieee.c - turn a Flonum into an IEEE floating point number |
2 | | Copyright (C) 1987-2025 Free Software Foundation, Inc. |
3 | | |
4 | | This file is part of GAS, the GNU Assembler. |
5 | | |
6 | | GAS is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3, or (at your option) |
9 | | any later version. |
10 | | |
11 | | GAS is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License |
17 | | along with GAS; see the file COPYING. If not, write to the Free |
18 | | Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA |
19 | | 02110-1301, USA. */ |
20 | | |
21 | | #include "as.h" |
22 | | #include "safe-ctype.h" |
23 | | |
24 | | /* Flonums returned here. */ |
25 | | extern FLONUM_TYPE generic_floating_point_number; |
26 | | |
27 | | /* Precision in LittleNums. */ |
28 | | /* Don't count the gap in the m68k extended precision format. */ |
29 | 3.76k | #define MAX_PRECISION 5 |
30 | 0 | #define H_PRECISION 1 |
31 | 0 | #define B_PRECISION 1 /* Not strictly IEEE, but handled here anyway. */ |
32 | 3.76k | #define F_PRECISION 2 |
33 | 0 | #define D_PRECISION 4 |
34 | 2.36k | #define X_PRECISION 5 |
35 | | #ifndef X_PRECISION_PAD |
36 | | #define X_PRECISION_PAD 0 |
37 | | #endif |
38 | 0 | #define P_PRECISION 5 |
39 | | #ifndef P_PRECISION_PAD |
40 | 0 | #define P_PRECISION_PAD X_PRECISION_PAD |
41 | | #endif |
42 | | |
43 | | /* Length in LittleNums of guard bits. */ |
44 | 1.88k | #define GUARD 2 |
45 | | |
46 | | #ifndef TC_LARGEST_EXPONENT_IS_NORMAL |
47 | 1.68k | #define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) 0 |
48 | | #endif |
49 | | |
50 | | static const unsigned long mask[] = |
51 | | { |
52 | | 0x00000000, |
53 | | 0x00000001, |
54 | | 0x00000003, |
55 | | 0x00000007, |
56 | | 0x0000000f, |
57 | | 0x0000001f, |
58 | | 0x0000003f, |
59 | | 0x0000007f, |
60 | | 0x000000ff, |
61 | | 0x000001ff, |
62 | | 0x000003ff, |
63 | | 0x000007ff, |
64 | | 0x00000fff, |
65 | | 0x00001fff, |
66 | | 0x00003fff, |
67 | | 0x00007fff, |
68 | | 0x0000ffff, |
69 | | 0x0001ffff, |
70 | | 0x0003ffff, |
71 | | 0x0007ffff, |
72 | | 0x000fffff, |
73 | | 0x001fffff, |
74 | | 0x003fffff, |
75 | | 0x007fffff, |
76 | | 0x00ffffff, |
77 | | 0x01ffffff, |
78 | | 0x03ffffff, |
79 | | 0x07ffffff, |
80 | | 0x0fffffff, |
81 | | 0x1fffffff, |
82 | | 0x3fffffff, |
83 | | 0x7fffffff, |
84 | | 0xffffffff, |
85 | | }; |
86 | | |
87 | | static int bits_left_in_littlenum; |
88 | | static int littlenums_left; |
89 | | static LITTLENUM_TYPE *littlenum_pointer; |
90 | | |
91 | | static int |
92 | | next_bits (int number_of_bits) |
93 | 14.9k | { |
94 | 14.9k | int return_value; |
95 | | |
96 | 14.9k | if (!littlenums_left) |
97 | 719 | return 0; |
98 | | |
99 | 14.2k | if (number_of_bits >= bits_left_in_littlenum) |
100 | 1.54k | { |
101 | 1.54k | return_value = mask[bits_left_in_littlenum] & *littlenum_pointer; |
102 | 1.54k | number_of_bits -= bits_left_in_littlenum; |
103 | 1.54k | return_value <<= number_of_bits; |
104 | | |
105 | 1.54k | if (--littlenums_left) |
106 | 1.16k | { |
107 | 1.16k | bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; |
108 | 1.16k | --littlenum_pointer; |
109 | 1.16k | return_value |= |
110 | 1.16k | (*littlenum_pointer >> bits_left_in_littlenum) |
111 | 1.16k | & mask[number_of_bits]; |
112 | 1.16k | } |
113 | 1.54k | } |
114 | 12.7k | else |
115 | 12.7k | { |
116 | 12.7k | bits_left_in_littlenum -= number_of_bits; |
117 | 12.7k | return_value = |
118 | 12.7k | mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum); |
119 | 12.7k | } |
120 | 14.2k | return return_value; |
121 | 14.9k | } |
122 | | |
123 | | /* Num had better be less than LITTLENUM_NUMBER_OF_BITS. */ |
124 | | |
125 | | static void |
126 | | unget_bits (int num) |
127 | 514 | { |
128 | 514 | if (!littlenums_left) |
129 | 0 | { |
130 | 0 | ++littlenum_pointer; |
131 | 0 | ++littlenums_left; |
132 | 0 | bits_left_in_littlenum = num; |
133 | 0 | } |
134 | 514 | else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS) |
135 | 7 | { |
136 | 7 | bits_left_in_littlenum = |
137 | 7 | num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum); |
138 | 7 | ++littlenum_pointer; |
139 | 7 | ++littlenums_left; |
140 | 7 | } |
141 | 507 | else |
142 | 507 | bits_left_in_littlenum += num; |
143 | 514 | } |
144 | | |
145 | | static void |
146 | | make_invalid_floating_point_number (LITTLENUM_TYPE *words) |
147 | 88 | { |
148 | 88 | as_bad (_("cannot create floating-point number")); |
149 | | /* Zero the leftmost bit. */ |
150 | 88 | words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; |
151 | 88 | words[1] = (LITTLENUM_TYPE) -1; |
152 | 88 | words[2] = (LITTLENUM_TYPE) -1; |
153 | 88 | words[3] = (LITTLENUM_TYPE) -1; |
154 | 88 | words[4] = (LITTLENUM_TYPE) -1; |
155 | 88 | words[5] = (LITTLENUM_TYPE) -1; |
156 | 88 | } |
157 | | |
158 | | /* Build a floating point constant at str into a IEEE floating |
159 | | point number. This function does the same thing as atof_ieee |
160 | | however it allows more control over the exact format, i.e. |
161 | | explicitly specifying the precision and number of exponent bits |
162 | | instead of relying on this infomation being deduced from a given type. |
163 | | |
164 | | If generic_float_info is not NULL then it will be set to contain generic |
165 | | infomation about the parsed floating point number. |
166 | | |
167 | | Returns pointer past text consumed. */ |
168 | | char * |
169 | | atof_ieee_detail (char * str, |
170 | | int precision, |
171 | | int exponent_bits, |
172 | | LITTLENUM_TYPE * words, |
173 | | FLONUM_TYPE * generic_float_info) |
174 | 1.88k | { |
175 | | /* Extra bits for zeroed low-order bits. |
176 | | The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */ |
177 | 1.88k | static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; |
178 | 1.88k | char *return_value; |
179 | | |
180 | | /* Number of 16-bit words in the format. */ |
181 | 1.88k | FLONUM_TYPE save_gen_flonum; |
182 | | |
183 | | /* We have to save the generic_floating_point_number because it |
184 | | contains storage allocation about the array of LITTLENUMs where |
185 | | the value is actually stored. We will allocate our own array of |
186 | | littlenums below, but have to restore the global one on exit. */ |
187 | 1.88k | save_gen_flonum = generic_floating_point_number; |
188 | | |
189 | 1.88k | return_value = str; |
190 | 1.88k | generic_floating_point_number.low = bits + MAX_PRECISION; |
191 | 1.88k | generic_floating_point_number.high = NULL; |
192 | 1.88k | generic_floating_point_number.leader = NULL; |
193 | 1.88k | generic_floating_point_number.exponent = 0; |
194 | 1.88k | generic_floating_point_number.sign = '\0'; |
195 | | |
196 | | /* Use more LittleNums than seems necessary: the highest flonum may |
197 | | have 15 leading 0 bits, so could be useless. */ |
198 | | |
199 | 1.88k | memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); |
200 | | |
201 | 1.88k | generic_floating_point_number.high |
202 | 1.88k | = generic_floating_point_number.low + precision - 1 + GUARD; |
203 | | |
204 | 1.88k | if (atof_generic (&return_value, ".", EXP_CHARS, |
205 | 1.88k | &generic_floating_point_number)) |
206 | 9 | { |
207 | 9 | make_invalid_floating_point_number (words); |
208 | 9 | return NULL; |
209 | 9 | } |
210 | | |
211 | 1.87k | if (generic_float_info) |
212 | 0 | *generic_float_info = generic_floating_point_number; |
213 | | |
214 | 1.87k | gen_to_words (words, precision, exponent_bits); |
215 | | |
216 | | /* Restore the generic_floating_point_number's storage alloc (and |
217 | | everything else). */ |
218 | 1.87k | generic_floating_point_number = save_gen_flonum; |
219 | | |
220 | 1.87k | return return_value; |
221 | 1.88k | } |
222 | | |
223 | | /* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to |
224 | | figure out any alignment problems and to conspire for the |
225 | | bytes/word to be emitted in the right order. Bigendians beware! */ |
226 | | |
227 | | /* Note that atof-ieee always has X and P precisions enabled. it is up |
228 | | to md_atof to filter them out if the target machine does not support |
229 | | them. */ |
230 | | |
231 | | /* Returns pointer past text consumed. */ |
232 | | char * |
233 | | atof_ieee (char *str, /* Text to convert to binary. */ |
234 | | int what_kind, /* 'd', 'f', 'x', 'p'. */ |
235 | | LITTLENUM_TYPE *words) /* Build the binary here. */ |
236 | 1.88k | { |
237 | 1.88k | int precision; |
238 | 1.88k | long exponent_bits; |
239 | | |
240 | 1.88k | switch (what_kind) |
241 | 1.88k | { |
242 | 0 | case 'h': |
243 | 0 | case 'H': |
244 | 0 | precision = H_PRECISION; |
245 | 0 | exponent_bits = 5; |
246 | 0 | break; |
247 | | |
248 | 0 | case 'b': |
249 | 0 | case 'B': |
250 | 0 | precision = B_PRECISION; |
251 | 0 | exponent_bits = 8; |
252 | 0 | break; |
253 | | |
254 | 1.88k | case 'f': |
255 | 1.88k | case 'F': |
256 | 1.88k | case 's': |
257 | 1.88k | case 'S': |
258 | 1.88k | precision = F_PRECISION; |
259 | 1.88k | exponent_bits = 8; |
260 | 1.88k | break; |
261 | | |
262 | 0 | case 'd': |
263 | 0 | case 'D': |
264 | 0 | case 'r': |
265 | 0 | case 'R': |
266 | 0 | precision = D_PRECISION; |
267 | 0 | exponent_bits = 11; |
268 | 0 | break; |
269 | | |
270 | 0 | case 'x': |
271 | 0 | case 'X': |
272 | 0 | case 'e': |
273 | 0 | case 'E': |
274 | 0 | precision = X_PRECISION; |
275 | 0 | exponent_bits = 15; |
276 | 0 | break; |
277 | | |
278 | 0 | case 'p': |
279 | 0 | case 'P': |
280 | 0 | precision = P_PRECISION; |
281 | 0 | exponent_bits = -1; |
282 | 0 | break; |
283 | | |
284 | 0 | default: |
285 | 0 | make_invalid_floating_point_number (words); |
286 | 0 | return (NULL); |
287 | 1.88k | } |
288 | | |
289 | 1.88k | return atof_ieee_detail (str, precision, exponent_bits, words, NULL); |
290 | 1.88k | } |
291 | | |
292 | | /* Turn generic_floating_point_number into a real float/double/extended. */ |
293 | | |
294 | | int |
295 | | gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits) |
296 | 1.87k | { |
297 | 1.87k | int return_value = 0; |
298 | | |
299 | 1.87k | long exponent_1; |
300 | 1.87k | long exponent_2; |
301 | 1.87k | long exponent_3; |
302 | 1.87k | long exponent_4; |
303 | 1.87k | int exponent_skippage; |
304 | 1.87k | LITTLENUM_TYPE word1; |
305 | 1.87k | LITTLENUM_TYPE *lp; |
306 | 1.87k | LITTLENUM_TYPE *words_end; |
307 | | |
308 | 1.87k | words_end = words + precision; |
309 | | #ifdef TC_M68K |
310 | | if (precision == X_PRECISION) |
311 | | /* On the m68k the extended precision format has a gap of 16 bits |
312 | | between the exponent and the mantissa. */ |
313 | | words_end++; |
314 | | #endif |
315 | | |
316 | 1.87k | if (generic_floating_point_number.low > generic_floating_point_number.leader) |
317 | 480 | { |
318 | | /* 0.0e0 seen. */ |
319 | 480 | if (generic_floating_point_number.sign == '+') |
320 | 478 | words[0] = 0x0000; |
321 | 2 | else |
322 | 2 | words[0] = 0x8000; |
323 | 480 | memset (&words[1], '\0', |
324 | 480 | (words_end - words - 1) * sizeof (LITTLENUM_TYPE)); |
325 | 480 | return return_value; |
326 | 480 | } |
327 | | |
328 | 1.39k | switch (generic_floating_point_number.sign) |
329 | 1.39k | { |
330 | | /* NaN: Do the right thing. */ |
331 | 0 | case 0: |
332 | 0 | case 'Q': case 'q': |
333 | 0 | case 'S': case 's': |
334 | 0 | if (TC_LARGEST_EXPONENT_IS_NORMAL (precision)) |
335 | 0 | as_warn (_("NaNs are not supported by this target")); |
336 | |
|
337 | 0 | if (precision == H_PRECISION) |
338 | 0 | { |
339 | 0 | if (TOUPPER (generic_floating_point_number.sign) != 'S') |
340 | 0 | words[0] = 0x7fff; |
341 | 0 | else |
342 | 0 | words[0] = exponent_bits == 5 ? 0x7dff : 0x7fbf; |
343 | 0 | } |
344 | 0 | else if (precision == F_PRECISION) |
345 | 0 | { |
346 | 0 | words[0] = TOUPPER (generic_floating_point_number.sign) == 'S' |
347 | 0 | ? 0x7fbf : 0x7fff; |
348 | 0 | words[1] = 0xffff; |
349 | 0 | } |
350 | 0 | else if (precision == X_PRECISION) |
351 | 0 | { |
352 | | #ifdef TC_M68K |
353 | | if (generic_floating_point_number.sign) |
354 | | as_warn (_("NaN flavors are not supported by this target")); |
355 | | |
356 | | words[0] = 0x7fff; |
357 | | words[1] = 0; |
358 | | words[2] = 0xffff; |
359 | | words[3] = 0xffff; |
360 | | words[4] = 0xffff; |
361 | | words[5] = 0xffff; |
362 | | #else /* ! TC_M68K */ |
363 | 0 | #ifdef TC_I386 |
364 | 0 | words[0] = 0x7fff; |
365 | 0 | words[1] = TOUPPER (generic_floating_point_number.sign) == 'S' |
366 | 0 | ? 0xbfff : 0xffff; |
367 | 0 | words[2] = 0xffff; |
368 | 0 | words[3] = 0xffff; |
369 | 0 | words[4] = 0xffff; |
370 | | #else /* ! TC_I386 */ |
371 | | abort (); |
372 | | #endif /* ! TC_I386 */ |
373 | 0 | #endif /* ! TC_M68K */ |
374 | 0 | } |
375 | 0 | else |
376 | 0 | { |
377 | 0 | words[0] = TOUPPER (generic_floating_point_number.sign) == 'S' |
378 | 0 | ? 0x7ff7 : 0x7fff; |
379 | 0 | words[1] = 0xffff; |
380 | 0 | words[2] = 0xffff; |
381 | 0 | words[3] = 0xffff; |
382 | 0 | } |
383 | |
|
384 | 0 | if (ISLOWER (generic_floating_point_number.sign)) |
385 | 0 | words[0] |= 0x8000; |
386 | |
|
387 | 0 | return return_value; |
388 | | |
389 | 0 | case 'P': |
390 | 0 | case 'N': |
391 | 0 | if (TC_LARGEST_EXPONENT_IS_NORMAL (precision)) |
392 | 0 | as_warn (_("Infinities are not supported by this target")); |
393 | | |
394 | | /* +INF: Do the right thing. */ |
395 | 0 | if (precision == H_PRECISION /* also B_PRECISION */) |
396 | 0 | { |
397 | 0 | words[0] = exponent_bits == 5 ? 0x7c00 : 0x7f80; |
398 | 0 | } |
399 | 0 | else if (precision == F_PRECISION) |
400 | 0 | { |
401 | 0 | words[0] = 0x7f80; |
402 | 0 | words[1] = 0; |
403 | 0 | } |
404 | 0 | else if (precision == X_PRECISION) |
405 | 0 | { |
406 | | #ifdef TC_M68K |
407 | | words[0] = 0x7fff; |
408 | | words[1] = 0; |
409 | | words[2] = 0; |
410 | | words[3] = 0; |
411 | | words[4] = 0; |
412 | | words[5] = 0; |
413 | | #else /* ! TC_M68K */ |
414 | 0 | #ifdef TC_I386 |
415 | 0 | words[0] = 0x7fff; |
416 | 0 | words[1] = 0x8000; |
417 | 0 | words[2] = 0; |
418 | 0 | words[3] = 0; |
419 | 0 | words[4] = 0; |
420 | | #else /* ! TC_I386 */ |
421 | | abort (); |
422 | | #endif /* ! TC_I386 */ |
423 | 0 | #endif /* ! TC_M68K */ |
424 | 0 | } |
425 | 0 | else |
426 | 0 | { |
427 | 0 | words[0] = 0x7ff0; |
428 | 0 | words[1] = 0; |
429 | 0 | words[2] = 0; |
430 | 0 | words[3] = 0; |
431 | 0 | } |
432 | |
|
433 | 0 | if (generic_floating_point_number.sign == 'N') |
434 | 0 | words[0] |= 0x8000; |
435 | |
|
436 | 0 | return return_value; |
437 | 1.39k | } |
438 | | |
439 | | /* The floating point formats we support have: |
440 | | Bit 15 is sign bit. |
441 | | Bits 14:n are excess-whatever exponent. |
442 | | Bits n-1:0 (if any) are most significant bits of fraction. |
443 | | Bits 15:0 of the next word(s) are the next most significant bits. |
444 | | |
445 | | So we need: number of bits of exponent, number of bits of |
446 | | mantissa. */ |
447 | 1.39k | bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; |
448 | 1.39k | littlenum_pointer = generic_floating_point_number.leader; |
449 | 1.39k | littlenums_left = (1 |
450 | 1.39k | + generic_floating_point_number.leader |
451 | 1.39k | - generic_floating_point_number.low); |
452 | | |
453 | | /* Seek (and forget) 1st significant bit. */ |
454 | 11.0k | for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage); |
455 | 1.39k | exponent_1 = (generic_floating_point_number.exponent |
456 | 1.39k | + generic_floating_point_number.leader |
457 | 1.39k | + 1 |
458 | 1.39k | - generic_floating_point_number.low); |
459 | | |
460 | | /* Radix LITTLENUM_RADIX, point just higher than |
461 | | generic_floating_point_number.leader. */ |
462 | 1.39k | exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; |
463 | | |
464 | | /* Radix 2. */ |
465 | 1.39k | exponent_3 = exponent_2 - exponent_skippage; |
466 | | |
467 | | /* Forget leading zeros, forget 1st bit. */ |
468 | 1.39k | exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); |
469 | | |
470 | | /* Offset exponent. */ |
471 | 1.39k | lp = words; |
472 | | |
473 | | /* Word 1. Sign, exponent and perhaps high bits. */ |
474 | 1.39k | word1 = ((generic_floating_point_number.sign == '+') |
475 | 1.39k | ? 0 |
476 | 1.39k | : (1 << (LITTLENUM_NUMBER_OF_BITS - 1))); |
477 | | |
478 | | /* Assume 2's complement integers. */ |
479 | 1.39k | if (exponent_4 <= 0) |
480 | 514 | { |
481 | 514 | int prec_bits; |
482 | 514 | int num_bits; |
483 | | |
484 | 514 | unget_bits (1); |
485 | 514 | num_bits = -exponent_4; |
486 | 514 | prec_bits = |
487 | 514 | LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits); |
488 | 514 | #ifdef TC_I386 |
489 | 514 | if (precision == X_PRECISION && exponent_bits == 15) |
490 | 0 | { |
491 | | /* On the i386 a denormalized extended precision float is |
492 | | shifted down by one, effectively decreasing the exponent |
493 | | bias by one. */ |
494 | 0 | prec_bits -= 1; |
495 | 0 | num_bits += 1; |
496 | 0 | } |
497 | 514 | #endif |
498 | | |
499 | 514 | if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits) |
500 | 100 | { |
501 | | /* Bigger than one littlenum. */ |
502 | 100 | num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits; |
503 | 100 | *lp++ = word1; |
504 | 100 | if (num_bits + exponent_bits + 1 |
505 | 100 | > precision * LITTLENUM_NUMBER_OF_BITS) |
506 | 42 | { |
507 | | /* Exponent overflow. */ |
508 | 42 | make_invalid_floating_point_number (words); |
509 | 42 | return return_value; |
510 | 42 | } |
511 | | #ifdef TC_M68K |
512 | | if (precision == X_PRECISION && exponent_bits == 15) |
513 | | *lp++ = 0; |
514 | | #endif |
515 | 58 | while (num_bits >= LITTLENUM_NUMBER_OF_BITS) |
516 | 0 | { |
517 | 0 | num_bits -= LITTLENUM_NUMBER_OF_BITS; |
518 | 0 | *lp++ = 0; |
519 | 0 | } |
520 | 58 | if (num_bits) |
521 | 58 | *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits)); |
522 | 58 | } |
523 | 414 | else |
524 | 414 | { |
525 | 414 | if (precision == X_PRECISION && exponent_bits == 15) |
526 | 0 | { |
527 | 0 | *lp++ = word1; |
528 | | #ifdef TC_M68K |
529 | | *lp++ = 0; |
530 | | #endif |
531 | 0 | *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits); |
532 | 0 | } |
533 | 414 | else |
534 | 414 | { |
535 | 414 | word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) |
536 | 414 | - (exponent_bits + num_bits)); |
537 | 414 | *lp++ = word1; |
538 | 414 | } |
539 | 414 | } |
540 | 886 | while (lp < words_end) |
541 | 414 | *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); |
542 | | |
543 | | /* Round the mantissa up, but don't change the number. */ |
544 | 472 | if (next_bits (1)) |
545 | 465 | { |
546 | 465 | --lp; |
547 | 465 | if (prec_bits >= LITTLENUM_NUMBER_OF_BITS) |
548 | 407 | { |
549 | 407 | int n = 0; |
550 | 407 | int tmp_bits; |
551 | | |
552 | 407 | n = 0; |
553 | 407 | tmp_bits = prec_bits; |
554 | 407 | while (tmp_bits > LITTLENUM_NUMBER_OF_BITS) |
555 | 188 | { |
556 | 188 | if (lp[n] != (LITTLENUM_TYPE) - 1) |
557 | 188 | break; |
558 | 0 | --n; |
559 | 0 | tmp_bits -= LITTLENUM_NUMBER_OF_BITS; |
560 | 0 | } |
561 | 407 | if (tmp_bits > LITTLENUM_NUMBER_OF_BITS |
562 | 407 | || (lp[n] & mask[tmp_bits]) != mask[tmp_bits] |
563 | 407 | || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS |
564 | 0 | - exponent_bits - 1) |
565 | 0 | #ifdef TC_I386 |
566 | | /* An extended precision float with only the integer |
567 | | bit set would be invalid. That must be converted |
568 | | to the smallest normalized number. */ |
569 | 0 | && !(precision == X_PRECISION |
570 | 0 | && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS |
571 | 0 | - exponent_bits - 2)) |
572 | 0 | #endif |
573 | 0 | )) |
574 | 407 | { |
575 | 407 | unsigned long carry; |
576 | | |
577 | 814 | for (carry = 1; carry && (lp >= words); lp--) |
578 | 407 | { |
579 | 407 | carry = *lp + carry; |
580 | 407 | *lp = carry; |
581 | 407 | carry >>= LITTLENUM_NUMBER_OF_BITS; |
582 | 407 | } |
583 | 407 | } |
584 | 0 | else |
585 | 0 | { |
586 | | /* This is an overflow of the denormal numbers. We |
587 | | need to forget what we have produced, and instead |
588 | | generate the smallest normalized number. */ |
589 | 0 | lp = words; |
590 | 0 | word1 = ((generic_floating_point_number.sign == '+') |
591 | 0 | ? 0 |
592 | 0 | : (1 << (LITTLENUM_NUMBER_OF_BITS - 1))); |
593 | 0 | word1 |= (1 |
594 | 0 | << ((LITTLENUM_NUMBER_OF_BITS - 1) |
595 | 0 | - exponent_bits)); |
596 | 0 | *lp++ = word1; |
597 | 0 | #ifdef TC_I386 |
598 | | /* Set the integer bit in the extended precision format. |
599 | | This cannot happen on the m68k where the mantissa |
600 | | just overflows into the integer bit above. */ |
601 | 0 | if (precision == X_PRECISION) |
602 | 0 | *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1); |
603 | 0 | #endif |
604 | 0 | while (lp < words_end) |
605 | 0 | *lp++ = 0; |
606 | 0 | } |
607 | 407 | } |
608 | 58 | else |
609 | 58 | *lp += 1; |
610 | 465 | } |
611 | | |
612 | 472 | return return_value; |
613 | 514 | } |
614 | 878 | else if ((unsigned long) exponent_4 > mask[exponent_bits] |
615 | 878 | || (! TC_LARGEST_EXPONENT_IS_NORMAL (precision) |
616 | 841 | && (unsigned long) exponent_4 == mask[exponent_bits])) |
617 | 37 | { |
618 | | /* Exponent overflow. Lose immediately. */ |
619 | | |
620 | | /* We leave return_value alone: admit we read the |
621 | | number, but return a floating exception |
622 | | because we can't encode the number. */ |
623 | 37 | make_invalid_floating_point_number (words); |
624 | 37 | return return_value; |
625 | 37 | } |
626 | 841 | else |
627 | 841 | { |
628 | 841 | word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits)) |
629 | 841 | | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits); |
630 | 841 | } |
631 | | |
632 | 841 | *lp++ = word1; |
633 | | |
634 | | /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the |
635 | | middle. Either way, it is then followed by a 1 bit. */ |
636 | 841 | if (exponent_bits == 15 && precision == X_PRECISION) |
637 | 0 | { |
638 | | #ifdef TC_M68K |
639 | | *lp++ = 0; |
640 | | #endif |
641 | 0 | *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1) |
642 | 0 | | next_bits (LITTLENUM_NUMBER_OF_BITS - 1)); |
643 | 0 | } |
644 | | |
645 | | /* The rest of the words are just mantissa bits. */ |
646 | 1.68k | while (lp < words_end) |
647 | 841 | *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); |
648 | | |
649 | 841 | if (next_bits (1)) |
650 | 252 | { |
651 | 252 | unsigned long carry; |
652 | | /* Since the NEXT bit is a 1, round UP the mantissa. |
653 | | The cunning design of these hidden-1 floats permits |
654 | | us to let the mantissa overflow into the exponent, and |
655 | | it 'does the right thing'. However, we lose if the |
656 | | highest-order bit of the lowest-order word flips. |
657 | | Is that clear? */ |
658 | | |
659 | | /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) |
660 | | Please allow at least 1 more bit in carry than is in a LITTLENUM. |
661 | | We need that extra bit to hold a carry during a LITTLENUM carry |
662 | | propagation. Another extra bit (kept 0) will assure us that we |
663 | | don't get a sticky sign bit after shifting right, and that |
664 | | permits us to propagate the carry without any masking of bits. |
665 | | #endif */ |
666 | 504 | for (carry = 1, lp--; carry; lp--) |
667 | 252 | { |
668 | 252 | carry = *lp + carry; |
669 | 252 | *lp = carry; |
670 | 252 | carry >>= LITTLENUM_NUMBER_OF_BITS; |
671 | 252 | if (lp == words) |
672 | 0 | break; |
673 | 252 | } |
674 | 252 | if (precision == X_PRECISION && exponent_bits == 15) |
675 | 0 | { |
676 | | /* Extended precision numbers have an explicit integer bit |
677 | | that we may have to restore. */ |
678 | 0 | if (lp == words) |
679 | 0 | { |
680 | | #ifdef TC_M68K |
681 | | /* On the m68k there is a gap of 16 bits. We must |
682 | | explicitly propagate the carry into the exponent. */ |
683 | | words[0] += words[1]; |
684 | | words[1] = 0; |
685 | | lp++; |
686 | | #endif |
687 | | /* Put back the integer bit. */ |
688 | 0 | lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1); |
689 | 0 | } |
690 | 0 | } |
691 | 252 | if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) |
692 | 0 | { |
693 | | /* We leave return_value alone: admit we read the number, |
694 | | but return a floating exception because we can't encode |
695 | | the number. */ |
696 | 0 | *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1)); |
697 | 0 | } |
698 | 252 | } |
699 | 841 | return return_value; |
700 | 1.39k | } |
701 | | |
702 | | #ifdef TEST |
703 | | char * |
704 | | print_gen (gen) |
705 | | FLONUM_TYPE *gen; |
706 | | { |
707 | | FLONUM_TYPE f; |
708 | | LITTLENUM_TYPE arr[10]; |
709 | | double dv; |
710 | | float fv; |
711 | | static char sbuf[40]; |
712 | | |
713 | | if (gen) |
714 | | { |
715 | | f = generic_floating_point_number; |
716 | | generic_floating_point_number = *gen; |
717 | | } |
718 | | gen_to_words (&arr[0], 4, 11); |
719 | | memcpy (&dv, &arr[0], sizeof (double)); |
720 | | sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv); |
721 | | gen_to_words (&arr[0], 2, 8); |
722 | | memcpy (&fv, &arr[0], sizeof (float)); |
723 | | sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv); |
724 | | |
725 | | if (gen) |
726 | | generic_floating_point_number = f; |
727 | | |
728 | | return (sbuf); |
729 | | } |
730 | | #endif |
731 | | |
732 | | /* This is a utility function called from various tc-*.c files. It |
733 | | is here in order to reduce code duplication. |
734 | | |
735 | | Turn a string at input_line_pointer into a floating point constant |
736 | | of type TYPE (a character found in the FLT_CHARS macro), and store |
737 | | it as LITTLENUMS in the bytes buffer LITP. The number of chars |
738 | | emitted is stored in *SIZEP. BIG_WORDIAN is TRUE if the littlenums |
739 | | should be emitted most significant littlenum first. |
740 | | |
741 | | An error message is returned, or a NULL pointer if everything went OK. */ |
742 | | |
743 | | const char * |
744 | | ieee_md_atof (int type, |
745 | | char *litP, |
746 | | int *sizeP, |
747 | | bool big_wordian) |
748 | 1.88k | { |
749 | 1.88k | LITTLENUM_TYPE words[MAX_LITTLENUMS]; |
750 | 1.88k | LITTLENUM_TYPE *wordP; |
751 | 1.88k | char *t; |
752 | 1.88k | int prec = 0, pad = 0; |
753 | | |
754 | 1.88k | if (strchr (FLT_CHARS, type) != NULL) |
755 | 1.88k | { |
756 | 1.88k | switch (type) |
757 | 1.88k | { |
758 | 0 | case 'H': |
759 | 0 | case 'h': |
760 | 0 | prec = H_PRECISION; |
761 | 0 | break; |
762 | | |
763 | 0 | case 'B': |
764 | 0 | case 'b': |
765 | 0 | prec = B_PRECISION; |
766 | 0 | break; |
767 | | |
768 | 1.88k | case 'f': |
769 | 1.88k | case 'F': |
770 | 1.88k | case 's': |
771 | 1.88k | case 'S': |
772 | 1.88k | prec = F_PRECISION; |
773 | 1.88k | break; |
774 | | |
775 | 0 | case 'd': |
776 | 0 | case 'D': |
777 | 0 | case 'r': |
778 | 0 | case 'R': |
779 | 0 | prec = D_PRECISION; |
780 | 0 | break; |
781 | | |
782 | 0 | case 't': |
783 | 0 | case 'T': |
784 | 0 | prec = X_PRECISION; |
785 | 0 | pad = X_PRECISION_PAD; |
786 | 0 | type = 'x'; /* This is what atof_ieee() understands. */ |
787 | 0 | break; |
788 | | |
789 | 0 | case 'x': |
790 | 0 | case 'X': |
791 | 0 | case 'p': |
792 | 0 | case 'P': |
793 | | #ifdef TC_M68K |
794 | | /* Note: on the m68k there is a gap of 16 bits (one littlenum) |
795 | | between the exponent and mantissa. Hence the precision is |
796 | | 6 and not 5. */ |
797 | | prec = P_PRECISION + 1; |
798 | | #else |
799 | 0 | prec = P_PRECISION; |
800 | 0 | #endif |
801 | 0 | pad = P_PRECISION_PAD; |
802 | 0 | break; |
803 | | |
804 | 0 | default: |
805 | 0 | break; |
806 | 1.88k | } |
807 | 1.88k | } |
808 | | /* The 'f' and 'd' types are always recognised, even if the target has |
809 | | not put them into the FLT_CHARS macro. This is because the 'f' type |
810 | | can come from the .dc.s, .dcb.s, .float or .single pseudo-ops and the |
811 | | 'd' type from the .dc.d, .dbc.d or .double pseudo-ops. |
812 | | |
813 | | The 'x' type is not implicitly recognised however, even though it can |
814 | | be generated by the .dc.x and .dbc.x pseudo-ops because not all targets |
815 | | can support floating point values that big. ie the target has to |
816 | | explicitly allow them by putting them into FLT_CHARS. */ |
817 | 0 | else if (type == 'f') |
818 | 0 | prec = F_PRECISION; |
819 | 0 | else if (type == 'd') |
820 | 0 | prec = D_PRECISION; |
821 | | |
822 | 1.88k | if (prec == 0) |
823 | 0 | { |
824 | 0 | *sizeP = 0; |
825 | 0 | return _("Unrecognized or unsupported floating point constant"); |
826 | 0 | } |
827 | | |
828 | 1.88k | gas_assert (prec <= MAX_LITTLENUMS); |
829 | | |
830 | 1.88k | t = atof_ieee (input_line_pointer, type, words); |
831 | 1.88k | if (t) |
832 | 1.87k | input_line_pointer = t; |
833 | | |
834 | 1.88k | *sizeP = (prec + pad) * sizeof (LITTLENUM_TYPE); |
835 | | |
836 | 1.88k | if (big_wordian) |
837 | 0 | { |
838 | 0 | for (wordP = words; prec --;) |
839 | 0 | { |
840 | 0 | md_number_to_chars (litP, (valueT) (* wordP ++), sizeof (LITTLENUM_TYPE)); |
841 | 0 | litP += sizeof (LITTLENUM_TYPE); |
842 | 0 | } |
843 | 0 | } |
844 | 1.88k | else |
845 | 1.88k | { |
846 | 5.64k | for (wordP = words + prec; prec --;) |
847 | 3.76k | { |
848 | 3.76k | md_number_to_chars (litP, (valueT) (* -- wordP), sizeof (LITTLENUM_TYPE)); |
849 | 3.76k | litP += sizeof (LITTLENUM_TYPE); |
850 | 3.76k | } |
851 | 1.88k | } |
852 | | |
853 | 1.88k | memset (litP, 0, pad * sizeof (LITTLENUM_TYPE)); |
854 | 1.88k | litP += pad * sizeof (LITTLENUM_TYPE); |
855 | | |
856 | 1.88k | return NULL; |
857 | 1.88k | } |