1 /* atof_tahoe.c - turn a string into a Tahoe floating point number
2    Copyright 1987, 1993, 2000 Free Software Foundation, Inc.
3 
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>
7 
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.  */
10 
11 #include "as.h"
12 
13 /* Precision in LittleNums.  */
14 #define MAX_PRECISION (4)
15 #define D_PRECISION (4)
16 #define F_PRECISION (2)
17 
18 /* Precision in chars.  */
19 #define D_PRECISION_CHARS (8)
20 #define F_PRECISION_CHARS (4)
21 
22 /* Length in LittleNums of guard bits.  */
23 #define GUARD (2)
24 
25 static const long int mask[] =
26 {
27   0x00000000,
28   0x00000001,
29   0x00000003,
30   0x00000007,
31   0x0000000f,
32   0x0000001f,
33   0x0000003f,
34   0x0000007f,
35   0x000000ff,
36   0x000001ff,
37   0x000003ff,
38   0x000007ff,
39   0x00000fff,
40   0x00001fff,
41   0x00003fff,
42   0x00007fff,
43   0x0000ffff,
44   0x0001ffff,
45   0x0003ffff,
46   0x0007ffff,
47   0x000fffff,
48   0x001fffff,
49   0x003fffff,
50   0x007fffff,
51   0x00ffffff,
52   0x01ffffff,
53   0x03ffffff,
54   0x07ffffff,
55   0x0fffffff,
56   0x1fffffff,
57   0x3fffffff,
58   0x7fffffff,
59   0xffffffff
60 };
61 
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;
66 
67 #if __STDC__ == 1
68 
69 int flonum_gen2tahoe (int format_letter, FLONUM_TYPE * f,
70 		      LITTLENUM_TYPE * words);
71 
72 #else /* not __STDC__  */
73 
74 int flonum_gen2tahoe ();
75 
76 #endif /* not __STDC__  */
77 
78 static int
79 next_bits (number_of_bits)
80      int number_of_bits;
81 {
82   int return_value;
83 
84   if (littlenum_pointer < littlenum_end)
85     return 0;
86   if (number_of_bits >= bits_left_in_littlenum)
87     {
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;
92       littlenum_pointer--;
93       if (littlenum_pointer >= littlenum_end)
94 	return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) &
95 	  mask[number_of_bits];
96     }
97   else
98     {
99       bits_left_in_littlenum -= number_of_bits;
100       return_value = mask[number_of_bits] &
101 	((*littlenum_pointer) >> bits_left_in_littlenum);
102     }
103   return return_value;
104 }
105 
106 static void
107 make_invalid_floating_point_number (words)
108      LITTLENUM_TYPE *words;
109 {
110   /* Floating Reserved Operand Code.  */
111   *words = 0x8000;
112 }
113 
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?  */
117      char letter;
118 
119      /* Number of 16-bit words in the float.  */
120      int *precisionP;
121 
122      /* Number of exponent bits.  */
123      long int *exponent_bitsP;
124 {
125   int retval;			/* 0: OK.  */
126 
127   retval = 0;
128   switch (letter)
129     {
130     case 'f':
131       *precisionP = F_PRECISION;
132       *exponent_bitsP = 8;
133       break;
134 
135     case 'd':
136       *precisionP = D_PRECISION;
137       *exponent_bitsP = 8;
138       break;
139 
140     default:
141       retval = 69;
142       break;
143     }
144   return (retval);
145 }
146 
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!  */
151 
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.  */
157 {
158   FLONUM_TYPE f;
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.  */
162   char *return_value;
163   int precision;		/* Number of 16-bit words in the format.  */
164   long int exponent_bits;
165 
166   return_value = str;
167   f.low = bits + MAX_PRECISION;
168   f.high = NULL;
169   f.leader = NULL;
170   f.exponent = NULL;
171   f.sign = '\0';
172 
173   if (what_kind_of_float (what_kind, &precision, &exponent_bits))
174     {
175       /* We lost.  */
176       return_value = NULL;
177       make_invalid_floating_point_number (words);
178     }
179   if (return_value)
180     {
181       memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
182 
183       /* Use more LittleNums than seems necessary:
184 	 the highest flonum may have 15 leading 0 bits, so could be
185 	 useless.  */
186       f.high = f.low + precision - 1 + GUARD;
187 
188       if (atof_generic (&return_value, ".", "eE", &f))
189 	{
190 	  make_invalid_floating_point_number (words);
191 	  /* We lost.  */
192 	  return_value = NULL;
193 	}
194       else
195 	{
196 	  if (flonum_gen2tahoe (what_kind, &f, words))
197 	    return_value = NULL;
198 	}
199     }
200   return return_value;
201 }
202 
203 /* In: a flonum, a Tahoe floating point format.
204    Out: a Tahoe floating-point bit pattern.  */
205 
206 int				/* 0: OK.  */
207 flonum_gen2tahoe (format_letter, f, words)
208      char format_letter;	/* One of 'd' 'f'.  */
209      FLONUM_TYPE *f;
210      LITTLENUM_TYPE *words;	/* Deliver answer here.  */
211 {
212   LITTLENUM_TYPE *lp;
213   int precision;
214   long int exponent_bits;
215   int return_value;		/* 0 == OK.  */
216 
217   return_value =
218     what_kind_of_float (format_letter, &precision, &exponent_bits);
219   if (return_value != 0)
220     {
221       make_invalid_floating_point_number (words);
222     }
223   else
224     {
225       if (f->low > f->leader)
226 	{
227 	  /* 0.0e0 seen.  */
228 	  memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
229 	}
230       else
231 	{
232 	  long int exponent_1;
233 	  long int exponent_2;
234 	  long int exponent_3;
235 	  long int exponent_4;
236 	  int exponent_skippage;
237 	  LITTLENUM_TYPE word1;
238 
239 	  /* JF: Deal with new Nan, +Inf and -Inf codes.  */
240 	  if (f->sign != '-' && f->sign != '+')
241 	    {
242 	      make_invalid_floating_point_number (words);
243 	      return return_value;
244 	    }
245 	  /* All tahoe floating_point formats have:
246 	     Bit 15 is sign bit.
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.
251 
252 	     So we need: number of bits of exponent, number of bits of
253 	     mantissa.  */
254 
255 	  bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
256 	  littlenum_pointer = f->leader;
257 	  littlenum_end = f->low;
258 
259 	  /* Seek (and forget) 1st significant bit.  */
260 	  for (exponent_skippage = 0;
261 	       !next_bits (1);
262 	       exponent_skippage++)
263 	    ;
264 
265 	  exponent_1 = f->exponent + f->leader + 1 - f->low;
266 
267 	  /* Radix LITTLENUM_RADIX, point just higher than f -> leader.  */
268 	  exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
269 
270 	  /* Radix 2.  */
271 	  exponent_3 = exponent_2 - exponent_skippage;
272 
273 	  /* Forget leading zeros, forget 1st bit.  */
274 	  exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
275 
276 	  /* Offset exponent.  */
277 
278 	  if (exponent_4 & ~mask[exponent_bits])
279 	    {
280 	      /* Exponent overflow. Lose immediately.  */
281 
282 	      make_invalid_floating_point_number (words);
283 
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.  */
287 	    }
288 	  else
289 	    {
290 	      lp = words;
291 
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);
298 	      *lp++ = word1;
299 
300 	      /* The rest of the words are just mantissa bits.  */
301 	      for (; lp < words + precision; lp++)
302 		*lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
303 
304 	      if (next_bits (1))
305 		{
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.
311 		     Is that clear?  */
312 
313 		  unsigned long int carry;
314 
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.
323 		     #endif  */
324 		  for (carry = 1, lp--;
325 		       carry && (lp >= words);
326 		       lp--)
327 		    {
328 		      carry = *lp + carry;
329 		      *lp = carry;
330 		      carry >>= LITTLENUM_NUMBER_OF_BITS;
331 		    }
332 
333 		  if ((word1 ^ *words)
334 		      & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
335 		    {
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.  */
340 		    }
341 		}		/* if (we needed to round up)  */
342 	    }			/* if (exponent overflow)  */
343 	}			/* if (0.0e0)  */
344     }				/* if (float_type was OK)  */
345   return return_value;
346 }
347 
348 /* In:	input_line_pointer -> the 1st character of a floating-point
349  *		number.
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).
355  *
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.  */
360 
361 char *
362 md_atof (what_statement_type, literalP, sizeP)
363      char what_statement_type;
364      char *literalP;
365      int *sizeP;
366 {
367   LITTLENUM_TYPE words[MAX_PRECISION];
368   register char kind_of_float;
369   register int number_of_chars;
370   register LITTLENUM_TYPE *littlenum_pointer;
371 
372   switch (what_statement_type)
373     {
374     case 'f':			/* .ffloat  */
375     case 'd':			/* .dfloat  */
376       kind_of_float = what_statement_type;
377       break;
378 
379     default:
380       kind_of_float = 0;
381       break;
382     }
383 
384   if (kind_of_float)
385     {
386       register LITTLENUM_TYPE *limit;
387 
388       input_line_pointer = atof_tahoe (input_line_pointer,
389 				       kind_of_float,
390 				       words);
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;
401 	   littlenum_pointer++)
402 	{
403 	  md_number_to_chars (literalP, *littlenum_pointer,
404 			      sizeof (LITTLENUM_TYPE));
405 	  literalP += sizeof (LITTLENUM_TYPE);
406 	}
407     }
408   else
409     {
410       number_of_chars = 0;
411     }
412 
413   *sizeP = number_of_chars;
414   return kind_of_float ? 0 : _("Bad call to md_atof()");
415 }
416