Back to index

cell-binutils  2.17cvs20070401
atof-vax.c
Go to the documentation of this file.
00001 /* atof_vax.c - turn a Flonum into a VAX floating point number
00002    Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000, 2005
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of GAS, the GNU Assembler.
00006 
00007    GAS is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2, or (at your option)
00010    any later version.
00011 
00012    GAS is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with GAS; see the file COPYING.  If not, write to the Free
00019    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00020    02110-1301, USA.  */
00021 
00022 #include "as.h"
00023 
00024 /* Precision in LittleNums.  */
00025 #define MAX_PRECISION       8
00026 #define H_PRECISION  8
00027 #define G_PRECISION  4
00028 #define D_PRECISION  4
00029 #define F_PRECISION  2
00030 
00031 /* Length in LittleNums of guard bits.  */
00032 #define GUARD        2
00033 
00034 int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *);
00035 
00036 /* Number of chars in flonum type 'letter'.  */
00037 
00038 static int
00039 atof_vax_sizeof (int letter)
00040 {
00041   int return_value;
00042 
00043   /* Permitting uppercase letters is probably a bad idea.
00044      Please use only lower-cased letters in case the upper-cased
00045      ones become unsupported!  */
00046   switch (letter)
00047     {
00048     case 'f':
00049     case 'F':
00050       return_value = 4;
00051       break;
00052 
00053     case 'd':
00054     case 'D':
00055     case 'g':
00056     case 'G':
00057       return_value = 8;
00058       break;
00059 
00060     case 'h':
00061     case 'H':
00062       return_value = 16;
00063       break;
00064 
00065     default:
00066       return_value = 0;
00067       break;
00068     }
00069 
00070   return return_value;
00071 }
00072 
00073 static const long mask[] =
00074 {
00075   0x00000000,
00076   0x00000001,
00077   0x00000003,
00078   0x00000007,
00079   0x0000000f,
00080   0x0000001f,
00081   0x0000003f,
00082   0x0000007f,
00083   0x000000ff,
00084   0x000001ff,
00085   0x000003ff,
00086   0x000007ff,
00087   0x00000fff,
00088   0x00001fff,
00089   0x00003fff,
00090   0x00007fff,
00091   0x0000ffff,
00092   0x0001ffff,
00093   0x0003ffff,
00094   0x0007ffff,
00095   0x000fffff,
00096   0x001fffff,
00097   0x003fffff,
00098   0x007fffff,
00099   0x00ffffff,
00100   0x01ffffff,
00101   0x03ffffff,
00102   0x07ffffff,
00103   0x0fffffff,
00104   0x1fffffff,
00105   0x3fffffff,
00106   0x7fffffff,
00107   0xffffffff
00108 };
00109 
00110 
00111 /* Shared between flonum_gen2vax and next_bits.  */
00112 static int bits_left_in_littlenum;
00113 static LITTLENUM_TYPE *littlenum_pointer;
00114 static LITTLENUM_TYPE *littlenum_end;
00115 
00116 static int
00117 next_bits (int number_of_bits)
00118 {
00119   int return_value;
00120 
00121   if (littlenum_pointer < littlenum_end)
00122     return 0;
00123   if (number_of_bits >= bits_left_in_littlenum)
00124     {
00125       return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
00126       number_of_bits -= bits_left_in_littlenum;
00127       return_value <<= number_of_bits;
00128       bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
00129       littlenum_pointer--;
00130       if (littlenum_pointer >= littlenum_end)
00131        return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & mask[number_of_bits];
00132     }
00133   else
00134     {
00135       bits_left_in_littlenum -= number_of_bits;
00136       return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum);
00137     }
00138   return return_value;
00139 }
00140 
00141 static void
00142 make_invalid_floating_point_number (LITTLENUM_TYPE *words)
00143 {
00144   *words = 0x8000;          /* Floating Reserved Operand Code.  */
00145 }
00146 
00147 
00148 static int                  /* 0 means letter is OK.  */
00149 what_kind_of_float (int letter,                  /* In: lowercase please. What kind of float?  */
00150                   int *precisionP,        /* Number of 16-bit words in the float.  */
00151                   long *exponent_bitsP)   /* Number of exponent bits.  */
00152 {
00153   int retval;
00154 
00155   retval = 0;
00156   switch (letter)
00157     {
00158     case 'f':
00159       *precisionP = F_PRECISION;
00160       *exponent_bitsP = 8;
00161       break;
00162 
00163     case 'd':
00164       *precisionP = D_PRECISION;
00165       *exponent_bitsP = 8;
00166       break;
00167 
00168     case 'g':
00169       *precisionP = G_PRECISION;
00170       *exponent_bitsP = 11;
00171       break;
00172 
00173     case 'h':
00174       *precisionP = H_PRECISION;
00175       *exponent_bitsP = 15;
00176       break;
00177 
00178     default:
00179       retval = 69;
00180       break;
00181     }
00182   return retval;
00183 }
00184 
00185 /* Warning: this returns 16-bit LITTLENUMs, because that is
00186    what the VAX thinks in. It is up to the caller to figure
00187    out any alignment problems and to conspire for the bytes/word
00188    to be emitted in the right order. Bigendians beware!  */
00189 
00190 static char *
00191 atof_vax (char *str,               /* Text to convert to binary.  */
00192          int what_kind,            /* 'd', 'f', 'g', 'h'  */
00193          LITTLENUM_TYPE *words)    /* Build the binary here.  */
00194 {
00195   FLONUM_TYPE f;
00196   LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
00197   /* Extra bits for zeroed low-order bits.
00198      The 1st MAX_PRECISION are zeroed,
00199      the last contain flonum bits.  */
00200   char *return_value;
00201   int precision;            /* Number of 16-bit words in the format.  */
00202   long exponent_bits;
00203 
00204   return_value = str;
00205   f.low = bits + MAX_PRECISION;
00206   f.high = NULL;
00207   f.leader = NULL;
00208   f.exponent = 0;
00209   f.sign = '\0';
00210 
00211   if (what_kind_of_float (what_kind, &precision, &exponent_bits))
00212     {
00213       return_value = NULL;
00214       make_invalid_floating_point_number (words);
00215     }
00216 
00217   if (return_value)
00218     {
00219       memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
00220 
00221       /* Use more LittleNums than seems
00222          necessary: the highest flonum may have
00223          15 leading 0 bits, so could be useless.  */
00224       f.high = f.low + precision - 1 + GUARD;
00225 
00226       if (atof_generic (&return_value, ".", "eE", &f))
00227        {
00228          make_invalid_floating_point_number (words);
00229          return_value = NULL;
00230        }
00231       else if (flonum_gen2vax (what_kind, &f, words))
00232        return_value = NULL;
00233     }
00234 
00235   return return_value;
00236 }
00237 
00238 /* In: a flonum, a vax floating point format.
00239    Out: a vax floating-point bit pattern.  */
00240 
00241 int
00242 flonum_gen2vax (int format_letter, /* One of 'd' 'f' 'g' 'h'.  */
00243               FLONUM_TYPE *f,
00244               LITTLENUM_TYPE *words)      /* Deliver answer here.  */
00245 {
00246   LITTLENUM_TYPE *lp;
00247   int precision;
00248   long exponent_bits;
00249   int return_value;         /* 0 == OK.  */
00250 
00251   return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
00252 
00253   if (return_value != 0)
00254     make_invalid_floating_point_number (words);
00255 
00256   else
00257     {
00258       if (f->low > f->leader)
00259        /* 0.0e0 seen.  */
00260        memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
00261 
00262       else
00263        {
00264          long exponent_1;
00265          long exponent_2;
00266          long exponent_3;
00267          long exponent_4;
00268          int exponent_skippage;
00269          LITTLENUM_TYPE word1;
00270 
00271          /* JF: Deal with new Nan, +Inf and -Inf codes.  */
00272          if (f->sign != '-' && f->sign != '+')
00273            {
00274              make_invalid_floating_point_number (words);
00275              return return_value;
00276            }
00277 
00278          /* All vaxen floating_point formats (so far) have:
00279             Bit 15 is sign bit.
00280             Bits 14:n are excess-whatever exponent.
00281             Bits n-1:0 (if any) are most significant bits of fraction.
00282             Bits 15:0 of the next word are the next most significant bits.
00283             And so on for each other word.
00284 
00285             All this to be compatible with a KF11?? (Which is still faster
00286             than lots of vaxen I can think of, but it also has higher
00287             maintenance costs ... sigh).
00288 
00289             So we need: number of bits of exponent, number of bits of
00290             mantissa.  */
00291 
00292          bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
00293          littlenum_pointer = f->leader;
00294          littlenum_end = f->low;
00295          /* Seek (and forget) 1st significant bit.  */
00296          for (exponent_skippage = 0;
00297               !next_bits (1);
00298               exponent_skippage++);;
00299 
00300          exponent_1 = f->exponent + f->leader + 1 - f->low;
00301          /* Radix LITTLENUM_RADIX, point just higher than f->leader.  */
00302          exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
00303          /* Radix 2.  */
00304          exponent_3 = exponent_2 - exponent_skippage;
00305          /* Forget leading zeros, forget 1st bit.  */
00306          exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
00307          /* Offset exponent.  */
00308 
00309          if (exponent_4 & ~mask[exponent_bits])
00310            {
00311              /* Exponent overflow. Lose immediately.  */
00312              make_invalid_floating_point_number (words);
00313 
00314              /* We leave return_value alone: admit we read the
00315                 number, but return a floating exception
00316                 because we can't encode the number.  */
00317            }
00318          else
00319            {
00320              lp = words;
00321 
00322              /* Word 1. Sign, exponent and perhaps high bits.
00323                 Assume 2's complement integers.  */
00324              word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits))
00325                      | ((f->sign == '+') ? 0 : 0x8000)
00326                      | next_bits (15 - exponent_bits));
00327              *lp++ = word1;
00328 
00329              /* The rest of the words are just mantissa bits.  */
00330              for (; lp < words + precision; lp++)
00331               *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
00332 
00333              if (next_bits (1))
00334               {
00335                 /* Since the NEXT bit is a 1, round UP the mantissa.
00336                    The cunning design of these hidden-1 floats permits
00337                    us to let the mantissa overflow into the exponent, and
00338                    it 'does the right thing'. However, we lose if the
00339                    highest-order bit of the lowest-order word flips.
00340                    Is that clear?  */
00341                 unsigned long carry;
00342 
00343                 /*
00344                   #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
00345                   Please allow at least 1 more bit in carry than is in a LITTLENUM.
00346                   We need that extra bit to hold a carry during a LITTLENUM carry
00347                   propagation. Another extra bit (kept 0) will assure us that we
00348                   don't get a sticky sign bit after shifting right, and that
00349                   permits us to propagate the carry without any masking of bits.
00350                   #endif   */
00351                 for (carry = 1, lp--;
00352                      carry && (lp >= words);
00353                      lp--)
00354                   {
00355                     carry = *lp + carry;
00356                     *lp = carry;
00357                     carry >>= LITTLENUM_NUMBER_OF_BITS;
00358                   }
00359 
00360                 if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
00361                   {
00362                     make_invalid_floating_point_number (words);
00363                     /* We leave return_value alone: admit we read the
00364                        number, but return a floating exception
00365                        because we can't encode the number.  */
00366                   }
00367               }
00368            }
00369        }
00370     }
00371   return return_value;
00372 }
00373 
00374 /* JF this used to be in vax.c but this looks like a better place for it.  */
00375 
00376 /* In: input_line_pointer->the 1st character of a floating-point
00377               number.
00378        1 letter denoting the type of statement that wants a
00379               binary floating point number returned.
00380        Address of where to build floating point literal.
00381               Assumed to be 'big enough'.
00382        Address of where to return size of literal (in chars).
00383   
00384    Out:       Input_line_pointer->of next char after floating number.
00385        Error message, or 0.
00386        Floating point literal.
00387        Number of chars we used for the literal.  */
00388 
00389 #define MAXIMUM_NUMBER_OF_LITTLENUMS  8   /* For .hfloats.  */
00390 
00391 char *
00392 md_atof (int what_statement_type,
00393         char *literalP,
00394         int *sizeP)
00395 {
00396   LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS];
00397   char kind_of_float;
00398   int number_of_chars;
00399   LITTLENUM_TYPE *littlenumP;
00400 
00401   switch (what_statement_type)
00402     {
00403     case 'F':
00404     case 'f':
00405       kind_of_float = 'f';
00406       break;
00407 
00408     case 'D':
00409     case 'd':
00410       kind_of_float = 'd';
00411       break;
00412 
00413     case 'g':
00414       kind_of_float = 'g';
00415       break;
00416 
00417     case 'h':
00418       kind_of_float = 'h';
00419       break;
00420 
00421     default:
00422       kind_of_float = 0;
00423       break;
00424     };
00425 
00426   if (kind_of_float)
00427     {
00428       LITTLENUM_TYPE *limit;
00429 
00430       input_line_pointer = atof_vax (input_line_pointer,
00431                                  kind_of_float,
00432                                  words);
00433       /* The atof_vax() builds up 16-bit numbers.
00434          Since the assembler may not be running on
00435          a little-endian machine, be very careful about
00436          converting words to chars.  */
00437       number_of_chars = atof_vax_sizeof (kind_of_float);
00438       know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE));
00439       limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE));
00440       for (littlenumP = words; littlenumP < limit; littlenumP++)
00441        {
00442          md_number_to_chars (literalP, *littlenumP, sizeof (LITTLENUM_TYPE));
00443          literalP += sizeof (LITTLENUM_TYPE);
00444        };
00445     }
00446   else
00447     number_of_chars = 0;
00448 
00449   *sizeP = number_of_chars;
00450   return kind_of_float ? NULL : _("Bad call to md_atof()");
00451 }