Annotation of gas/atof-vax.c, revision 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.