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