White space and comments only. The devo tree prior to this delta is
[external/binutils.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 */