1 /* atof_tahoe.c - turn a string into a Tahoe floating point number
2 Copyright (C) 1987 Free Software Foundation, Inc.
5 /* This is really a simplified version of atof_vax.c. I glommed it wholesale
6 and then shaved it down. I don't even know how it works. (Don't you find
7 my honesty refreshing? bowen@cs.Buffalo.EDU (Devon E Bowen)
9 I don't allow uppercase letters in the precision descrpitors. Ie 'f' and
10 'd' are allowed but 'F' and 'D' aren't */
14 /* Precision in LittleNums. */
15 #define MAX_PRECISION (4)
16 #define D_PRECISION (4)
17 #define F_PRECISION (2)
19 /* Precision in chars. */
20 #define D_PRECISION_CHARS (8)
21 #define F_PRECISION_CHARS (4)
23 /* Length in LittleNums of guard bits. */
26 static const long int mask [] = {
63 /* Shared between flonum_gen2tahoe and next_bits */
64 static int bits_left_in_littlenum;
65 static LITTLENUM_TYPE * littlenum_pointer;
66 static LITTLENUM_TYPE * littlenum_end;
70 int flonum_gen2tahoe(int format_letter, FLONUM_TYPE *f, LITTLENUM_TYPE *words);
72 #else /* not __STDC__ */
74 int flonum_gen2tahoe();
76 #endif /* not __STDC__ */
80 next_bits (number_of_bits)
85 if(littlenum_pointer<littlenum_end)
87 if (number_of_bits >= bits_left_in_littlenum)
89 return_value = mask [bits_left_in_littlenum] & * littlenum_pointer;
90 number_of_bits -= bits_left_in_littlenum;
91 return_value <<= number_of_bits;
92 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
94 if(littlenum_pointer>=littlenum_end)
95 return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) &
96 mask [number_of_bits];
100 bits_left_in_littlenum -= number_of_bits;
101 return_value = mask [number_of_bits] &
102 ((*littlenum_pointer) >> bits_left_in_littlenum);
104 return (return_value);
108 make_invalid_floating_point_number (words)
109 LITTLENUM_TYPE * words;
111 *words = 0x8000; /* Floating Reserved Operand Code */
114 static int /* 0 means letter is OK. */
115 what_kind_of_float (letter, precisionP, exponent_bitsP)
116 char letter; /* In: lowercase please. What kind of float? */
117 int * precisionP; /* Number of 16-bit words in the float. */
118 long int * exponent_bitsP; /* Number of exponent bits. */
120 int retval; /* 0: OK. */
126 * precisionP = F_PRECISION;
127 * exponent_bitsP = 8;
131 * precisionP = D_PRECISION;
132 * exponent_bitsP = 8;
142 /***********************************************************************\
144 * Warning: this returns 16-bit LITTLENUMs, because that is *
145 * what the VAX thinks in. It is up to the caller to figure *
146 * out any alignment problems and to conspire for the bytes/word *
147 * to be emitted in the right order. Bigendians beware! *
149 \***********************************************************************/
151 char * /* Return pointer past text consumed. */
152 atof_tahoe (str, what_kind, words)
153 char * str; /* Text to convert to binary. */
154 char what_kind; /* 'd', 'f', 'g', 'h' */
155 LITTLENUM_TYPE * words; /* Build the binary here. */
158 LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD];
159 /* Extra bits for zeroed low-order bits. */
160 /* The 1st MAX_PRECISION are zeroed, */
161 /* 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))
175 return_value = NULL; /* We lost. */
176 make_invalid_floating_point_number (words);
180 memset(bits, '\0', sizeof(LITTLENUM_TYPE) * MAX_PRECISION);
182 /* Use more LittleNums than seems */
183 /* necessary: the highest flonum may have */
184 /* 15 leading 0 bits, so could be useless. */
185 f . high = f . low + precision - 1 + GUARD;
187 if (atof_generic (& return_value, ".", "eE", & f))
189 make_invalid_floating_point_number (words);
190 return_value = NULL; /* we lost */
194 if (flonum_gen2tahoe (what_kind, & f, words))
200 return (return_value);
204 * In: a flonum, a Tahoe floating point format.
205 * Out: a Tahoe floating-point bit pattern.
209 flonum_gen2tahoe (format_letter, f, words)
210 char format_letter; /* One of 'd' 'f'. */
212 LITTLENUM_TYPE * words; /* Deliver answer here. */
216 long int exponent_bits;
217 int return_value; /* 0 == OK. */
219 return_value = what_kind_of_float(format_letter,&precision,&exponent_bits);
220 if (return_value != 0)
222 make_invalid_floating_point_number (words);
226 if (f -> low > f -> leader)
229 memset(words, '\0', sizeof(LITTLENUM_TYPE) * precision);
237 int exponent_skippage;
238 LITTLENUM_TYPE word1;
240 /* JF: Deal with new Nan, +Inf and -Inf codes */
241 if(f->sign!='-' && f->sign!='+') {
242 make_invalid_floating_point_number(words);
246 * All tahoe floating_point formats have:
247 * Bit 15 is sign bit.
248 * Bits 14:n are excess-whatever exponent.
249 * Bits n-1:0 (if any) are most significant bits of fraction.
250 * Bits 15:0 of the next word are the next most significant bits.
251 * And so on for each other word.
253 * So we need: number of bits of exponent, number of bits of
257 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
258 littlenum_pointer = f -> leader;
259 littlenum_end = f->low;
260 /* Seek (and forget) 1st significant bit */
261 for (exponent_skippage = 0;
263 exponent_skippage ++)
266 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;
270 exponent_3 = exponent_2 - exponent_skippage;
271 /* Forget leading zeros, forget 1st bit. */
272 exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
273 /* Offset exponent. */
275 if (exponent_4 & ~ mask [exponent_bits])
278 * Exponent overflow. Lose immediately.
281 make_invalid_floating_point_number (words);
284 * We leave return_value alone: admit we read the
285 * number, but return a floating exception
286 * because we can't encode the number.
293 /* Word 1. Sign, exponent and perhaps high bits. */
294 /* Assume 2's complement integers. */
295 word1 = ((exponent_4 & mask [exponent_bits]) << (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++)
303 * lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
309 * Since the NEXT bit is a 1, round UP the mantissa.
310 * The cunning design of these hidden-1 floats permits
311 * us to let the mantissa overflow into the exponent, and
312 * it 'does the right thing'. However, we lose if the
313 * highest-order bit of the lowest-order word flips.
317 unsigned long int carry;
320 #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
321 Please allow at least 1 more bit in carry than is in a LITTLENUM.
322 We need that extra bit to hold a carry during a LITTLENUM carry
323 propagation. Another extra bit (kept 0) will assure us that we
324 don't get a sticky sign bit after shifting right, and that
325 permits us to propagate the carry without any masking of bits.
328 for (carry = 1, lp --;
329 carry && (lp >= words);
332 carry = * lp + carry;
334 carry >>= LITTLENUM_NUMBER_OF_BITS;
337 if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) )
339 make_invalid_floating_point_number (words);
341 * We leave return_value alone: admit we read the
342 * number, but return a floating exception
343 * because we can't encode the number.
346 } /* if (we needed to round up) */
347 } /* if (exponent overflow) */
349 } /* if (float_type was OK) */
350 return (return_value);
356 * In: input_line_pointer -> the 1st character of a floating-point
358 * 1 letter denoting the type of statement that wants a
359 * binary floating point number returned.
360 * Address of where to build floating point literal.
361 * Assumed to be 'big enough'.
362 * Address of where to return size of literal (in chars).
364 * Out: Input_line_pointer -> of next char after floating number.
365 * Error message, or "".
366 * Floating point literal.
367 * Number of chars we used for the literal.
371 md_atof (what_statement_type, literalP, sizeP)
372 char what_statement_type;
376 LITTLENUM_TYPE words [MAX_PRECISION];
377 register char kind_of_float;
378 register int number_of_chars;
379 register LITTLENUM_TYPE * littlenum_pointer;
381 switch (what_statement_type)
383 case 'f': /* .ffloat */
384 case 'd': /* .dfloat */
385 kind_of_float = what_statement_type;
395 register LITTLENUM_TYPE * limit;
397 input_line_pointer = atof_tahoe (input_line_pointer,
401 * The atof_tahoe() builds up 16-bit numbers.
402 * Since the assembler may not be running on
403 * a different-endian machine, be very careful about
404 * converting words to chars.
406 number_of_chars = (kind_of_float == 'f' ? F_PRECISION_CHARS :
407 (kind_of_float == 'd' ? D_PRECISION_CHARS : 0));
408 know(number_of_chars<=MAX_PRECISION*sizeof(LITTLENUM_TYPE));
409 limit = words + (number_of_chars / sizeof(LITTLENUM_TYPE));
410 for (littlenum_pointer = words;
411 littlenum_pointer < limit;
412 littlenum_pointer ++)
414 md_number_to_chars(literalP,*littlenum_pointer,
415 sizeof(LITTLENUM_TYPE));
416 literalP += sizeof(LITTLENUM_TYPE);
424 * sizeP = number_of_chars;
425 return (kind_of_float ? "" : "Bad call to md_atof()");