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