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

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

unix.superglobalmegacorp.com

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