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

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

unix.superglobalmegacorp.com

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