Annotation of gas/atof-vax.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.