1 /* atof_tahoe.c - turn a string into a Tahoe floating point number
2 Copyright 1987, 1993, 2000 Free Software Foundation, Inc.
4 /* This is really a simplified version of atof_vax.c. I glommed it wholesale
5 and then shaved it down. I don't even know how it works. (Don't you find
6 my honesty refreshing? Devon E Bowen <bowen@cs.buffalo.edu>
8 I don't allow uppercase letters in the precision descrpitors.
9 i.e. 'f' and 'd' are allowed but 'F' and 'D' aren't. */
13 /* Precision in LittleNums. */
14 #define MAX_PRECISION (4)
15 #define D_PRECISION (4)
16 #define F_PRECISION (2)
18 /* Precision in chars. */
19 #define D_PRECISION_CHARS (8)
20 #define F_PRECISION_CHARS (4)
22 /* Length in LittleNums of guard bits. */
25 static const long int mask
[] =
62 /* Shared between flonum_gen2tahoe and next_bits. */
63 static int bits_left_in_littlenum
;
64 static LITTLENUM_TYPE
*littlenum_pointer
;
65 static LITTLENUM_TYPE
*littlenum_end
;
69 int flonum_gen2tahoe (int format_letter
, FLONUM_TYPE
* f
,
70 LITTLENUM_TYPE
* words
);
72 #else /* not __STDC__ */
74 int flonum_gen2tahoe ();
76 #endif /* not __STDC__ */
79 next_bits (number_of_bits
)
84 if (littlenum_pointer
< littlenum_end
)
86 if (number_of_bits
>= bits_left_in_littlenum
)
88 return_value
= mask
[bits_left_in_littlenum
] & *littlenum_pointer
;
89 number_of_bits
-= bits_left_in_littlenum
;
90 return_value
<<= number_of_bits
;
91 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
- number_of_bits
;
93 if (littlenum_pointer
>= littlenum_end
)
94 return_value
|= ((*littlenum_pointer
) >> (bits_left_in_littlenum
)) &
99 bits_left_in_littlenum
-= number_of_bits
;
100 return_value
= mask
[number_of_bits
] &
101 ((*littlenum_pointer
) >> bits_left_in_littlenum
);
107 make_invalid_floating_point_number (words
)
108 LITTLENUM_TYPE
*words
;
110 /* Floating Reserved Operand Code. */
114 static int /* 0 means letter is OK. */
115 what_kind_of_float (letter
, precisionP
, exponent_bitsP
)
116 /* In: lowercase please. What kind of float? */
119 /* Number of 16-bit words in the float. */
122 /* Number of exponent bits. */
123 long int *exponent_bitsP
;
125 int retval
; /* 0: OK. */
131 *precisionP
= F_PRECISION
;
136 *precisionP
= D_PRECISION
;
147 /* Warning: This returns 16-bit LITTLENUMs, because that is what the
148 VAX thinks in. It is up to the caller to figure out any alignment
149 problems and to conspire for the bytes/word to be emitted in the
150 right order. Bigendians beware! */
152 char * /* Return pointer past text consumed. */
153 atof_tahoe (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, the last contain flonum bits. */
163 int precision
; /* Number of 16-bit words in the format. */
164 long int exponent_bits
;
167 f
.low
= bits
+ MAX_PRECISION
;
173 if (what_kind_of_float (what_kind
, &precision
, &exponent_bits
))
177 make_invalid_floating_point_number (words
);
181 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
183 /* Use more LittleNums than seems necessary:
184 the highest flonum may have 15 leading 0 bits, so could be
186 f
.high
= f
.low
+ precision
- 1 + GUARD
;
188 if (atof_generic (&return_value
, ".", "eE", &f
))
190 make_invalid_floating_point_number (words
);
196 if (flonum_gen2tahoe (what_kind
, &f
, words
))
203 /* In: a flonum, a Tahoe floating point format.
204 Out: a Tahoe floating-point bit pattern. */
207 flonum_gen2tahoe (format_letter
, f
, words
)
208 char format_letter
; /* One of 'd' 'f'. */
210 LITTLENUM_TYPE
*words
; /* Deliver answer here. */
214 long int exponent_bits
;
215 int return_value
; /* 0 == OK. */
218 what_kind_of_float (format_letter
, &precision
, &exponent_bits
);
219 if (return_value
!= 0)
221 make_invalid_floating_point_number (words
);
225 if (f
->low
> f
->leader
)
228 memset (words
, '\0', sizeof (LITTLENUM_TYPE
) * precision
);
236 int exponent_skippage
;
237 LITTLENUM_TYPE word1
;
239 /* JF: Deal with new Nan, +Inf and -Inf codes. */
240 if (f
->sign
!= '-' && f
->sign
!= '+')
242 make_invalid_floating_point_number (words
);
245 /* All tahoe floating_point formats have:
247 Bits 14:n are excess-whatever exponent.
248 Bits n-1:0 (if any) are most significant bits of fraction.
249 Bits 15:0 of the next word are the next most significant bits.
250 And so on for each other word.
252 So we need: number of bits of exponent, number of bits of
255 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
;
256 littlenum_pointer
= f
->leader
;
257 littlenum_end
= f
->low
;
259 /* Seek (and forget) 1st significant bit. */
260 for (exponent_skippage
= 0;
265 exponent_1
= f
->exponent
+ f
->leader
+ 1 - f
->low
;
267 /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */
268 exponent_2
= exponent_1
* LITTLENUM_NUMBER_OF_BITS
;
271 exponent_3
= exponent_2
- exponent_skippage
;
273 /* Forget leading zeros, forget 1st bit. */
274 exponent_4
= exponent_3
+ (1 << (exponent_bits
- 1));
276 /* Offset exponent. */
278 if (exponent_4
& ~mask
[exponent_bits
])
280 /* Exponent overflow. Lose immediately. */
282 make_invalid_floating_point_number (words
);
284 /* We leave return_value alone: admit we read the
285 number, but return a floating exception because we
286 can't encode the number. */
292 /* Word 1. Sign, exponent and perhaps high bits. */
293 /* Assume 2's complement integers. */
294 word1
= ((exponent_4
& mask
[exponent_bits
])
295 << (15 - exponent_bits
))
296 | ((f
->sign
== '+') ? 0 : 0x8000)
297 | next_bits (15 - exponent_bits
);
300 /* The rest of the words are just mantissa bits. */
301 for (; lp
< words
+ precision
; lp
++)
302 *lp
= next_bits (LITTLENUM_NUMBER_OF_BITS
);
306 /* Since the NEXT bit is a 1, round UP the mantissa.
307 The cunning design of these hidden-1 floats permits
308 us to let the mantissa overflow into the exponent, and
309 it 'does the right thing'. However, we lose if the
310 highest-order bit of the lowest-order word flips.
313 unsigned long int carry
;
315 /* #if (sizeof(carry)) < ((sizeof(bits[0]) *
316 BITS_PER_CHAR) + 2) Please allow at least 1 more
317 bit in carry than is in a LITTLENUM. We need
318 that extra bit to hold a carry during a LITTLENUM
319 carry propagation. Another extra bit (kept 0)
320 will assure us that we don't get a sticky sign
321 bit after shifting right, and that permits us to
322 propagate the carry without any masking of bits.
324 for (carry
= 1, lp
--;
325 carry
&& (lp
>= words
);
330 carry
>>= LITTLENUM_NUMBER_OF_BITS
;
334 & (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)))
336 make_invalid_floating_point_number (words
);
337 /* We leave return_value alone: admit we read
338 the number, but return a floating exception
339 because we can't encode the number. */
341 } /* if (we needed to round up) */
342 } /* if (exponent overflow) */
344 } /* if (float_type was OK) */
348 /* In: input_line_pointer -> the 1st character of a floating-point
350 * 1 letter denoting the type of statement that wants a
351 * binary floating point number returned.
352 * Address of where to build floating point literal.
353 * Assumed to be 'big enough'.
354 * Address of where to return size of literal (in chars).
356 * Out: Input_line_pointer -> of next char after floating number.
357 * Error message, or 0.
358 * Floating point literal.
359 * Number of chars we used for the literal. */
362 md_atof (what_statement_type
, literalP
, sizeP
)
363 char what_statement_type
;
367 LITTLENUM_TYPE words
[MAX_PRECISION
];
368 register char kind_of_float
;
369 register int number_of_chars
;
370 register LITTLENUM_TYPE
*littlenum_pointer
;
372 switch (what_statement_type
)
374 case 'f': /* .ffloat */
375 case 'd': /* .dfloat */
376 kind_of_float
= what_statement_type
;
386 register LITTLENUM_TYPE
*limit
;
388 input_line_pointer
= atof_tahoe (input_line_pointer
,
391 /* The atof_tahoe() builds up 16-bit numbers.
392 Since the assembler may not be running on
393 a different-endian machine, be very careful about
394 converting words to chars. */
395 number_of_chars
= (kind_of_float
== 'f' ? F_PRECISION_CHARS
:
396 (kind_of_float
== 'd' ? D_PRECISION_CHARS
: 0));
397 know (number_of_chars
<= MAX_PRECISION
* sizeof (LITTLENUM_TYPE
));
398 limit
= words
+ (number_of_chars
/ sizeof (LITTLENUM_TYPE
));
399 for (littlenum_pointer
= words
;
400 littlenum_pointer
< limit
;
403 md_number_to_chars (literalP
, *littlenum_pointer
,
404 sizeof (LITTLENUM_TYPE
));
405 literalP
+= sizeof (LITTLENUM_TYPE
);
413 *sizeP
= number_of_chars
;
414 return kind_of_float
? 0 : _("Bad call to md_atof()");
This page took 0.038839 seconds and 4 git commands to generate.