Initial import from FreeBSD RELENG_4:
[dragonfly.git] / gnu / usr.bin / as / config / atof-vax.c
1 /* atof_vax.c - turn a Flonum into a VAX 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 /* JF added these two for md_atof() */
21 #include "as.h"
22
23 /* Precision in LittleNums. */
24 #define MAX_PRECISION (8)
25 #define H_PRECISION (8)
26 #define G_PRECISION (4)
27 #define D_PRECISION (4)
28 #define F_PRECISION (2)
29
30 /* Length in LittleNums of guard bits. */
31 #define GUARD (2)
32
33 #if __STDC__ == 1
34
35 int flonum_gen2vax(int format_letter, FLONUM_TYPE *f, LITTLENUM_TYPE *words);
36
37 #else /* not __STDC__ */
38
39 int flonum_gen2vax();
40
41 #endif /* not __STDC__ */
42
43 int                             /* Number of chars in flonum type 'letter'. */
44     atof_vax_sizeof (letter)
45 char letter;
46 {
47         int     return_value;
48
49         /*
50          * Permitting uppercase letters is probably a bad idea.
51          * Please use only lower-cased letters in case the upper-cased
52          * ones become unsupported!
53          */
54         switch (letter)
55             {
56             case 'f':
57             case 'F':
58                     return_value = 4;
59                     break;
60
61             case 'd':
62             case 'D':
63             case 'g':
64             case 'G':
65                     return_value = 8;
66                     break;
67
68             case 'h':
69             case 'H':
70                     return_value = 16;
71                     break;
72
73             default:
74                     return_value = 0;
75                     break;
76             }
77         return (return_value);
78 } /* atof_vax_sizeof */
79
80 static const long mask[] = {
81         0x00000000,
82         0x00000001,
83         0x00000003,
84         0x00000007,
85         0x0000000f,
86         0x0000001f,
87         0x0000003f,
88         0x0000007f,
89         0x000000ff,
90         0x000001ff,
91         0x000003ff,
92         0x000007ff,
93         0x00000fff,
94         0x00001fff,
95         0x00003fff,
96         0x00007fff,
97         0x0000ffff,
98         0x0001ffff,
99         0x0003ffff,
100         0x0007ffff,
101         0x000fffff,
102         0x001fffff,
103         0x003fffff,
104         0x007fffff,
105         0x00ffffff,
106         0x01ffffff,
107         0x03ffffff,
108         0x07ffffff,
109         0x0fffffff,
110         0x1fffffff,
111         0x3fffffff,
112         0x7fffffff,
113         0xffffffff
114     };
115 \f
116
117 /* Shared between flonum_gen2vax and next_bits */
118 static int              bits_left_in_littlenum;
119 static LITTLENUM_TYPE * littlenum_pointer;
120 static LITTLENUM_TYPE * littlenum_end;
121
122 static int
123     next_bits (number_of_bits)
124 int             number_of_bits;
125 {
126         int                     return_value;
127
128         if (littlenum_pointer<littlenum_end)
129             return 0;
130         if (number_of_bits >= bits_left_in_littlenum)
131             {
132                     return_value  = mask[bits_left_in_littlenum] & * littlenum_pointer;
133                     number_of_bits -= bits_left_in_littlenum;
134                     return_value <<= number_of_bits;
135                     bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
136                     littlenum_pointer --;
137                     if (littlenum_pointer >= littlenum_end)
138                         return_value |= ( (* littlenum_pointer) >> (bits_left_in_littlenum) ) & mask[number_of_bits];
139             }
140         else
141             {
142                     bits_left_in_littlenum -= number_of_bits;
143                     return_value = mask[number_of_bits] & ( (* littlenum_pointer) >> bits_left_in_littlenum);
144             }
145         return (return_value);
146 }
147
148 static void
149     make_invalid_floating_point_number (words)
150 LITTLENUM_TYPE *        words;
151 {
152         * words = 0x8000;               /* Floating Reserved Operand Code */
153 }
154 \f
155 static int                      /* 0 means letter is OK. */
156     what_kind_of_float (letter, precisionP, exponent_bitsP)
157 char            letter; /* In: lowercase please. What kind of float? */
158 int *           precisionP; /* Number of 16-bit words in the float. */
159 long *          exponent_bitsP; /* Number of exponent bits. */
160 {
161         int     retval;                 /* 0: OK. */
162
163         retval = 0;
164         switch (letter)
165             {
166             case 'f':
167                     * precisionP = F_PRECISION;
168                     * exponent_bitsP = 8;
169                     break;
170
171             case 'd':
172                     * precisionP = D_PRECISION;
173                     * exponent_bitsP = 8;
174                     break;
175
176             case 'g':
177                     * precisionP = G_PRECISION;
178                     * exponent_bitsP = 11;
179                     break;
180
181             case 'h':
182                     * precisionP = H_PRECISION;
183                     * exponent_bitsP = 15;
184                     break;
185
186             default:
187                     retval = 69;
188                     break;
189             }
190         return (retval);
191 }
192 \f
193 /***********************************************************************\
194  *                                                                      *
195  *      Warning: this returns 16-bit LITTLENUMs, because that is        *
196  *      what the VAX thinks in. It is up to the caller to figure        *
197  *      out any alignment problems and to conspire for the bytes/word   *
198  *      to be emitted in the right order. Bigendians beware!            *
199  *                                                                      *
200  \***********************************************************************/
201
202 char * /* Return pointer past text consumed. */
203     atof_vax(str, what_kind, words)
204 char *str; /* Text to convert to binary. */
205 char what_kind; /* 'd', 'f', 'g', 'h' */
206 LITTLENUM_TYPE *words; /* Build the binary here. */
207 {
208         FLONUM_TYPE f;
209         LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
210         /* Extra bits for zeroed low-order bits. */
211         /* The 1st MAX_PRECISION are zeroed, */
212         /* the last contain flonum bits. */
213         char *return_value;
214         int precision; /* Number of 16-bit words in the format. */
215         long exponent_bits;
216
217         return_value = str;
218         f.low = bits + MAX_PRECISION;
219         f.high = NULL;
220         f.leader = NULL;
221         f.exponent = NULL;
222         f.sign = '\0';
223
224         if (what_kind_of_float (what_kind, & precision, & exponent_bits)) {
225                 return_value = NULL; /* We lost. */
226                 make_invalid_floating_point_number (words);
227         }
228
229         if (return_value) {
230                 memset(bits, '\0', sizeof(LITTLENUM_TYPE) * MAX_PRECISION);
231
232                 /* Use more LittleNums than seems */
233                 /* necessary: the highest flonum may have */
234                 /* 15 leading 0 bits, so could be useless. */
235                 f.high = f.low + precision - 1 + GUARD;
236
237                 if (atof_generic (& return_value, ".", "eE", & f)) {
238                         make_invalid_floating_point_number (words);
239                         return_value = NULL;    /* we lost */
240                 } else {
241                         if (flonum_gen2vax(what_kind, & f, words)) {
242                                 return_value = NULL;
243                         }
244                 }
245         }
246         return(return_value);
247 } /* atof_vax() */
248 \f
249 /*
250  * In: a flonum, a vax floating point format.
251  * Out: a vax floating-point bit pattern.
252  */
253
254 int                             /* 0: OK. */
255     flonum_gen2vax (format_letter, f, words)
256 char format_letter; /* One of 'd' 'f' 'g' 'h'. */
257 FLONUM_TYPE *f;
258 LITTLENUM_TYPE *words;  /* Deliver answer here. */
259 {
260         LITTLENUM_TYPE *lp;
261         int precision;
262         long exponent_bits;
263         int return_value; /* 0 == OK. */
264
265         return_value = what_kind_of_float(format_letter, &precision, &exponent_bits);
266
267         if (return_value != 0) {
268                 make_invalid_floating_point_number (words);
269         } else {
270                 if (f->low > f->leader) {
271                         /* 0.0e0 seen. */
272 memset(words, '\0', sizeof(LITTLENUM_TYPE) * precision);
273                 } else {
274                         long exponent_1;
275                         long exponent_2;
276                         long exponent_3;
277                         long exponent_4;
278                         int exponent_skippage;
279                         LITTLENUM_TYPE word1;
280
281                         /* JF: Deal with new Nan, +Inf and -Inf codes */
282                         if (f->sign != '-' && f->sign != '+') {
283                                 make_invalid_floating_point_number(words);
284                                 return return_value;
285                         }
286                         /*
287                          * All vaxen floating_point formats (so far) have:
288                          * Bit 15 is sign bit.
289                          * Bits 14:n are excess-whatever exponent.
290                          * Bits n-1:0 (if any) are most significant bits of fraction.
291                          * Bits 15:0 of the next word are the next most significant bits.
292                          * And so on for each other word.
293                          *
294                          * All this to be compatible with a KF11?? (Which is still faster
295                          * than lots of vaxen I can think of, but it also has higher
296                          * maintenance costs ... sigh).
297                          *
298                          * So we need: number of bits of exponent, number of bits of
299                          * mantissa.
300                          */
301
302 #ifdef NEVER  /******* This zeroing seems redundant - Dean 3may86 **********/
303                         /*
304                          * No matter how few bits we got back from the atof()
305                          * routine, add enough zero littlenums so the rest of the
306                          * code won't run out of "significant" bits in the mantissa.
307                          */
308                         {
309                                 LITTLENUM_TYPE *ltp;
310                                 for (ltp = f->leader + 1;
311                                      ltp <= f->low + precision;
312                                      ltp++) {
313                                         *ltp = 0;
314                                 }
315                         }
316 #endif
317
318                         bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
319                         littlenum_pointer = f->leader;
320                         littlenum_end = f->low;
321                         /* Seek (and forget) 1st significant bit */
322                         for (exponent_skippage = 0;
323                              ! next_bits(1);
324                              exponent_skippage ++) ;;
325
326                         exponent_1 = f->exponent + f->leader + 1 - f->low;
327                         /* Radix LITTLENUM_RADIX, point just higher than f->leader. */
328                         exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
329                         /* Radix 2. */
330                         exponent_3 = exponent_2 - exponent_skippage;
331                         /* Forget leading zeros, forget 1st bit. */
332                         exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
333                         /* Offset exponent. */
334
335                         if (exponent_4 & ~mask[exponent_bits]) {
336                                 /*
337                                  * Exponent overflow. Lose immediately.
338                                  */
339
340                                 make_invalid_floating_point_number (words);
341
342                                 /*
343                                  * We leave return_value alone: admit we read the
344                                  * number, but return a floating exception
345                                  * because we can't encode the number.
346                                  */
347                         } else {
348                                 lp = words;
349
350                                 /* Word 1. Sign, exponent and perhaps high bits. */
351                                 /* Assume 2's complement integers. */
352                                 word1 = (((exponent_4 &mask[exponent_bits]) << (15 - exponent_bits))
353                                          | ((f->sign == '+') ? 0 : 0x8000)
354                                          | next_bits(15 - exponent_bits));
355                                 *lp++ = word1;
356
357                                 /* The rest of the words are just mantissa bits. */
358                                 for (; lp < words + precision; lp++) {
359                                         *lp = next_bits(LITTLENUM_NUMBER_OF_BITS);
360                                 }
361
362                                 if (next_bits (1)) {
363                                         /*
364                                          * Since the NEXT bit is a 1, round UP the mantissa.
365                                          * The cunning design of these hidden-1 floats permits
366                                          * us to let the mantissa overflow into the exponent, and
367                                          * it 'does the right thing'. However, we lose if the
368                                          * highest-order bit of the lowest-order word flips.
369                                          * Is that clear?
370                                          */
371
372                                         unsigned long carry;
373
374                                         /*
375                                           #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
376                                           Please allow at least 1 more bit in carry than is in a LITTLENUM.
377                                           We need that extra bit to hold a carry during a LITTLENUM carry
378                                           propagation. Another extra bit (kept 0) will assure us that we
379                                           don't get a sticky sign bit after shifting right, and that
380                                           permits us to propagate the carry without any masking of bits.
381                                           #endif
382                                           */
383                                         for (carry = 1, lp--;
384                                              carry && (lp >= words);
385                                              lp--) {
386                                                 carry = *lp + carry;
387                                                 *lp = carry;
388                                                 carry >>= LITTLENUM_NUMBER_OF_BITS;
389                                         }
390
391                                         if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) {
392                                                 make_invalid_floating_point_number(words);
393                                                 /*
394                                                  * We leave return_value alone: admit we read the
395                                                  * number, but return a floating exception
396                                                  * because we can't encode the number.
397                                                  */
398                                         }
399                                 } /* if (we needed to round up) */
400                         } /* if (exponent overflow) */
401                 } /* if (0.0e0) */
402         } /* if (float_type was OK) */
403         return(return_value);
404 } /* flonum_gen2vax() */
405
406
407 /* JF this used to be in vax.c but this looks like a better place for it */
408
409 /*
410  *              md_atof()
411  *
412  * In:  input_line_pointer->the 1st character of a floating-point
413  *              number.
414  *      1 letter denoting the type of statement that wants a
415  *              binary floating point number returned.
416  *      Address of where to build floating point literal.
417  *              Assumed to be 'big enough'.
418  *      Address of where to return size of literal (in chars).
419  *
420  * Out: Input_line_pointer->of next char after floating number.
421  *      Error message, or "".
422  *      Floating point literal.
423  *      Number of chars we used for the literal.
424  */
425
426 #define MAXIMUM_NUMBER_OF_LITTLENUMS (8) /* For .hfloats. */
427
428 char *
429     md_atof (what_statement_type, literalP, sizeP)
430 char    what_statement_type;
431 char *  literalP;
432 int *   sizeP;
433 {
434         LITTLENUM_TYPE  words[MAXIMUM_NUMBER_OF_LITTLENUMS];
435         register char           kind_of_float;
436         register int            number_of_chars;
437         register LITTLENUM_TYPE * littlenum_pointer;
438
439         switch (what_statement_type)
440             {
441             case 'F':                   /* .float */
442             case 'f':                   /* .ffloat */
443                     kind_of_float = 'f';
444                     break;
445
446             case 'D':                   /* .double */
447             case 'd':                   /* .dfloat */
448                     kind_of_float = 'd';
449                     break;
450
451             case 'g':                   /* .gfloat */
452                     kind_of_float = 'g';
453                     break;
454
455             case 'h':                   /* .hfloat */
456                     kind_of_float = 'h';
457                     break;
458
459             default:
460                     kind_of_float = 0;
461                     break;
462             };
463
464         if (kind_of_float)
465             {
466                     register LITTLENUM_TYPE * limit;
467
468                     input_line_pointer = atof_vax (input_line_pointer,
469                                                    kind_of_float,
470                                                    words);
471                     /*
472                      * The atof_vax() builds up 16-bit numbers.
473                      * Since the assembler may not be running on
474                      * a little-endian machine, be very careful about
475                      * converting words to chars.
476                      */
477                     number_of_chars = atof_vax_sizeof (kind_of_float);
478                     know( number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof(LITTLENUM_TYPE) );
479                     limit = words + (number_of_chars / sizeof(LITTLENUM_TYPE));
480                     for (littlenum_pointer = words;
481                          littlenum_pointer < limit;
482                          littlenum_pointer ++)
483                         {
484                                 md_number_to_chars (literalP, * littlenum_pointer, sizeof(LITTLENUM_TYPE));
485                                 literalP += sizeof(LITTLENUM_TYPE);
486                         };
487             }
488         else
489             {
490                     number_of_chars = 0;
491             };
492
493         * sizeP = number_of_chars;
494         return (kind_of_float ? "" : "Bad call to md_atof()");
495 }                               /* md_atof() */
496
497 /* end of atof-vax.c */