source: trunk/binutils/gas/config/atof-vax.c@ 2446

Last change on this file since 2446 was 10, checked in by bird, 22 years ago

Initial revision

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