1 /* atof_vax.c - turn a Flonum into a VAX floating point number
2    Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000, 2005, 2007
3    Free Software Foundation, Inc.
4 
5    This file is part of GAS, the GNU Assembler.
6 
7    GAS is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11 
12    GAS is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with GAS; see the file COPYING.  If not, write to the Free
19    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, USA.  */
21 
22 #include "as.h"
23 
24 /* Precision in LittleNums.  */
25 #define MAX_PRECISION	8
26 #define H_PRECISION	8
27 #define G_PRECISION	4
28 #define D_PRECISION	4
29 #define F_PRECISION	2
30 
31 /* Length in LittleNums of guard bits.  */
32 #define GUARD		2
33 
34 int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *);
35 
36 /* Number of chars in flonum type 'letter'.  */
37 
38 static unsigned int
39 atof_vax_sizeof (int letter)
40 {
41   int return_value;
42 
43   /* Permitting uppercase letters is probably a bad idea.
44      Please use only lower-cased letters in case the upper-cased
45      ones become unsupported!  */
46   switch (letter)
47     {
48     case 'f':
49     case 'F':
50       return_value = 4;
51       break;
52 
53     case 'd':
54     case 'D':
55     case 'g':
56     case 'G':
57       return_value = 8;
58       break;
59 
60     case 'h':
61     case 'H':
62       return_value = 16;
63       break;
64 
65     default:
66       return_value = 0;
67       break;
68     }
69 
70   return return_value;
71 }
72 
73 static const long mask[] =
74 {
75   0x00000000,
76   0x00000001,
77   0x00000003,
78   0x00000007,
79   0x0000000f,
80   0x0000001f,
81   0x0000003f,
82   0x0000007f,
83   0x000000ff,
84   0x000001ff,
85   0x000003ff,
86   0x000007ff,
87   0x00000fff,
88   0x00001fff,
89   0x00003fff,
90   0x00007fff,
91   0x0000ffff,
92   0x0001ffff,
93   0x0003ffff,
94   0x0007ffff,
95   0x000fffff,
96   0x001fffff,
97   0x003fffff,
98   0x007fffff,
99   0x00ffffff,
100   0x01ffffff,
101   0x03ffffff,
102   0x07ffffff,
103   0x0fffffff,
104   0x1fffffff,
105   0x3fffffff,
106   0x7fffffff,
107   0xffffffff
108 };
109 
110 
111 /* Shared between flonum_gen2vax and next_bits.  */
112 static int bits_left_in_littlenum;
113 static LITTLENUM_TYPE *littlenum_pointer;
114 static LITTLENUM_TYPE *littlenum_end;
115 
116 static int
117 next_bits (int number_of_bits)
118 {
119   int return_value;
120 
121   if (littlenum_pointer < littlenum_end)
122     return 0;
123   if (number_of_bits >= bits_left_in_littlenum)
124     {
125       return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
126       number_of_bits -= bits_left_in_littlenum;
127       return_value <<= number_of_bits;
128       bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
129       littlenum_pointer--;
130       if (littlenum_pointer >= littlenum_end)
131 	return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & mask[number_of_bits];
132     }
133   else
134     {
135       bits_left_in_littlenum -= number_of_bits;
136       return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum);
137     }
138   return return_value;
139 }
140 
141 static void
142 make_invalid_floating_point_number (LITTLENUM_TYPE *words)
143 {
144   *words = 0x8000;		/* Floating Reserved Operand Code.  */
145 }
146 
147 
148 static int			/* 0 means letter is OK.  */
149 what_kind_of_float (int letter,			/* In: lowercase please. What kind of float?  */
150 		    int *precisionP,		/* Number of 16-bit words in the float.  */
151 		    long *exponent_bitsP)	/* Number of exponent bits.  */
152 {
153   int retval;
154 
155   retval = 0;
156   switch (letter)
157     {
158     case 'f':
159       *precisionP = F_PRECISION;
160       *exponent_bitsP = 8;
161       break;
162 
163     case 'd':
164       *precisionP = D_PRECISION;
165       *exponent_bitsP = 8;
166       break;
167 
168     case 'g':
169       *precisionP = G_PRECISION;
170       *exponent_bitsP = 11;
171       break;
172 
173     case 'h':
174       *precisionP = H_PRECISION;
175       *exponent_bitsP = 15;
176       break;
177 
178     default:
179       retval = 69;
180       break;
181     }
182   return retval;
183 }
184 
185 /* Warning: this returns 16-bit LITTLENUMs, because that is
186    what the VAX thinks in. It is up to the caller to figure
187    out any alignment problems and to conspire for the bytes/word
188    to be emitted in the right order. Bigendians beware!  */
189 
190 static char *
191 atof_vax (char *str,			/* Text to convert to binary.  */
192 	  int what_kind,		/* 'd', 'f', 'g', 'h'  */
193 	  LITTLENUM_TYPE *words)	/* Build the binary here.  */
194 {
195   FLONUM_TYPE f;
196   LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
197   /* Extra bits for zeroed low-order bits.
198      The 1st MAX_PRECISION are zeroed,
199      the last contain flonum bits.  */
200   char *return_value;
201   int precision;		/* Number of 16-bit words in the format.  */
202   long exponent_bits;
203 
204   return_value = str;
205   f.low = bits + MAX_PRECISION;
206   f.high = NULL;
207   f.leader = NULL;
208   f.exponent = 0;
209   f.sign = '\0';
210 
211   if (what_kind_of_float (what_kind, &precision, &exponent_bits))
212     {
213       return_value = NULL;
214       make_invalid_floating_point_number (words);
215     }
216 
217   if (return_value)
218     {
219       memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
220 
221       /* Use more LittleNums than seems
222          necessary: the highest flonum may have
223          15 leading 0 bits, so could be useless.  */
224       f.high = f.low + precision - 1 + GUARD;
225 
226       if (atof_generic (&return_value, ".", "eE", &f))
227 	{
228 	  make_invalid_floating_point_number (words);
229 	  return_value = NULL;
230 	}
231       else if (flonum_gen2vax (what_kind, &f, words))
232 	return_value = NULL;
233     }
234 
235   return return_value;
236 }
237 
238 /* In: a flonum, a vax floating point format.
239    Out: a vax floating-point bit pattern.  */
240 
241 int
242 flonum_gen2vax (int format_letter,	/* One of 'd' 'f' 'g' 'h'.  */
243 		FLONUM_TYPE *f,
244 		LITTLENUM_TYPE *words)	/* Deliver answer here.  */
245 {
246   LITTLENUM_TYPE *lp;
247   int precision;
248   long exponent_bits;
249   int return_value;		/* 0 == OK.  */
250 
251   return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
252 
253   if (return_value != 0)
254     make_invalid_floating_point_number (words);
255 
256   else
257     {
258       if (f->low > f->leader)
259 	/* 0.0e0 seen.  */
260 	memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
261 
262       else
263 	{
264 	  long exponent_1;
265 	  long exponent_2;
266 	  long exponent_3;
267 	  long exponent_4;
268 	  int exponent_skippage;
269 	  LITTLENUM_TYPE word1;
270 
271 	  if (f->sign != '-' && f->sign != '+')
272 	    {
273 	      if (f->sign == 0)
274 		{
275 		  /* All NaNs are 0.  */
276 		  memset (words, 0x00, sizeof (LITTLENUM_TYPE) * precision);
277 		}
278 	      else if (f->sign == 'P')
279 		{
280 		  /* Positive Infinity.  */
281 		  memset (words, 0xff, sizeof (LITTLENUM_TYPE) * precision);
282 		  words[0] &= 0x7fff;
283 		}
284 	      else if (f->sign == 'N')
285 		{
286 		  /* Negative Infinity.  */
287 		  memset (words, 0x00, sizeof (LITTLENUM_TYPE) * precision);
288 		  words[0] = 0x0080;
289 		}
290 	      else
291 		make_invalid_floating_point_number (words);
292 	      return return_value;
293 	    }
294 
295 	  /* All vaxen floating_point formats (so far) have:
296 	     Bit 15 is sign bit.
297 	     Bits 14:n are excess-whatever exponent.
298 	     Bits n-1:0 (if any) are most significant bits of fraction.
299 	     Bits 15:0 of the next word are the next most significant bits.
300 	     And so on for each other word.
301 
302 	     All this to be compatible with a KF11?? (Which is still faster
303 	     than lots of vaxen I can think of, but it also has higher
304 	     maintenance costs ... sigh).
305 
306 	     So we need: number of bits of exponent, number of bits of
307 	     mantissa.  */
308 
309 	  bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
310 	  littlenum_pointer = f->leader;
311 	  littlenum_end = f->low;
312 	  /* Seek (and forget) 1st significant bit.  */
313 	  for (exponent_skippage = 0;
314 	       !next_bits (1);
315 	       exponent_skippage++);;
316 
317 	  exponent_1 = f->exponent + f->leader + 1 - f->low;
318 	  /* Radix LITTLENUM_RADIX, point just higher than f->leader.  */
319 	  exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
320 	  /* Radix 2.  */
321 	  exponent_3 = exponent_2 - exponent_skippage;
322 	  /* Forget leading zeros, forget 1st bit.  */
323 	  exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
324 	  /* Offset exponent.  */
325 
326 	  if (exponent_4 & ~mask[exponent_bits])
327 	    {
328 	      /* Exponent overflow. Lose immediately.  */
329 	      make_invalid_floating_point_number (words);
330 
331 	      /* We leave return_value alone: admit we read the
332 	         number, but return a floating exception
333 	         because we can't encode the number.  */
334 	    }
335 	  else
336 	    {
337 	      lp = words;
338 
339 	      /* Word 1. Sign, exponent and perhaps high bits.
340 	         Assume 2's complement integers.  */
341 	      word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits))
342 		       | ((f->sign == '+') ? 0 : 0x8000)
343 		       | next_bits (15 - exponent_bits));
344 	      *lp++ = word1;
345 
346 	      /* The rest of the words are just mantissa bits.  */
347 	      for (; lp < words + precision; lp++)
348 		*lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
349 
350 	      if (next_bits (1))
351 		{
352 		  /* Since the NEXT bit is a 1, round UP the mantissa.
353 		     The cunning design of these hidden-1 floats permits
354 		     us to let the mantissa overflow into the exponent, and
355 		     it 'does the right thing'. However, we lose if the
356 		     highest-order bit of the lowest-order word flips.
357 		     Is that clear?  */
358 		  unsigned long carry;
359 
360 		  /*
361 		    #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
362 		    Please allow at least 1 more bit in carry than is in a LITTLENUM.
363 		    We need that extra bit to hold a carry during a LITTLENUM carry
364 		    propagation. Another extra bit (kept 0) will assure us that we
365 		    don't get a sticky sign bit after shifting right, and that
366 		    permits us to propagate the carry without any masking of bits.
367 		    #endif   */
368 		  for (carry = 1, lp--;
369 		       carry && (lp >= words);
370 		       lp--)
371 		    {
372 		      carry = *lp + carry;
373 		      *lp = carry;
374 		      carry >>= LITTLENUM_NUMBER_OF_BITS;
375 		    }
376 
377 		  if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
378 		    {
379 		      make_invalid_floating_point_number (words);
380 		      /* We leave return_value alone: admit we read the
381 		         number, but return a floating exception
382 		         because we can't encode the number.  */
383 		    }
384 		}
385 	    }
386 	}
387     }
388   return return_value;
389 }
390 
391 /* JF this used to be in vax.c but this looks like a better place for it.  */
392 
393 /* In:	input_line_pointer->the 1st character of a floating-point
394   		number.
395   	1 letter denoting the type of statement that wants a
396   		binary floating point number returned.
397   	Address of where to build floating point literal.
398   		Assumed to be 'big enough'.
399   	Address of where to return size of literal (in chars).
400 
401    Out:	Input_line_pointer->of next char after floating number.
402   	Error message, or 0.
403   	Floating point literal.
404   	Number of chars we used for the literal.  */
405 
406 #define MAXIMUM_NUMBER_OF_LITTLENUMS  8 	/* For .hfloats.  */
407 
408 char *
409 vax_md_atof (int what_statement_type,
410 	     char *literalP,
411 	     int *sizeP)
412 {
413   LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS];
414   char kind_of_float;
415   unsigned int number_of_chars;
416   LITTLENUM_TYPE *littlenumP;
417 
418   switch (what_statement_type)
419     {
420     case 'F':
421     case 'f':
422       kind_of_float = 'f';
423       break;
424 
425     case 'D':
426     case 'd':
427       kind_of_float = 'd';
428       break;
429 
430     case 'g':
431       kind_of_float = 'g';
432       break;
433 
434     case 'h':
435       kind_of_float = 'h';
436       break;
437 
438     default:
439       kind_of_float = 0;
440       break;
441     };
442 
443   if (kind_of_float)
444     {
445       LITTLENUM_TYPE *limit;
446 
447       input_line_pointer = atof_vax (input_line_pointer,
448 				     kind_of_float,
449 				     words);
450       /* The atof_vax() builds up 16-bit numbers.
451          Since the assembler may not be running on
452          a little-endian machine, be very careful about
453          converting words to chars.  */
454       number_of_chars = atof_vax_sizeof (kind_of_float);
455       know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE));
456       limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE));
457       for (littlenumP = words; littlenumP < limit; littlenumP++)
458 	{
459 	  md_number_to_chars (literalP, *littlenumP, sizeof (LITTLENUM_TYPE));
460 	  literalP += sizeof (LITTLENUM_TYPE);
461 	};
462     }
463   else
464     number_of_chars = 0;
465 
466   *sizeP = number_of_chars;
467   return kind_of_float ? NULL : _("Unrecognized or unsupported floating point constant");
468 }
469