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

1.1.1.3 ! root        1: /* atof_m68k.c - turn a Flonum into a 68020 floating point number
        !             2:    Copyright (C) 1987 Free Software Foundation, Inc.
1.1       root        3: 
1.1.1.3 ! root        4: This file is part of GAS, the GNU Assembler.
1.1       root        5: 
1.1.1.3 ! root        6: GAS is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 1, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GAS is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GAS; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
1.1       root       19: 
                     20: #include "flonum.h"
1.1.1.3 ! root       21: #ifdef USG
        !            22: #define bzero(s,n) memset(s,0,n)
        !            23: #endif
1.1       root       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 (6)
                     34: #define P_PRECISION (6)
                     35: 
                     36:                                /* Length in LittleNums of guard bits. */
                     37: #define GUARD (2)
                     38: 
                     39: static unsigned long int mask [] = {
                     40:   0x00000000,
                     41:   0x00000001,
                     42:   0x00000003,
                     43:   0x00000007,
                     44:   0x0000000f,
                     45:   0x0000001f,
                     46:   0x0000003f,
                     47:   0x0000007f,
                     48:   0x000000ff,
                     49:   0x000001ff,
                     50:   0x000003ff,
                     51:   0x000007ff,
                     52:   0x00000fff,
                     53:   0x00001fff,
                     54:   0x00003fff,
                     55:   0x00007fff,
                     56:   0x0000ffff,
                     57:   0x0001ffff,
                     58:   0x0003ffff,
                     59:   0x0007ffff,
                     60:   0x000fffff,
                     61:   0x001fffff,
                     62:   0x003fffff,
                     63:   0x007fffff,
                     64:   0x00ffffff,
                     65:   0x01ffffff,
                     66:   0x03ffffff,
                     67:   0x07ffffff,
                     68:   0x0fffffff,
                     69:   0x1fffffff,
                     70:   0x3fffffff,
                     71:   0x7fffffff,
                     72:   0xffffffff
                     73:   };
                     74: 
1.1.1.2   root       75: static int bits_left_in_littlenum;
                     76: static int littlenums_left;
                     77: static LITTLENUM_TYPE *        littlenum_pointer;
                     78: 
1.1       root       79: static int
1.1.1.2   root       80: next_bits (number_of_bits)
1.1       root       81:      int               number_of_bits;
                     82: {
                     83:   int                  return_value;
                     84: 
1.1.1.2   root       85:   if(!littlenums_left)
                     86:        return 0;
                     87:   if (number_of_bits >= bits_left_in_littlenum)
1.1       root       88:     {
1.1.1.2   root       89:       return_value  = mask [bits_left_in_littlenum] & *littlenum_pointer;
                     90:       number_of_bits -= bits_left_in_littlenum;
1.1       root       91:       return_value <<= number_of_bits;
1.1.1.3 ! root       92:       if(--littlenums_left) {
1.1.1.2   root       93:              bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
                     94:              littlenum_pointer --;
                     95:              return_value |= (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits];
                     96:       }
1.1       root       97:     }
                     98:   else
                     99:     {
1.1.1.2   root      100:       bits_left_in_littlenum -= number_of_bits;
                    101:       return_value = mask [number_of_bits] & (*littlenum_pointer>>bits_left_in_littlenum);
1.1       root      102:     }
                    103:   return (return_value);
                    104: }
                    105: 
                    106: static void
                    107: make_invalid_floating_point_number (words)
                    108:      LITTLENUM_TYPE *  words;
                    109: {
1.1.1.3 ! root      110:        as_warn("cannot create floating-point number");
1.1       root      111:        words[0]= ((unsigned)-1)>>1;    /* Zero the leftmost bit */
                    112:        words[1]= -1;
                    113:        words[2]= -1;
                    114:        words[3]= -1;
                    115:        words[4]= -1;
                    116:        words[5]= -1;
                    117: }
                    118: 
                    119: /***********************************************************************\
1.1.1.3 ! root      120: *      Warning: this returns 16-bit LITTLENUMs. It is up to the caller *
        !           121: *      to figure out any alignment problems and to conspire for the    *
        !           122: *      bytes/word to be emitted in the right order. Bigendians beware! *
1.1       root      123: *                                                                      *
                    124: \***********************************************************************/
                    125: 
                    126: char *                         /* Return pointer past text consumed. */
                    127: atof_m68k (str, what_kind, words)
                    128:      char *            str;    /* Text to convert to binary. */
                    129:      char              what_kind; /* 'd', 'f', 'g', 'h' */
                    130:      LITTLENUM_TYPE *  words;  /* Build the binary here. */
                    131: {
                    132:        LITTLENUM_TYPE  bits [MAX_PRECISION + MAX_PRECISION + GUARD];
                    133:                                /* Extra bits for zeroed low-order bits. */
                    134:                                /* The 1st MAX_PRECISION are zeroed, */
                    135:                                /* the last contain flonum bits. */
                    136:        char *          return_value;
                    137:        int             precision; /* Number of 16-bit words in the format. */
                    138:        long int        exponent_bits;
                    139: 
                    140:        return_value = str;
1.1.1.3 ! root      141:        generic_floating_point_number.low       = bits + MAX_PRECISION;
        !           142:        generic_floating_point_number.high      = NULL;
        !           143:        generic_floating_point_number.leader    = NULL;
        !           144:        generic_floating_point_number.exponent  = NULL;
        !           145:        generic_floating_point_number.sign      = '\0';
1.1       root      146: 
                    147:                                /* Use more LittleNums than seems */
                    148:                                /* necessary: the highest flonum may have */
                    149:                                /* 15 leading 0 bits, so could be useless. */
                    150: 
                    151:        bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION);
                    152: 
                    153:        switch(what_kind) {
                    154:        case 'f':
                    155:        case 'F':
                    156:        case 's':
                    157:        case 'S':
                    158:                precision = F_PRECISION;
                    159:                exponent_bits = 8;
                    160:                break;
                    161: 
                    162:        case 'd':
                    163:        case 'D':
                    164:        case 'r':
                    165:        case 'R':
                    166:                precision = D_PRECISION;
                    167:                exponent_bits = 11;
                    168:                break;
                    169: 
                    170:        case 'x':
                    171:        case 'X':
1.1.1.3 ! root      172:        case 'e':
        !           173:        case 'E':
1.1       root      174:                precision = X_PRECISION;
                    175:                exponent_bits = 15;
                    176:                break;
                    177: 
                    178:        case 'p':
                    179:        case 'P':
                    180:                
                    181:                precision = P_PRECISION;
                    182:                exponent_bits= -1;
                    183:                break;
                    184: 
                    185:        default:
                    186:                make_invalid_floating_point_number (words);
                    187:                return NULL;
                    188:        }
                    189: 
1.1.1.3 ! root      190:        generic_floating_point_number.high = generic_floating_point_number.low + precision - 1 + GUARD;
1.1       root      191: 
1.1.1.3 ! root      192:        if (atof_generic (& return_value, ".", EXP_CHARS, & generic_floating_point_number)) {
        !           193:                /* as_warn("Error converting floating point number (Exponent overflow?)"); */
1.1       root      194:                make_invalid_floating_point_number (words);
                    195:                return NULL;
                    196:        }
1.1.1.3 ! root      197:        gen_to_words(words, precision, exponent_bits);
        !           198:        return return_value;
1.1       root      199: }
                    200: 
1.1.1.2   root      201: /* This is really identical to atof_m68k except for some details */
                    202: 
1.1       root      203: gen_to_words(words,precision,exponent_bits)
                    204: LITTLENUM_TYPE *words;
                    205: long int       exponent_bits;
1.1.1.3 ! root      206: int precision;
1.1       root      207: {
                    208:        int return_value=0;
                    209: 
                    210:        long int        exponent_1;
                    211:        long int        exponent_2;
                    212:        long int        exponent_3;
                    213:        long int        exponent_4;
                    214:        int             exponent_skippage;
                    215:        LITTLENUM_TYPE  word1;
                    216:        LITTLENUM_TYPE *        lp;
                    217: 
                    218:        if (generic_floating_point_number.low > generic_floating_point_number.leader) {
                    219:                /* 0.0e0 seen. */
                    220:                bzero (words, sizeof(LITTLENUM_TYPE) * precision);
                    221:                return return_value;
                    222:        }
                    223: 
1.1.1.3 ! root      224:        /* NaN:  Do the right thing */
        !           225:        if(generic_floating_point_number.sign==0) {
        !           226:                if(precision==F_PRECISION) {
        !           227:                        words[0]=0xffc0;
        !           228:                        words[1]=0x0007;
        !           229:                } else {
        !           230:                        words[0]=0x7ff0;
        !           231:                        words[1]=0;
        !           232:                        words[2]=0xffff;
        !           233:                        words[3]=0xffff;
        !           234:                }
        !           235:                return return_value;
        !           236:        } else if(generic_floating_point_number.sign=='P') {
        !           237:                /* +INF:  Do the right thing */
        !           238:                if(precision==F_PRECISION) {
        !           239:                        words[0]=0x7f80;
        !           240:                        words[1]=0;
        !           241:                } else {
        !           242:                        words[0]=0x7ff0;
        !           243:                        words[1]=0;
        !           244:                        words[2]=0;
        !           245:                        words[3]=0;
        !           246:                }
        !           247:                return return_value;
        !           248:        } else if(generic_floating_point_number.sign=='N') {
        !           249:                /* Negative INF */
        !           250:                if(precision==F_PRECISION) {
        !           251:                        words[0]=0xff80;
        !           252:                        words[1]=0x0;
        !           253:                } else {
        !           254:                        words[0]=0xfff0;
        !           255:                        words[1]=0x0;
        !           256:                        words[2]=0x0;
        !           257:                        words[3]=0x0;
        !           258:                }
        !           259:                return return_value;
        !           260:        }
1.1       root      261:                /*
1.1.1.3 ! root      262:                 * The floating point formats we support have:
1.1       root      263:                 * Bit 15 is sign bit.
                    264:                 * Bits 14:n are excess-whatever exponent.
                    265:                 * Bits n-1:0 (if any) are most significant bits of fraction.
                    266:                 * Bits 15:0 of the next word are the next most significant bits.
                    267:                 * And so on for each other word.
                    268:                 *
                    269:                 * So we need: number of bits of exponent, number of bits of
                    270:                 * mantissa.
                    271:                 */
                    272:        bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
                    273:        littlenum_pointer = generic_floating_point_number.leader;
1.1.1.2   root      274:        littlenums_left = 1+generic_floating_point_number.leader - generic_floating_point_number.low;
1.1       root      275:        /* Seek (and forget) 1st significant bit */
1.1.1.2   root      276:        for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++)
1.1       root      277:                ;
                    278:        exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader + 1 -
                    279:  generic_floating_point_number.low;
                    280:        /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */
                    281:        exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
                    282:        /* Radix 2. */
                    283:        exponent_3 = exponent_2 - exponent_skippage;
                    284:        /* Forget leading zeros, forget 1st bit. */
                    285:        exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
                    286:        /* Offset exponent. */
                    287: 
                    288:        if (exponent_4 & ~ mask [exponent_bits]) {
                    289:                        /*
                    290:                         * Exponent overflow. Lose immediately.
                    291:                         */
                    292: 
                    293:                        /*
                    294:                         * We leave return_value alone: admit we read the
                    295:                         * number, but return a floating exception
                    296:                         * because we can't encode the number.
                    297:                         */
                    298:                make_invalid_floating_point_number (words);
                    299:                return return_value;
                    300:        }
                    301:        lp = words;
                    302: 
                    303:        /* Word 1. Sign, exponent and perhaps high bits. */
                    304:        /* Assume 2's complement integers. */
                    305:        word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits)) |
1.1.1.2   root      306:  ((generic_floating_point_number.sign == '+') ? 0 : 0x8000) | next_bits (15 - exponent_bits);
1.1       root      307:        * lp ++ = word1;
                    308: 
1.1.1.3 ! root      309:        /* X_PRECISION is special: it has 16 bits of zero in the middle,
        !           310:           followed by a 1 bit. */
        !           311:        if(exponent_bits==15 && precision==X_PRECISION) {
        !           312:                *lp++=0;
        !           313:                *lp++= 1<<(LITTLENUM_NUMBER_OF_BITS)|next_bits(LITTLENUM_NUMBER_OF_BITS-1);
        !           314:        }
        !           315: 
1.1       root      316:        /* The rest of the words are just mantissa bits. */
                    317:        for (; lp < words + precision; lp++)
1.1.1.2   root      318:                * lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
1.1       root      319: 
1.1.1.2   root      320:        if (next_bits (1)) {
1.1       root      321:                unsigned long int       carry;
                    322:                        /*
                    323:                         * Since the NEXT bit is a 1, round UP the mantissa.
                    324:                         * The cunning design of these hidden-1 floats permits
                    325:                         * us to let the mantissa overflow into the exponent, and
                    326:                         * it 'does the right thing'. However, we lose if the
                    327:                         * highest-order bit of the lowest-order word flips.
                    328:                         * Is that clear?
                    329:                         */
                    330: 
                    331: 
                    332: /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
                    333:        Please allow at least 1 more bit in carry than is in a LITTLENUM.
                    334:        We need that extra bit to hold a carry during a LITTLENUM carry
                    335:        propagation. Another extra bit (kept 0) will assure us that we
                    336:        don't get a sticky sign bit after shifting right, and that
                    337:        permits us to propagate the carry without any masking of bits.
                    338: #endif */
                    339:                for (carry = 1, lp --; carry && (lp >= words); lp --) {
                    340:                        carry = * lp + carry;
                    341:                        * lp = carry;
                    342:                        carry >>= LITTLENUM_NUMBER_OF_BITS;
                    343:                }
                    344:                if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) {
                    345:                        /* We leave return_value alone: admit we read the
                    346:                         * number, but return a floating exception
                    347:                         * because we can't encode the number.
                    348:                         */
                    349:                        make_invalid_floating_point_number (words);
                    350:                        return return_value;
                    351:                }
                    352:        }
                    353:        return (return_value);
                    354: }
                    355: 
                    356: /* This routine is a real kludge.  Someone really should do it better, but
                    357:    I'm too lazy, and I don't understand this stuff all too well anyway
                    358:    (JF)
                    359:  */
1.1.1.3 ! root      360: void
1.1       root      361: int_to_gen(x)
                    362: long x;
                    363: {
                    364:        char buf[20];
                    365:        char *bufp;
                    366: 
                    367:        sprintf(buf,"%ld",x);
                    368:        bufp= &buf[0];
                    369:        if(atof_generic(&bufp,".", EXP_CHARS, &generic_floating_point_number))
                    370:                as_warn("Error converting number to floating point (Exponent overflow?)");
                    371: }

unix.superglobalmegacorp.com

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