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