1 /* atof_ns32k.c - turn a Flonum into a ns32k floating point number
2 Copyright (C) 1987 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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 1, or (at your option)
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.
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. */
20 /* this is atof-m68k.c hacked for ns32k */
24 extern FLONUM_TYPE generic_floating_point_number
; /* Flonums returned here. */
26 extern const char EXP_CHARS
[];
27 /* Precision in LittleNums. */
28 #define MAX_PRECISION (4)
29 #define F_PRECISION (2)
30 #define D_PRECISION (4)
32 /* Length in LittleNums of guard bits. */
35 int /* Number of chars in flonum type 'letter'. */
42 * Permitting uppercase letters is probably a bad idea.
43 * Please use only lower-cased letters in case the upper-cased
44 * ones become unsupported!
49 return_value
= F_PRECISION
;
53 return_value
= D_PRECISION
;
60 return (return_value
);
63 static unsigned long int mask
[] =
100 static int bits_left_in_littlenum
;
101 static int littlenums_left
;
102 static LITTLENUM_TYPE
*littlenum_pointer
;
105 next_bits (number_of_bits
)
110 if (!littlenums_left
)
112 if (number_of_bits
>= bits_left_in_littlenum
)
114 return_value
= mask
[bits_left_in_littlenum
] & *littlenum_pointer
;
115 number_of_bits
-= bits_left_in_littlenum
;
116 return_value
<<= number_of_bits
;
119 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
- number_of_bits
;
122 return_value
|= (*littlenum_pointer
>> bits_left_in_littlenum
) & mask
[number_of_bits
];
127 bits_left_in_littlenum
-= number_of_bits
;
128 return_value
= mask
[number_of_bits
] & (*littlenum_pointer
>> bits_left_in_littlenum
);
130 return (return_value
);
134 make_invalid_floating_point_number (words
)
135 LITTLENUM_TYPE
*words
;
137 words
[0] = ((unsigned) -1) >> 1; /* Zero the leftmost bit */
143 /***********************************************************************\
145 * Warning: this returns 16-bit LITTLENUMs, because that is *
146 * what the VAX thinks in. It is up to the caller to figure *
147 * out any alignment problems and to conspire for the bytes/word *
148 * to be emitted in the right order. Bigendians beware! *
150 \***********************************************************************/
152 char * /* Return pointer past text consumed. */
153 atof_ns32k (str
, what_kind
, words
)
154 char *str
; /* Text to convert to binary. */
155 char what_kind
; /* 'd', 'f', 'g', 'h' */
156 LITTLENUM_TYPE
*words
; /* Build the binary here. */
159 LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
160 /* Extra bits for zeroed low-order bits. */
161 /* The 1st MAX_PRECISION are zeroed, */
162 /* the last contain flonum bits. */
164 int precision
; /* Number of 16-bit words in the format. */
165 long int exponent_bits
;
171 int exponent_skippage
;
172 LITTLENUM_TYPE word1
;
176 f
.low
= bits
+ MAX_PRECISION
;
182 /* Use more LittleNums than seems */
183 /* necessary: the highest flonum may have */
184 /* 15 leading 0 bits, so could be useless. */
186 bzero (bits
, sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
191 precision
= F_PRECISION
;
196 precision
= D_PRECISION
;
201 make_invalid_floating_point_number (words
);
205 f
.high
= f
.low
+ precision
- 1 + GUARD
;
207 if (atof_generic (&return_value
, ".", EXP_CHARS
, &f
))
209 as_warn ("Error converting floating point number (Exponent overflow?)");
210 make_invalid_floating_point_number (words
);
214 if (f
.low
> f
.leader
)
217 bzero (words
, sizeof (LITTLENUM_TYPE
) * precision
);
221 if (f
.sign
!= '+' && f
.sign
!= '-')
223 make_invalid_floating_point_number (words
);
229 * All vaxen floating_point formats (so far) have:
230 * Bit 15 is sign bit.
231 * Bits 14:n are excess-whatever exponent.
232 * Bits n-1:0 (if any) are most significant bits of fraction.
233 * Bits 15:0 of the next word are the next most significant bits.
234 * And so on for each other word.
236 * So we need: number of bits of exponent, number of bits of
239 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
;
240 littlenum_pointer
= f
.leader
;
241 littlenums_left
= 1 + f
.leader
- f
.low
;
242 /* Seek (and forget) 1st significant bit */
243 for (exponent_skippage
= 0; !next_bits (1); exponent_skippage
++)
245 exponent_1
= f
.exponent
+ f
.leader
+ 1 - f
.low
;
246 /* Radix LITTLENUM_RADIX, point just higher than f.leader. */
247 exponent_2
= exponent_1
* LITTLENUM_NUMBER_OF_BITS
;
249 exponent_3
= exponent_2
- exponent_skippage
;
250 /* Forget leading zeros, forget 1st bit. */
251 exponent_4
= exponent_3
+ ((1 << (exponent_bits
- 1)) - 2);
252 /* Offset exponent. */
254 if (exponent_4
& ~mask
[exponent_bits
])
257 * Exponent overflow. Lose immediately.
261 * We leave return_value alone: admit we read the
262 * number, but return a floating exception
263 * because we can't encode the number.
266 as_warn ("Exponent overflow in floating-point number");
267 make_invalid_floating_point_number (words
);
272 /* Word 1. Sign, exponent and perhaps high bits. */
273 /* Assume 2's complement integers. */
274 word1
= ((exponent_4
& mask
[exponent_bits
]) << (15 - exponent_bits
)) |
275 ((f
.sign
== '+') ? 0 : 0x8000) | next_bits (15 - exponent_bits
);
278 /* The rest of the words are just mantissa bits. */
279 for (; lp
< words
+ precision
; lp
++)
280 *lp
= next_bits (LITTLENUM_NUMBER_OF_BITS
);
284 unsigned long int carry
;
286 * Since the NEXT bit is a 1, round UP the mantissa.
287 * The cunning design of these hidden-1 floats permits
288 * us to let the mantissa overflow into the exponent, and
289 * it 'does the right thing'. However, we lose if the
290 * highest-order bit of the lowest-order word flips.
295 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
296 Please allow at least 1 more bit in carry than is in a LITTLENUM.
297 We need that extra bit to hold a carry during a LITTLENUM carry
298 propagation. Another extra bit (kept 0) will assure us that we
299 don't get a sticky sign bit after shifting right, and that
300 permits us to propagate the carry without any masking of bits.
302 for (carry
= 1, lp
--; carry
&& (lp
>= words
); lp
--)
306 carry
>>= LITTLENUM_NUMBER_OF_BITS
;
308 if ((word1
^ *words
) & (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)))
310 /* We leave return_value alone: admit we read the
311 * number, but return a floating exception
312 * because we can't encode the number.
314 make_invalid_floating_point_number (words
);
318 return (return_value
);
321 /* This is really identical to atof_ns32k except for some details */
323 gen_to_words (words
, precision
, exponent_bits
)
324 LITTLENUM_TYPE
*words
;
325 long int exponent_bits
;
327 int return_value
= 0;
333 int exponent_skippage
;
334 LITTLENUM_TYPE word1
;
337 if (generic_floating_point_number
.low
> generic_floating_point_number
.leader
)
340 bzero (words
, sizeof (LITTLENUM_TYPE
) * precision
);
345 * All vaxen floating_point formats (so far) have:
346 * Bit 15 is sign bit.
347 * Bits 14:n are excess-whatever exponent.
348 * Bits n-1:0 (if any) are most significant bits of fraction.
349 * Bits 15:0 of the next word are the next most significant bits.
350 * And so on for each other word.
352 * So we need: number of bits of exponent, number of bits of
355 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
;
356 littlenum_pointer
= generic_floating_point_number
.leader
;
357 littlenums_left
= 1 + generic_floating_point_number
.leader
- generic_floating_point_number
.low
;
358 /* Seek (and forget) 1st significant bit */
359 for (exponent_skippage
= 0; !next_bits (1); exponent_skippage
++)
361 exponent_1
= generic_floating_point_number
.exponent
+ generic_floating_point_number
.leader
+ 1 -
362 generic_floating_point_number
.low
;
363 /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */
364 exponent_2
= exponent_1
* LITTLENUM_NUMBER_OF_BITS
;
366 exponent_3
= exponent_2
- exponent_skippage
;
367 /* Forget leading zeros, forget 1st bit. */
368 exponent_4
= exponent_3
+ ((1 << (exponent_bits
- 1)) - 2);
369 /* Offset exponent. */
371 if (exponent_4
& ~mask
[exponent_bits
])
374 * Exponent overflow. Lose immediately.
378 * We leave return_value alone: admit we read the
379 * number, but return a floating exception
380 * because we can't encode the number.
383 make_invalid_floating_point_number (words
);
388 /* Word 1. Sign, exponent and perhaps high bits. */
389 /* Assume 2's complement integers. */
390 word1
= ((exponent_4
& mask
[exponent_bits
]) << (15 - exponent_bits
)) |
391 ((generic_floating_point_number
.sign
== '+') ? 0 : 0x8000) | next_bits (15 - exponent_bits
);
394 /* The rest of the words are just mantissa bits. */
395 for (; lp
< words
+ precision
; lp
++)
396 *lp
= next_bits (LITTLENUM_NUMBER_OF_BITS
);
400 unsigned long int carry
;
402 * Since the NEXT bit is a 1, round UP the mantissa.
403 * The cunning design of these hidden-1 floats permits
404 * us to let the mantissa overflow into the exponent, and
405 * it 'does the right thing'. However, we lose if the
406 * highest-order bit of the lowest-order word flips.
411 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
412 Please allow at least 1 more bit in carry than is in a LITTLENUM.
413 We need that extra bit to hold a carry during a LITTLENUM carry
414 propagation. Another extra bit (kept 0) will assure us that we
415 don't get a sticky sign bit after shifting right, and that
416 permits us to propagate the carry without any masking of bits.
418 for (carry
= 1, lp
--; carry
&& (lp
>= words
); lp
--)
422 carry
>>= LITTLENUM_NUMBER_OF_BITS
;
424 if ((word1
^ *words
) & (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)))
426 /* We leave return_value alone: admit we read the
427 * number, but return a floating exception
428 * because we can't encode the number.
430 make_invalid_floating_point_number (words
);
434 return (return_value
);
437 /* This routine is a real kludge. Someone really should do it better, but
438 I'm too lazy, and I don't understand this stuff all too well anyway
448 sprintf (buf
, "%ld", x
);
450 if (atof_generic (&bufp
, ".", EXP_CHARS
, &generic_floating_point_number
))
451 as_warn ("Error converting number to floating point (Exponent overflow?)");