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