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