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

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