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
[] = {
99 static int bits_left_in_littlenum
;
100 static int littlenums_left
;
101 static LITTLENUM_TYPE
* littlenum_pointer
;
104 next_bits (number_of_bits
)
111 if (number_of_bits
>= bits_left_in_littlenum
)
113 return_value
= mask
[bits_left_in_littlenum
] & *littlenum_pointer
;
114 number_of_bits
-= bits_left_in_littlenum
;
115 return_value
<<= number_of_bits
;
116 if(littlenums_left
) {
117 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
- number_of_bits
;
118 littlenum_pointer
--;
120 return_value
|= (*littlenum_pointer
>>bits_left_in_littlenum
) & mask
[number_of_bits
];
125 bits_left_in_littlenum
-= number_of_bits
;
126 return_value
= mask
[number_of_bits
] & (*littlenum_pointer
>>bits_left_in_littlenum
);
128 return (return_value
);
132 make_invalid_floating_point_number (words
)
133 LITTLENUM_TYPE
* words
;
135 words
[0]= ((unsigned)-1)>>1; /* Zero the leftmost bit */
141 /***********************************************************************\
143 * Warning: this returns 16-bit LITTLENUMs, because that is *
144 * what the VAX thinks in. It is up to the caller to figure *
145 * out any alignment problems and to conspire for the bytes/word *
146 * to be emitted in the right order. Bigendians beware! *
148 \***********************************************************************/
150 char * /* Return pointer past text consumed. */
151 atof_ns32k (str
, what_kind
, words
)
152 char * str
; /* Text to convert to binary. */
153 char what_kind
; /* 'd', 'f', 'g', 'h' */
154 LITTLENUM_TYPE
* words
; /* Build the binary here. */
157 LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
158 /* Extra bits for zeroed low-order bits. */
159 /* The 1st MAX_PRECISION are zeroed, */
160 /* the last contain flonum bits. */
162 int precision
; /* Number of 16-bit words in the format. */
163 long int exponent_bits
;
169 int exponent_skippage
;
170 LITTLENUM_TYPE word1
;
174 f
.low
= bits
+ MAX_PRECISION
;
180 /* Use more LittleNums than seems */
181 /* necessary: the highest flonum may have */
182 /* 15 leading 0 bits, so could be useless. */
184 bzero (bits
, sizeof(LITTLENUM_TYPE
) * MAX_PRECISION
);
188 precision
= F_PRECISION
;
193 precision
= D_PRECISION
;
198 make_invalid_floating_point_number (words
);
202 f
.high
= f
.low
+ precision
- 1 + GUARD
;
204 if (atof_generic (& return_value
, ".", EXP_CHARS
, & f
)) {
205 as_warn("Error converting floating point number (Exponent overflow?)");
206 make_invalid_floating_point_number (words
);
210 if (f
.low
> f
.leader
) {
212 bzero (words
, sizeof(LITTLENUM_TYPE
) * precision
);
216 if(f
.sign
!='+' && f
.sign
!='-') {
217 make_invalid_floating_point_number(words
);
223 * All vaxen floating_point formats (so far) have:
224 * Bit 15 is sign bit.
225 * Bits 14:n are excess-whatever exponent.
226 * Bits n-1:0 (if any) are most significant bits of fraction.
227 * Bits 15:0 of the next word are the next most significant bits.
228 * And so on for each other word.
230 * So we need: number of bits of exponent, number of bits of
233 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
;
234 littlenum_pointer
= f
.leader
;
235 littlenums_left
= 1 + f
.leader
-f
.low
;
236 /* Seek (and forget) 1st significant bit */
237 for (exponent_skippage
= 0;! next_bits(1); exponent_skippage
++)
239 exponent_1
= f
.exponent
+ f
.leader
+ 1 - f
.low
;
240 /* Radix LITTLENUM_RADIX, point just higher than f.leader. */
241 exponent_2
= exponent_1
* LITTLENUM_NUMBER_OF_BITS
;
243 exponent_3
= exponent_2
- exponent_skippage
;
244 /* Forget leading zeros, forget 1st bit. */
245 exponent_4
= exponent_3
+ ((1 << (exponent_bits
- 1)) - 2);
246 /* Offset exponent. */
248 if (exponent_4
& ~ mask
[exponent_bits
]) {
250 * Exponent overflow. Lose immediately.
254 * We leave return_value alone: admit we read the
255 * number, but return a floating exception
256 * because we can't encode the number.
259 as_warn("Exponent overflow in floating-point number");
260 make_invalid_floating_point_number (words
);
265 /* Word 1. Sign, exponent and perhaps high bits. */
266 /* Assume 2's complement integers. */
267 word1
= ((exponent_4
& mask
[exponent_bits
]) << (15 - exponent_bits
)) |
268 ((f
.sign
== '+') ? 0 : 0x8000) | next_bits (15 - exponent_bits
);
271 /* The rest of the words are just mantissa bits. */
272 for (; lp
< words
+ precision
; lp
++)
273 * lp
= next_bits (LITTLENUM_NUMBER_OF_BITS
);
276 unsigned long int carry
;
278 * Since the NEXT bit is a 1, round UP the mantissa.
279 * The cunning design of these hidden-1 floats permits
280 * us to let the mantissa overflow into the exponent, and
281 * it 'does the right thing'. However, we lose if the
282 * highest-order bit of the lowest-order word flips.
287 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
288 Please allow at least 1 more bit in carry than is in a LITTLENUM.
289 We need that extra bit to hold a carry during a LITTLENUM carry
290 propagation. Another extra bit (kept 0) will assure us that we
291 don't get a sticky sign bit after shifting right, and that
292 permits us to propagate the carry without any masking of bits.
294 for (carry
= 1, lp
--; carry
&& (lp
>= words
); lp
--) {
295 carry
= * lp
+ carry
;
297 carry
>>= LITTLENUM_NUMBER_OF_BITS
;
299 if ( (word1
^ *words
) & (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)) ) {
300 /* We leave return_value alone: admit we read the
301 * number, but return a floating exception
302 * because we can't encode the number.
304 make_invalid_floating_point_number (words
);
308 return (return_value
);
311 /* This is really identical to atof_ns32k except for some details */
313 gen_to_words(words
,precision
,exponent_bits
)
314 LITTLENUM_TYPE
*words
;
315 long int exponent_bits
;
323 int exponent_skippage
;
324 LITTLENUM_TYPE word1
;
327 if (generic_floating_point_number
.low
> generic_floating_point_number
.leader
) {
329 bzero (words
, sizeof(LITTLENUM_TYPE
) * precision
);
334 * All vaxen floating_point formats (so far) have:
335 * Bit 15 is sign bit.
336 * Bits 14:n are excess-whatever exponent.
337 * Bits n-1:0 (if any) are most significant bits of fraction.
338 * Bits 15:0 of the next word are the next most significant bits.
339 * And so on for each other word.
341 * So we need: number of bits of exponent, number of bits of
344 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
;
345 littlenum_pointer
= generic_floating_point_number
.leader
;
346 littlenums_left
= 1+generic_floating_point_number
.leader
- generic_floating_point_number
.low
;
347 /* Seek (and forget) 1st significant bit */
348 for (exponent_skippage
= 0;! next_bits(1); exponent_skippage
++)
350 exponent_1
= generic_floating_point_number
.exponent
+ generic_floating_point_number
.leader
+ 1 -
351 generic_floating_point_number
.low
;
352 /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */
353 exponent_2
= exponent_1
* LITTLENUM_NUMBER_OF_BITS
;
355 exponent_3
= exponent_2
- exponent_skippage
;
356 /* Forget leading zeros, forget 1st bit. */
357 exponent_4
= exponent_3
+ ((1 << (exponent_bits
- 1)) - 2);
358 /* Offset exponent. */
360 if (exponent_4
& ~ mask
[exponent_bits
]) {
362 * Exponent overflow. Lose immediately.
366 * We leave return_value alone: admit we read the
367 * number, but return a floating exception
368 * because we can't encode the number.
371 make_invalid_floating_point_number (words
);
376 /* Word 1. Sign, exponent and perhaps high bits. */
377 /* Assume 2's complement integers. */
378 word1
= ((exponent_4
& mask
[exponent_bits
]) << (15 - exponent_bits
)) |
379 ((generic_floating_point_number
.sign
== '+') ? 0 : 0x8000) | next_bits (15 - exponent_bits
);
382 /* The rest of the words are just mantissa bits. */
383 for (; lp
< words
+ precision
; lp
++)
384 * lp
= next_bits (LITTLENUM_NUMBER_OF_BITS
);
387 unsigned long int carry
;
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.
398 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
399 Please allow at least 1 more bit in carry than is in a LITTLENUM.
400 We need that extra bit to hold a carry during a LITTLENUM carry
401 propagation. Another extra bit (kept 0) will assure us that we
402 don't get a sticky sign bit after shifting right, and that
403 permits us to propagate the carry without any masking of bits.
405 for (carry
= 1, lp
--; carry
&& (lp
>= words
); lp
--) {
406 carry
= * lp
+ carry
;
408 carry
>>= LITTLENUM_NUMBER_OF_BITS
;
410 if ( (word1
^ *words
) & (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)) ) {
411 /* We leave return_value alone: admit we read the
412 * number, but return a floating exception
413 * because we can't encode the number.
415 make_invalid_floating_point_number (words
);
419 return (return_value
);
422 /* This routine is a real kludge. Someone really should do it better, but
423 I'm too lazy, and I don't understand this stuff all too well anyway
432 sprintf(buf
,"%ld",x
);
434 if(atof_generic(&bufp
,".", EXP_CHARS
, &generic_floating_point_number
))
435 as_warn("Error converting number to floating point (Exponent overflow?)");