2 /* atof_tahoe.c - turn a string into a Tahoe floating point number
3 Copyright (C) 1987 Free Software Foundation, Inc.
6 /* This is really a simplified version of atof_vax.c. I glommed it wholesale
7 and then shaved it down. I don't even know how it works. (Don't you find
8 my honesty refreshing? bowen@cs.Buffalo.EDU (Devon E Bowen)
10 I don't allow uppercase letters in the precision descrpitors. Ie 'f' and
11 'd' are allowed but 'F' and 'D' aren't */
15 /* Precision in LittleNums. */
16 #define MAX_PRECISION (4)
17 #define D_PRECISION (4)
18 #define F_PRECISION (2)
20 /* Precision in chars. */
21 #define D_PRECISION_CHARS (8)
22 #define F_PRECISION_CHARS (4)
24 /* Length in LittleNums of guard bits. */
27 static const long int mask
[] =
65 /* Shared between flonum_gen2tahoe and next_bits */
66 static int bits_left_in_littlenum
;
67 static LITTLENUM_TYPE
*littlenum_pointer
;
68 static LITTLENUM_TYPE
*littlenum_end
;
72 int flonum_gen2tahoe (int format_letter
, FLONUM_TYPE
* f
, LITTLENUM_TYPE
* words
);
74 #else /* not __STDC__ */
76 int flonum_gen2tahoe ();
78 #endif /* not __STDC__ */
82 next_bits (number_of_bits
)
87 if (littlenum_pointer
< littlenum_end
)
89 if (number_of_bits
>= bits_left_in_littlenum
)
91 return_value
= mask
[bits_left_in_littlenum
] & *littlenum_pointer
;
92 number_of_bits
-= bits_left_in_littlenum
;
93 return_value
<<= number_of_bits
;
94 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
- number_of_bits
;
96 if (littlenum_pointer
>= littlenum_end
)
97 return_value
|= ((*littlenum_pointer
) >> (bits_left_in_littlenum
)) &
102 bits_left_in_littlenum
-= number_of_bits
;
103 return_value
= mask
[number_of_bits
] &
104 ((*littlenum_pointer
) >> bits_left_in_littlenum
);
106 return (return_value
);
110 make_invalid_floating_point_number (words
)
111 LITTLENUM_TYPE
*words
;
113 *words
= 0x8000; /* Floating Reserved Operand Code */
116 static int /* 0 means letter is OK. */
117 what_kind_of_float (letter
, precisionP
, exponent_bitsP
)
118 char letter
; /* In: lowercase please. What kind of float? */
119 int *precisionP
; /* Number of 16-bit words in the float. */
120 long int *exponent_bitsP
; /* Number of exponent bits. */
122 int retval
; /* 0: OK. */
128 *precisionP
= F_PRECISION
;
133 *precisionP
= D_PRECISION
;
144 /***********************************************************************\
146 * Warning: this returns 16-bit LITTLENUMs, because that is *
147 * what the VAX thinks in. It is up to the caller to figure *
148 * out any alignment problems and to conspire for the bytes/word *
149 * to be emitted in the right order. Bigendians beware! *
151 \***********************************************************************/
153 char * /* Return pointer past text consumed. */
154 atof_tahoe (str
, what_kind
, words
)
155 char *str
; /* Text to convert to binary. */
156 char what_kind
; /* 'd', 'f', 'g', 'h' */
157 LITTLENUM_TYPE
*words
; /* Build the binary here. */
160 LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
161 /* Extra bits for zeroed low-order bits. */
162 /* The 1st MAX_PRECISION are zeroed, */
163 /* the last contain flonum bits. */
165 int precision
; /* Number of 16-bit words in the format. */
166 long int exponent_bits
;
169 f
.low
= bits
+ MAX_PRECISION
;
175 if (what_kind_of_float (what_kind
, &precision
, &exponent_bits
))
177 return_value
= NULL
; /* We lost. */
178 make_invalid_floating_point_number (words
);
182 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
184 /* Use more LittleNums than seems */
185 /* necessary: the highest flonum may have */
186 /* 15 leading 0 bits, so could be useless. */
187 f
.high
= f
.low
+ precision
- 1 + GUARD
;
189 if (atof_generic (&return_value
, ".", "eE", &f
))
191 make_invalid_floating_point_number (words
);
192 return_value
= NULL
; /* we lost */
196 if (flonum_gen2tahoe (what_kind
, &f
, words
))
202 return (return_value
);
206 * In: a flonum, a Tahoe floating point format.
207 * Out: a Tahoe floating-point bit pattern.
211 flonum_gen2tahoe (format_letter
, f
, words
)
212 char format_letter
; /* One of 'd' 'f'. */
214 LITTLENUM_TYPE
*words
; /* Deliver answer here. */
218 long int exponent_bits
;
219 int return_value
; /* 0 == OK. */
221 return_value
= what_kind_of_float (format_letter
, &precision
, &exponent_bits
);
222 if (return_value
!= 0)
224 make_invalid_floating_point_number (words
);
228 if (f
->low
> f
->leader
)
231 memset (words
, '\0', sizeof (LITTLENUM_TYPE
) * precision
);
239 int exponent_skippage
;
240 LITTLENUM_TYPE word1
;
242 /* JF: Deal with new Nan, +Inf and -Inf codes */
243 if (f
->sign
!= '-' && f
->sign
!= '+')
245 make_invalid_floating_point_number (words
);
249 * All tahoe floating_point formats have:
250 * Bit 15 is sign bit.
251 * Bits 14:n are excess-whatever exponent.
252 * Bits n-1:0 (if any) are most significant bits of fraction.
253 * Bits 15:0 of the next word are the next most significant bits.
254 * And so on for each other word.
256 * So we need: number of bits of exponent, number of bits of
260 bits_left_in_littlenum
= LITTLENUM_NUMBER_OF_BITS
;
261 littlenum_pointer
= f
->leader
;
262 littlenum_end
= f
->low
;
263 /* Seek (and forget) 1st significant bit */
264 for (exponent_skippage
= 0;
269 exponent_1
= f
->exponent
+ f
->leader
+ 1 - f
->low
;
270 /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */
271 exponent_2
= exponent_1
* LITTLENUM_NUMBER_OF_BITS
;
273 exponent_3
= exponent_2
- exponent_skippage
;
274 /* Forget leading zeros, forget 1st bit. */
275 exponent_4
= exponent_3
+ (1 << (exponent_bits
- 1));
276 /* Offset exponent. */
278 if (exponent_4
& ~mask
[exponent_bits
])
281 * Exponent overflow. Lose immediately.
284 make_invalid_floating_point_number (words
);
287 * We leave return_value alone: admit we read the
288 * number, but return a floating exception
289 * because we can't encode the number.
296 /* Word 1. Sign, exponent and perhaps high bits. */
297 /* Assume 2's complement integers. */
298 word1
= ((exponent_4
& mask
[exponent_bits
]) << (15 - exponent_bits
))
299 | ((f
->sign
== '+') ? 0 : 0x8000)
300 | next_bits (15 - exponent_bits
);
303 /* The rest of the words are just mantissa bits. */
304 for (; lp
< words
+ precision
; lp
++)
306 *lp
= next_bits (LITTLENUM_NUMBER_OF_BITS
);
312 * Since the NEXT bit is a 1, round UP the mantissa.
313 * The cunning design of these hidden-1 floats permits
314 * us to let the mantissa overflow into the exponent, and
315 * it 'does the right thing'. However, we lose if the
316 * highest-order bit of the lowest-order word flips.
320 unsigned long int carry
;
323 #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
324 Please allow at least 1 more bit in carry than is in a LITTLENUM.
325 We need that extra bit to hold a carry during a LITTLENUM carry
326 propagation. Another extra bit (kept 0) will assure us that we
327 don't get a sticky sign bit after shifting right, and that
328 permits us to propagate the carry without any masking of bits.
331 for (carry
= 1, lp
--;
332 carry
&& (lp
>= words
);
337 carry
>>= LITTLENUM_NUMBER_OF_BITS
;
340 if ((word1
^ *words
) & (1 << (LITTLENUM_NUMBER_OF_BITS
- 1)))
342 make_invalid_floating_point_number (words
);
344 * We leave return_value alone: admit we read the
345 * number, but return a floating exception
346 * because we can't encode the number.
349 } /* if (we needed to round up) */
350 } /* if (exponent overflow) */
352 } /* if (float_type was OK) */
353 return (return_value
);
359 * In: input_line_pointer -> the 1st character of a floating-point
361 * 1 letter denoting the type of statement that wants a
362 * binary floating point number returned.
363 * Address of where to build floating point literal.
364 * Assumed to be 'big enough'.
365 * Address of where to return size of literal (in chars).
367 * Out: Input_line_pointer -> of next char after floating number.
368 * Error message, or 0.
369 * Floating point literal.
370 * Number of chars we used for the literal.
374 md_atof (what_statement_type
, literalP
, sizeP
)
375 char what_statement_type
;
379 LITTLENUM_TYPE words
[MAX_PRECISION
];
380 register char kind_of_float
;
381 register int number_of_chars
;
382 register LITTLENUM_TYPE
*littlenum_pointer
;
384 switch (what_statement_type
)
386 case 'f': /* .ffloat */
387 case 'd': /* .dfloat */
388 kind_of_float
= what_statement_type
;
398 register LITTLENUM_TYPE
*limit
;
400 input_line_pointer
= atof_tahoe (input_line_pointer
,
404 * The atof_tahoe() builds up 16-bit numbers.
405 * Since the assembler may not be running on
406 * a different-endian machine, be very careful about
407 * converting words to chars.
409 number_of_chars
= (kind_of_float
== 'f' ? F_PRECISION_CHARS
:
410 (kind_of_float
== 'd' ? D_PRECISION_CHARS
: 0));
411 know (number_of_chars
<= MAX_PRECISION
* sizeof (LITTLENUM_TYPE
));
412 limit
= words
+ (number_of_chars
/ sizeof (LITTLENUM_TYPE
));
413 for (littlenum_pointer
= words
;
414 littlenum_pointer
< limit
;
417 md_number_to_chars (literalP
, *littlenum_pointer
,
418 sizeof (LITTLENUM_TYPE
));
419 literalP
+= sizeof (LITTLENUM_TYPE
);
427 *sizeP
= number_of_chars
;
428 return kind_of_float
? 0 : "Bad call to md_atof()";
This page took 0.037648 seconds and 4 git commands to generate.