Flag error if absolute constant is too large for an immediate field.
[deliverable/binutils-gdb.git] / gas / config / atof-ieee.c
1 /* atof_ieee.c - turn a Flonum into an IEEE floating point number
2 Copyright (C) 1987, 1992 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 2, 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
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "as.h"
21
22 #ifdef USG
23 #define bzero(s,n) memset(s,0,n)
24 #define bcopy(from,to,n) memcpy((to),(from),(n))
25 #endif
26
27 extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */
28
29 #ifndef NULL
30 #define NULL (0)
31 #endif
32
33 extern char EXP_CHARS[];
34 /* Precision in LittleNums. */
35 #define MAX_PRECISION (6)
36 #define F_PRECISION (2)
37 #define D_PRECISION (4)
38 #define X_PRECISION (6)
39 #define P_PRECISION (6)
40
41 /* Length in LittleNums of guard bits. */
42 #define GUARD (2)
43
44 static unsigned long mask [] = {
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 \f
80
81 static int bits_left_in_littlenum;
82 static int littlenums_left;
83 static LITTLENUM_TYPE *littlenum_pointer;
84
85 static int
86 next_bits (number_of_bits)
87 int number_of_bits;
88 {
89 int return_value;
90
91 if (!littlenums_left)
92 return(0);
93 if (number_of_bits >= bits_left_in_littlenum) {
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 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
100 --littlenum_pointer;
101 return_value |= (*littlenum_pointer >> bits_left_in_littlenum) & mask[number_of_bits];
102 }
103 } else {
104 bits_left_in_littlenum -= number_of_bits;
105 return_value = mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
106 }
107 return(return_value);
108 }
109
110 /* Num had better be less than LITTLENUM_NUMBER_OF_BITS */
111 static void
112 unget_bits(num)
113 int num;
114 {
115 if (!littlenums_left) {
116 ++littlenum_pointer;
117 ++littlenums_left;
118 bits_left_in_littlenum = num;
119 } else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS) {
120 bits_left_in_littlenum = num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
121 ++littlenum_pointer;
122 ++littlenums_left;
123 } else
124 bits_left_in_littlenum += num;
125 }
126
127 static void
128 make_invalid_floating_point_number(words)
129 LITTLENUM_TYPE *words;
130 {
131 as_bad("cannot create floating-point number");
132 words[0] = ((unsigned) -1) >> 1; /* Zero the leftmost bit */
133 words[1] = -1;
134 words[2] = -1;
135 words[3] = -1;
136 words[4] = -1;
137 words[5] = -1;
138 }
139 \f
140 /***********************************************************************\
141 * Warning: this returns 16-bit LITTLENUMs. It is up to the caller *
142 * to figure out any alignment problems and to conspire for the *
143 * bytes/word to be emitted in the right order. Bigendians beware! *
144 * *
145 \***********************************************************************/
146
147 /* Note that atof-ieee always has X and P precisions enabled. it is up
148 to md_atof to filter them out if the target machine does not support
149 them. */
150
151 char * /* Return pointer past text consumed. */
152 atof_ieee(str, what_kind, words)
153 char *str; /* Text to convert to binary. */
154 char what_kind; /* 'd', 'f', 'g', 'h' */
155 LITTLENUM_TYPE *words; /* Build the binary here. */
156 {
157 static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
158 /* Extra bits for zeroed low-order bits. */
159 /* The 1st MAX_PRECISION are zeroed, */
160 /* the last contain flonum bits. */
161 char *return_value;
162 int precision; /* Number of 16-bit words in the format. */
163 long exponent_bits;
164 FLONUM_TYPE save_gen_flonum;
165
166 /* We have to save the generic_floating_point_number because it
167 contains storage allocation about the array of LITTLENUMs
168 where the value is actually stored. We will allocate our
169 own array of littlenums below, but have to restore the global
170 one on exit. */
171 save_gen_flonum = generic_floating_point_number;
172
173 return_value = str;
174 generic_floating_point_number.low = bits + MAX_PRECISION;
175 generic_floating_point_number.high = NULL;
176 generic_floating_point_number.leader = NULL;
177 generic_floating_point_number.exponent = NULL;
178 generic_floating_point_number.sign = '\0';
179
180 /* Use more LittleNums than seems */
181 /* necessary: the highest flonum may have */
182 /* 15 leading 0 bits, so could be useless. */
183
184 bzero(bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION);
185
186 switch (what_kind) {
187 case 'f':
188 case 'F':
189 case 's':
190 case 'S':
191 precision = F_PRECISION;
192 exponent_bits = 8;
193 break;
194
195 case 'd':
196 case 'D':
197 case 'r':
198 case 'R':
199 precision = D_PRECISION;
200 exponent_bits = 11;
201 break;
202
203 case 'x':
204 case 'X':
205 case 'e':
206 case 'E':
207 precision = X_PRECISION;
208 exponent_bits = 15;
209 break;
210
211 case 'p':
212 case 'P':
213
214 precision = P_PRECISION;
215 exponent_bits = -1;
216 break;
217
218 default:
219 make_invalid_floating_point_number(words);
220 return(NULL);
221 }
222
223 generic_floating_point_number.high = generic_floating_point_number.low + precision - 1 + GUARD;
224
225 if (atof_generic(&return_value, ".", EXP_CHARS, &generic_floating_point_number)) {
226 /* as_bad("Error converting floating point number (Exponent overflow?)"); */
227 make_invalid_floating_point_number(words);
228 return(NULL);
229 }
230 gen_to_words(words, precision, exponent_bits);
231
232 /* Restore the generic_floating_point_number's storage alloc
233 (and everything else). */
234 generic_floating_point_number = save_gen_flonum;
235
236 return(return_value);
237 }
238
239 /* Turn generic_floating_point_number into a real float/double/extended */
240 int gen_to_words(words, precision, exponent_bits)
241 LITTLENUM_TYPE *words;
242 int precision;
243 long exponent_bits;
244 {
245 int return_value = 0;
246
247 long exponent_1;
248 long exponent_2;
249 long exponent_3;
250 long exponent_4;
251 int exponent_skippage;
252 LITTLENUM_TYPE word1;
253 LITTLENUM_TYPE *lp;
254
255 if (generic_floating_point_number.low > generic_floating_point_number.leader) {
256 /* 0.0e0 seen. */
257 if (generic_floating_point_number.sign == '+')
258 words[0] = 0x0000;
259 else
260 words[0] = 0x8000;
261 bzero(&words[1], sizeof(LITTLENUM_TYPE) * (precision - 1));
262 return(return_value);
263 }
264
265 /* NaN: Do the right thing */
266 if (generic_floating_point_number.sign == 0) {
267 if (precision == F_PRECISION) {
268 words[0] = 0x7fff;
269 words[1] = 0xffff;
270 } else {
271 words[0] = 0x7fff;
272 words[1] = 0xffff;
273 words[2] = 0xffff;
274 words[3] = 0xffff;
275 }
276 return return_value;
277 } else if (generic_floating_point_number.sign == 'P') {
278 /* +INF: Do the right thing */
279 if (precision == F_PRECISION) {
280 words[0] = 0x7f80;
281 words[1] = 0;
282 } else {
283 words[0] = 0x7ff0;
284 words[1] = 0;
285 words[2] = 0;
286 words[3] = 0;
287 }
288 return(return_value);
289 } else if (generic_floating_point_number.sign == 'N') {
290 /* Negative INF */
291 if (precision == F_PRECISION) {
292 words[0] = 0xff80;
293 words[1] = 0x0;
294 } else {
295 words[0] = 0xfff0;
296 words[1] = 0x0;
297 words[2] = 0x0;
298 words[3] = 0x0;
299 }
300 return(return_value);
301 }
302 /*
303 * The floating point formats we support have:
304 * Bit 15 is sign bit.
305 * Bits 14:n are excess-whatever exponent.
306 * Bits n-1:0 (if any) are most significant bits of fraction.
307 * Bits 15:0 of the next word(s) are the next most significant bits.
308 *
309 * So we need: number of bits of exponent, number of bits of
310 * mantissa.
311 */
312 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
313 littlenum_pointer = generic_floating_point_number.leader;
314 littlenums_left = 1 + generic_floating_point_number.leader - generic_floating_point_number.low;
315 /* Seek (and forget) 1st significant bit */
316 for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) ;;
317 exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader
318 + 1 - generic_floating_point_number.low;
319 /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */
320 exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
321 /* Radix 2. */
322 exponent_3 = exponent_2 - exponent_skippage;
323 /* Forget leading zeros, forget 1st bit. */
324 exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
325 /* Offset exponent. */
326
327 lp = words;
328
329 /* Word 1. Sign, exponent and perhaps high bits. */
330 word1 = (generic_floating_point_number.sign == '+') ? 0 : (1 << (LITTLENUM_NUMBER_OF_BITS - 1));
331
332 /* Assume 2's complement integers. */
333 if (exponent_4 < 1 && exponent_4 >= -62) {
334 int prec_bits;
335 int num_bits;
336
337 unget_bits(1);
338 num_bits = -exponent_4;
339 prec_bits = LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
340 if(precision == X_PRECISION && exponent_bits == 15)
341 prec_bits -= LITTLENUM_NUMBER_OF_BITS + 1;
342
343 if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits) {
344 /* Bigger than one littlenum */
345 num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
346 *lp++ = word1;
347 if (num_bits + exponent_bits + 1 >= precision * LITTLENUM_NUMBER_OF_BITS) {
348 /* Exponent overflow */
349 make_invalid_floating_point_number(words);
350 return(return_value);
351 }
352 if (precision == X_PRECISION && exponent_bits == 15) {
353 *lp++ = 0;
354 *lp++ = 0;
355 num_bits -= LITTLENUM_NUMBER_OF_BITS - 1;
356 }
357 while (num_bits >= LITTLENUM_NUMBER_OF_BITS) {
358 num_bits -= LITTLENUM_NUMBER_OF_BITS;
359 *lp++ = 0;
360 }
361 if (num_bits)
362 *lp++ = next_bits(LITTLENUM_NUMBER_OF_BITS - (num_bits));
363 } else {
364 if (precision == X_PRECISION && exponent_bits == 15) {
365 *lp++ = word1;
366 *lp++ = 0;
367 if (num_bits == LITTLENUM_NUMBER_OF_BITS) {
368 *lp++ = 0;
369 *lp++ = next_bits(LITTLENUM_NUMBER_OF_BITS - 1);
370 } else if (num_bits == LITTLENUM_NUMBER_OF_BITS - 1)
371 *lp++ = 0;
372 else
373 *lp++ = next_bits(LITTLENUM_NUMBER_OF_BITS - 1 - num_bits);
374 num_bits = 0;
375 } else {
376 word1 |= next_bits((LITTLENUM_NUMBER_OF_BITS - 1) - (exponent_bits + num_bits));
377 *lp++ = word1;
378 }
379 }
380 while (lp < words + precision)
381 *lp++ = next_bits(LITTLENUM_NUMBER_OF_BITS);
382
383 /* Round the mantissa up, but don't change the number */
384 if (next_bits(1)) {
385 --lp;
386 if (prec_bits > LITTLENUM_NUMBER_OF_BITS) {
387 int n = 0;
388 int tmp_bits;
389
390 n = 0;
391 tmp_bits = prec_bits;
392 while (tmp_bits > LITTLENUM_NUMBER_OF_BITS) {
393 if (lp[n] != (LITTLENUM_TYPE) - 1)
394 break;
395 --n;
396 tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
397 }
398 if (tmp_bits > LITTLENUM_NUMBER_OF_BITS || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]) {
399 unsigned long carry;
400
401 for (carry = 1; carry && (lp >= words); lp --) {
402 carry = *lp + carry;
403 *lp = carry;
404 carry >>= LITTLENUM_NUMBER_OF_BITS;
405 }
406 }
407 } else if ((*lp & mask[prec_bits]) != mask[prec_bits])
408 lp++;
409 }
410
411 return return_value;
412 } else if (exponent_4 & ~ mask [exponent_bits]) {
413 /*
414 * Exponent overflow. Lose immediately.
415 */
416
417 /*
418 * We leave return_value alone: admit we read the
419 * number, but return a floating exception
420 * because we can't encode the number.
421 */
422 make_invalid_floating_point_number (words);
423 return return_value;
424 } else {
425 word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
426 | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
427 }
428
429 *lp++ = word1;
430
431 /* X_PRECISION is special: it has 16 bits of zero in the middle,
432 followed by a 1 bit. */
433 if (exponent_bits == 15 && precision == X_PRECISION) {
434 *lp++ = 0;
435 *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS) | next_bits(LITTLENUM_NUMBER_OF_BITS - 1);
436 }
437
438 /* The rest of the words are just mantissa bits. */
439 while(lp < words + precision)
440 *lp++ = next_bits(LITTLENUM_NUMBER_OF_BITS);
441
442 if (next_bits(1)) {
443 unsigned long carry;
444 /*
445 * Since the NEXT bit is a 1, round UP the mantissa.
446 * The cunning design of these hidden-1 floats permits
447 * us to let the mantissa overflow into the exponent, and
448 * it 'does the right thing'. However, we lose if the
449 * highest-order bit of the lowest-order word flips.
450 * Is that clear?
451 */
452
453 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
454 Please allow at least 1 more bit in carry than is in a LITTLENUM.
455 We need that extra bit to hold a carry during a LITTLENUM carry
456 propagation. Another extra bit (kept 0) will assure us that we
457 don't get a sticky sign bit after shifting right, and that
458 permits us to propagate the carry without any masking of bits.
459 #endif */
460 for (carry = 1, lp--; carry && (lp >= words); lp--) {
461 carry = *lp + carry;
462 *lp = carry;
463 carry >>= LITTLENUM_NUMBER_OF_BITS;
464 }
465 if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) {
466 /* We leave return_value alone: admit we read the
467 * number, but return a floating exception
468 * because we can't encode the number.
469 */
470 *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
471 /* make_invalid_floating_point_number (words); */
472 /* return return_value; */
473 }
474 }
475 return (return_value);
476 }
477
478 /* This routine is a real kludge. Someone really should do it better, but
479 I'm too lazy, and I don't understand this stuff all too well anyway
480 (JF)
481 */
482 void
483 int_to_gen(x)
484 long x;
485 {
486 char buf[20];
487 char *bufp;
488
489 sprintf(buf,"%ld",x);
490 bufp = &buf[0];
491 if (atof_generic(&bufp, ".", EXP_CHARS, &generic_floating_point_number))
492 as_bad("Error converting number to floating point (Exponent overflow?)");
493 }
494
495 #ifdef TEST
496 char *
497 print_gen(gen)
498 FLONUM_TYPE *gen;
499 {
500 FLONUM_TYPE f;
501 LITTLENUM_TYPE arr[10];
502 double dv;
503 float fv;
504 static char sbuf[40];
505
506 if (gen) {
507 f = generic_floating_point_number;
508 generic_floating_point_number = *gen;
509 }
510 gen_to_words(&arr[0], 4, 11);
511 bcopy(&arr[0], &dv, sizeof(double));
512 sprintf(sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv);
513 gen_to_words(&arr[0],2,8);
514 bcopy(&arr[0],&fv,sizeof(float));
515 sprintf(sbuf + strlen(sbuf), "%x %x %.12g\n", arr[0], arr[1],
516 fv);
517
518 if (gen) {
519 generic_floating_point_number = f;
520 }
521
522 return(sbuf);
523 }
524 #endif
525
526 /* end of atof-ieee.c */
This page took 0.041845 seconds and 4 git commands to generate.