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