Annotation of gas/atof-i386.c, revision 1.1

1.1     ! root        1: /* atof_i386.c -- turn a Flonum into an i386 floating point number
        !             2:    Copyright (C) 1987 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GAS, the GNU Assembler.
        !             5: 
        !             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.  */
        !            19: 
        !            20: #include "flonum.h"
        !            21: #ifdef USG
        !            22: #define bzero(s,n) memset(s,0,n)
        !            23: #endif
        !            24: 
        !            25: extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */
        !            26: #define NULL (0)
        !            27: 
        !            28: extern char EXP_CHARS[];
        !            29:                                /* Precision in LittleNums. */
        !            30: #define MAX_PRECISION (6)
        !            31: #define F_PRECISION (2)
        !            32: #define D_PRECISION (4)
        !            33: #define X_PRECISION (5)
        !            34: 
        !            35:                                /* Length in LittleNums of guard bits. */
        !            36: #define GUARD (2)
        !            37: 
        !            38: int                            /* Number of chars in flonum type 'letter'. */
        !            39: atof_sizeof (letter)
        !            40:      char letter;
        !            41: {
        !            42:   int  return_value;
        !            43: 
        !            44:   /*
        !            45:    * Permitting uppercase letters is probably a bad idea.
        !            46:    * Please use only lower-cased letters in case the upper-cased
        !            47:    * ones become unsupported!
        !            48:    */
        !            49:   switch (letter)
        !            50:     {
        !            51:     case 'f':
        !            52:     case 'F':
        !            53:       return_value = F_PRECISION;
        !            54:       break;
        !            55: 
        !            56:     case 'd':
        !            57:     case 'D':
        !            58:       return_value = D_PRECISION;
        !            59:       break;
        !            60: 
        !            61:     case 'x':
        !            62:     case 'X':
        !            63:       return_value = X_PRECISION;
        !            64:       break;
        !            65: 
        !            66:     default:
        !            67:       return_value = 0;
        !            68:       break;
        !            69:     }
        !            70:   return (return_value);
        !            71: }
        !            72: 
        !            73: static unsigned long int mask [] = {
        !            74:   0x00000000,
        !            75:   0x00000001,
        !            76:   0x00000003,
        !            77:   0x00000007,
        !            78:   0x0000000f,
        !            79:   0x0000001f,
        !            80:   0x0000003f,
        !            81:   0x0000007f,
        !            82:   0x000000ff,
        !            83:   0x000001ff,
        !            84:   0x000003ff,
        !            85:   0x000007ff,
        !            86:   0x00000fff,
        !            87:   0x00001fff,
        !            88:   0x00003fff,
        !            89:   0x00007fff,
        !            90:   0x0000ffff,
        !            91:   0x0001ffff,
        !            92:   0x0003ffff,
        !            93:   0x0007ffff,
        !            94:   0x000fffff,
        !            95:   0x001fffff,
        !            96:   0x003fffff,
        !            97:   0x007fffff,
        !            98:   0x00ffffff,
        !            99:   0x01ffffff,
        !           100:   0x03ffffff,
        !           101:   0x07ffffff,
        !           102:   0x0fffffff,
        !           103:   0x1fffffff,
        !           104:   0x3fffffff,
        !           105:   0x7fffffff,
        !           106:   0xffffffff
        !           107:   };
        !           108: 
        !           109: static int bits_left_in_littlenum;
        !           110: static int littlenums_left;
        !           111: static LITTLENUM_TYPE *        littlenum_pointer;
        !           112: 
        !           113: static int
        !           114: next_bits (number_of_bits)
        !           115:      int               number_of_bits;
        !           116: {
        !           117:   int                  return_value;
        !           118: 
        !           119:   if(!littlenums_left)
        !           120:     return 0;
        !           121:   if (number_of_bits >= bits_left_in_littlenum) {
        !           122:     return_value  = mask [bits_left_in_littlenum] & *littlenum_pointer;
        !           123:     number_of_bits -= bits_left_in_littlenum;
        !           124:     return_value <<= number_of_bits;
        !           125:     if(littlenums_left) {
        !           126:       bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
        !           127:       littlenum_pointer --;
        !           128:       --littlenums_left;
        !           129:       return_value |=
        !           130:        (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits];
        !           131:     }
        !           132:   } else {
        !           133:     bits_left_in_littlenum -= number_of_bits;
        !           134:     return_value =
        !           135:       mask [number_of_bits] & (*littlenum_pointer>>bits_left_in_littlenum);
        !           136:   }
        !           137:   return (return_value);
        !           138: }
        !           139: 
        !           140: static void
        !           141: make_invalid_floating_point_number (words, precision)
        !           142:      LITTLENUM_TYPE *  words;
        !           143:      int precision;
        !           144: {
        !           145:   bzero (words, precision * sizeof (LITTLENUM_TYPE));
        !           146:   switch (precision) {
        !           147:   case F_PRECISION:
        !           148:     words[0] = 0xffc0; break;
        !           149:   case D_PRECISION:
        !           150:     words[0] = 0xfff8; break;
        !           151:   case X_PRECISION:
        !           152:     words[0] = 0xffff; words[1] = 0xc000; break;
        !           153:   }
        !           154: }
        !           155: 
        !           156: /***********************************************************************\
        !           157: *                                                                      *
        !           158: *      Warning: this returns 16-bit LITTLENUMs, because that is        *
        !           159: *      what the VAX thinks in. It is up to the caller to figure        *
        !           160: *      out any alignment problems and to conspire for the bytes/word   *
        !           161: *      to be emitted in the right order. Bigendians beware!            *
        !           162: *                                                                      *
        !           163: \***********************************************************************/
        !           164: 
        !           165: char *                         /* Return pointer past text consumed. */
        !           166: atof_i386 (str, what_kind, words)
        !           167:      char *            str;    /* Text to convert to binary. */
        !           168:      char              what_kind; /* 'd', 'f', 'g', 'h' */
        !           169:      LITTLENUM_TYPE *  words;  /* Build the binary here. */
        !           170: {
        !           171:        FLONUM_TYPE     f;
        !           172:        LITTLENUM_TYPE  bits [MAX_PRECISION + MAX_PRECISION + GUARD];
        !           173:                                /* Extra bits for zeroed low-order bits. */
        !           174:                                /* The 1st MAX_PRECISION are zeroed, */
        !           175:                                /* the last contain flonum bits. */
        !           176:        char *          return_value;
        !           177:        int             precision; /* Number of 16-bit words in the format. */
        !           178:        long int        exponent_bits;
        !           179: 
        !           180:        long int        exponent_1;
        !           181:        long int        exponent_2;
        !           182:        long int        exponent_3;
        !           183:        long int        exponent_4;
        !           184:        int             exponent_skippage;
        !           185:        LITTLENUM_TYPE  word1;
        !           186:        LITTLENUM_TYPE *        lp;
        !           187: 
        !           188:        return_value = str;
        !           189:        f.low   = bits + MAX_PRECISION;
        !           190:        f.high  = NULL;
        !           191:        f.leader        = NULL;
        !           192:        f.exponent      = NULL;
        !           193:        f.sign  = '\0';
        !           194: 
        !           195:                                /* Use more LittleNums than seems */
        !           196:                                /* necessary: the highest flonum may have */
        !           197:                                /* 15 leading 0 bits, so could be useless. */
        !           198: 
        !           199:        bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION);
        !           200: 
        !           201:        switch(what_kind) {
        !           202:        case 'f':
        !           203:        case 'F':
        !           204:                precision = F_PRECISION;
        !           205:                exponent_bits = 8;
        !           206:                break;
        !           207: 
        !           208:        case 'd':
        !           209:        case 'D':
        !           210:                precision = D_PRECISION;
        !           211:                exponent_bits = 11;
        !           212:                break;
        !           213: 
        !           214:        case 'x':
        !           215:        case 'X':
        !           216:                precision = X_PRECISION;
        !           217:                exponent_bits = 15;
        !           218:                break;
        !           219: 
        !           220:        default:
        !           221:                make_invalid_floating_point_number (words, precision);
        !           222:                return NULL;
        !           223:        }
        !           224: 
        !           225:        f.high = f.low + precision - 1 + GUARD;
        !           226: 
        !           227:        if (atof_generic (& return_value, ".", EXP_CHARS, & f)) {
        !           228:                as_warn("Error converting floating point number (Exponent overflow?)");
        !           229:                make_invalid_floating_point_number (words, precision);
        !           230:                return NULL;
        !           231:        }
        !           232: 
        !           233:        if (f.low > f.leader) {
        !           234:                /* 0.0e0 seen. */
        !           235:                bzero (words, sizeof(LITTLENUM_TYPE) * precision);
        !           236:                return return_value;
        !           237:        }
        !           238: 
        !           239:        if(f.sign!='+' && f.sign!='-') {
        !           240:                make_invalid_floating_point_number(words,precision);
        !           241:                return NULL;
        !           242:        }
        !           243:                /*
        !           244:                 * All vaxen floating_point formats (so far) have:
        !           245:                 * Bit 15 is sign bit.
        !           246:                 * Bits 14:n are excess-whatever exponent.
        !           247:                 * Bits n-1:0 (if any) are most significant bits of fraction.
        !           248:                 * Bits 15:0 of the next word are the next most significant bits.
        !           249:                 * And so on for each other word.
        !           250:                 *
        !           251:                 * So we need: number of bits of exponent, number of bits of
        !           252:                 * mantissa.
        !           253:                 */
        !           254:        bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
        !           255:        littlenum_pointer = f.leader;
        !           256:        littlenums_left = 1 + f.leader-f.low;
        !           257:        if (precision != X_PRECISION) {
        !           258:          /* Seek (and forget) 1st significant bit */
        !           259:          for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) ;
        !           260:        } else {
        !           261:          /* Dont seek (and forget) 1st significant bit for X format */
        !           262:          for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) ;
        !           263:          exponent_skippage--;
        !           264:          bits_left_in_littlenum++;
        !           265:        }
        !           266:        exponent_1 = f.exponent + f.leader + 1 - f.low;
        !           267:        /* Radix LITTLENUM_RADIX, point just higher than f.leader. */
        !           268:        exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
        !           269:        /* Radix 2. */
        !           270:        exponent_3 = exponent_2 - exponent_skippage;
        !           271:        /* Forget leading zeros, forget 1st bit. */
        !           272:        exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
        !           273:        /* Offset exponent. */
        !           274: 
        !           275:        if (exponent_4 & ~ mask [exponent_bits]) {
        !           276:                        /*
        !           277:                         * Exponent overflow. Lose immediately.
        !           278:                         */
        !           279: 
        !           280:                        /*
        !           281:                         * We leave return_value alone: admit we read the
        !           282:                         * number, but return a floating exception
        !           283:                         * because we can't encode the number.
        !           284:                         */
        !           285: 
        !           286:                as_warn("Exponent overflow in floating-point number");
        !           287:                make_invalid_floating_point_number (words, precision);
        !           288:                return return_value;
        !           289:        }
        !           290:        lp = words;
        !           291: 
        !           292:        /* Word 1. Sign, exponent and perhaps high bits. */
        !           293:        /* Assume 2's complement integers. */
        !           294:        word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits));
        !           295:        word1 |= ((f.sign == '+') ? 0 : 0x8000);
        !           296:        word1 |= next_bits (15 - exponent_bits);
        !           297:        * lp ++ = word1;
        !           298: 
        !           299:        /* The rest of the words are just mantissa bits. */
        !           300:        for (; lp < words + precision; lp++)
        !           301:                * lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
        !           302: 
        !           303:        if (next_bits (1)) {
        !           304:                unsigned long int       carry;
        !           305:                        /*
        !           306:                         * Since the NEXT bit is a 1, round UP the mantissa.
        !           307:                         * The cunning design of these hidden-1 floats permits
        !           308:                         * us to let the mantissa overflow into the exponent, and
        !           309:                         * it 'does the right thing'. However, we lose if the
        !           310:                         * highest-order bit of the lowest-order word flips.
        !           311:                         * Is that clear?
        !           312:                         */
        !           313: 
        !           314: 
        !           315: /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
        !           316:        Please allow at least 1 more bit in carry than is in a LITTLENUM.
        !           317:        We need that extra bit to hold a carry during a LITTLENUM carry
        !           318:        propagation. Another extra bit (kept 0) will assure us that we
        !           319:        don't get a sticky sign bit after shifting right, and that
        !           320:        permits us to propagate the carry without any masking of bits.
        !           321: #endif */
        !           322:                for (carry = 1, lp --; carry && (lp >= words); lp --) {
        !           323:                        carry = * lp + carry;
        !           324:                        * lp = carry;
        !           325:                        carry >>= LITTLENUM_NUMBER_OF_BITS;
        !           326:                }
        !           327:                if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) {
        !           328:                        /* We leave return_value alone: admit we read the
        !           329:                         * number, but return a floating exception
        !           330:                         * because we can't encode the number.
        !           331:                         */
        !           332:                        make_invalid_floating_point_number (words, precision);
        !           333:                        return return_value;
        !           334:                }
        !           335:        }
        !           336:        return (return_value);
        !           337: }
        !           338: 
        !           339: /* This is really identical to atof_m68k except for some details */
        !           340: 
        !           341: gen_to_words(words,precision,exponent_bits)
        !           342: LITTLENUM_TYPE *words;
        !           343: long int       exponent_bits;
        !           344: {
        !           345:        int return_value=0;
        !           346: 
        !           347:        long int        exponent_1;
        !           348:        long int        exponent_2;
        !           349:        long int        exponent_3;
        !           350:        long int        exponent_4;
        !           351:        int             exponent_skippage;
        !           352:        LITTLENUM_TYPE  word1;
        !           353:        LITTLENUM_TYPE *        lp;
        !           354: 
        !           355:        if (generic_floating_point_number.low > generic_floating_point_number.leader) {
        !           356:                /* 0.0e0 seen. */
        !           357:                bzero (words, sizeof(LITTLENUM_TYPE) * precision);
        !           358:                return return_value;
        !           359:        }
        !           360: 
        !           361:                /*
        !           362:                 * All vaxen floating_point formats (so far) have:
        !           363:                 * Bit 15 is sign bit.
        !           364:                 * Bits 14:n are excess-whatever exponent.
        !           365:                 * Bits n-1:0 (if any) are most significant bits of fraction.
        !           366:                 * Bits 15:0 of the next word are the next most significant bits.
        !           367:                 * And so on for each other word.
        !           368:                 *
        !           369:                 * So we need: number of bits of exponent, number of bits of
        !           370:                 * mantissa.
        !           371:                 */
        !           372:        bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
        !           373:        littlenum_pointer = generic_floating_point_number.leader;
        !           374:        littlenums_left = 1+generic_floating_point_number.leader - generic_floating_point_number.low;
        !           375:        /* Seek (and forget) 1st significant bit */
        !           376:        for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++)
        !           377:                ;
        !           378:        exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader + 1 -
        !           379:  generic_floating_point_number.low;
        !           380:        /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */
        !           381:        exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
        !           382:        /* Radix 2. */
        !           383:        exponent_3 = exponent_2 - exponent_skippage;
        !           384:        /* Forget leading zeros, forget 1st bit. */
        !           385:        exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
        !           386:        /* Offset exponent. */
        !           387: 
        !           388:        if (exponent_4 & ~ mask [exponent_bits]) {
        !           389:                        /*
        !           390:                         * Exponent overflow. Lose immediately.
        !           391:                         */
        !           392: 
        !           393:                        /*
        !           394:                         * We leave return_value alone: admit we read the
        !           395:                         * number, but return a floating exception
        !           396:                         * because we can't encode the number.
        !           397:                         */
        !           398: 
        !           399:                make_invalid_floating_point_number (words, precision);
        !           400:                return return_value;
        !           401:        }
        !           402:        lp = words;
        !           403: 
        !           404:        /* Word 1. Sign, exponent and perhaps high bits. */
        !           405:        /* Assume 2's complement integers. */
        !           406:        word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits));
        !           407:        word1 |= ((generic_floating_point_number.sign == '+') ? 0 : 0x8000);
        !           408:        word1 |= next_bits (15 - exponent_bits);
        !           409:        * lp ++ = word1;
        !           410: 
        !           411:        /* The rest of the words are just mantissa bits. */
        !           412:        for (; lp < words + precision; lp++)
        !           413:                * lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
        !           414: 
        !           415:        if (next_bits (1)) {
        !           416:                unsigned long int       carry;
        !           417:                        /*
        !           418:                         * Since the NEXT bit is a 1, round UP the mantissa.
        !           419:                         * The cunning design of these hidden-1 floats permits
        !           420:                         * us to let the mantissa overflow into the exponent, and
        !           421:                         * it 'does the right thing'. However, we lose if the
        !           422:                         * highest-order bit of the lowest-order word flips.
        !           423:                         * Is that clear?
        !           424:                         */
        !           425: 
        !           426: 
        !           427: /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
        !           428:        Please allow at least 1 more bit in carry than is in a LITTLENUM.
        !           429:        We need that extra bit to hold a carry during a LITTLENUM carry
        !           430:        propagation. Another extra bit (kept 0) will assure us that we
        !           431:        don't get a sticky sign bit after shifting right, and that
        !           432:        permits us to propagate the carry without any masking of bits.
        !           433: #endif */
        !           434:                for (carry = 1, lp --; carry && (lp >= words); lp --) {
        !           435:                        carry = * lp + carry;
        !           436:                        * lp = carry;
        !           437:                        carry >>= LITTLENUM_NUMBER_OF_BITS;
        !           438:                }
        !           439:                if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) {
        !           440:                        /* We leave return_value alone: admit we read the
        !           441:                         * number, but return a floating exception
        !           442:                         * because we can't encode the number.
        !           443:                         */
        !           444:                        make_invalid_floating_point_number (words, precision);
        !           445:                        return return_value;
        !           446:                }
        !           447:        }
        !           448:        return (return_value);
        !           449: }
        !           450: 
        !           451: /* This routine is a real kludge.  Someone really should do it better, but
        !           452:    I'm too lazy, and I don't understand this stuff all too well anyway
        !           453:    (JF)
        !           454:  */
        !           455: int_to_gen(x)
        !           456: long x;
        !           457: {
        !           458:        char buf[20];
        !           459:        char *bufp;
        !           460: 
        !           461:        sprintf(buf,"%ld",x);
        !           462:        bufp= &buf[0];
        !           463:        if(atof_generic(&bufp,".", EXP_CHARS, &generic_floating_point_number))
        !           464:                as_warn("Error converting number to floating point (Exponent overflow?)");
        !           465: }

unix.superglobalmegacorp.com

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