Annotation of 43BSD/bin/as/bignum1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)bignum1.c  5.1 (Berkeley) 4/30/85";
                      9: #endif not lint
                     10: 
                     11: #include <errno.h>
                     12: #include <stdio.h>
                     13: #include "as.h"
                     14: 
                     15: /*
                     16:  *     Construct a floating point number
                     17:  */
                     18: Bignum as_atof(numbuf, radix, ovfp)
                     19:        char    *numbuf;
                     20:        int     radix;
                     21:        Ovf     *ovfp;
                     22: {
                     23:        Bignum  number;
                     24:        extern  int     errno;
                     25:        double  atof();
                     26: 
                     27:        number = Znumber;
                     28:        errno = 0;
                     29:        switch(radix){
                     30:        case TYPF:
                     31:        case TYPD:
                     32:                number.num_tag = TYPD;
                     33:                *ovfp = 0;
                     34:                number.num_num.numFd_float.Fd_value = atof(numbuf);
                     35:                break;
                     36:        case TYPG:
                     37:        case TYPH:
                     38:                number = bigatof(numbuf, radix);
                     39:                break;
                     40:        }
                     41:        if (errno == ERANGE && passno == 2){
                     42:                yywarning("Floating conversion over/underflowed\n");
                     43:        }
                     44:        return(number);
                     45: }
                     46: 
                     47: /*
                     48:  *     Construct an integer.
                     49:  */
                     50: 
                     51: Bignum as_atoi(ccp, radix, ovfp)
                     52:        reg     char    *ccp;           /* character cp */
                     53:                int     radix;
                     54:                Ovf     *ovfp;
                     55: {
                     56:        reg     chptr   bcp;
                     57:                chptr   tcp;
                     58:        reg     int     i;
                     59:                int     val;
                     60:                Bignum  n_n;
                     61:                Bignum  t_n;
                     62:                int     sign;
                     63:                Ovf     ovf;
                     64: 
                     65:        ovf = 0;
                     66:        sign = 0;
                     67:        for (; *ccp; ccp++){
                     68:                switch(*ccp){
                     69:                case '0':
                     70:                case '+':       continue;
                     71:                case '-':       sign ^= 1;
                     72:                                continue;
                     73:                }
                     74:                break;
                     75:        }
                     76: 
                     77:        n_n = Znumber;
                     78:        t_n = Znumber;
                     79:        bcp = CH_FIELD(n_n); (void)numclear(bcp);
                     80:        tcp = CH_FIELD(t_n); (void)numclear(tcp);
                     81:        for (; *ccp; ccp++){
                     82:                switch(*ccp){
                     83:                case '8': case '9':
                     84:                        if (radix < 10)
                     85:                                goto done;
                     86:                        /*FALLTHROUGH*/
                     87:                case '0': case '1': case '2': case '3': case '4':
                     88:                case '5': case '6': case '7':
                     89:                        val = *ccp - '0';
                     90:                        break;
                     91:                case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
                     92:                        if (radix < 16)
                     93:                                goto done;
                     94:                        val = *ccp - 'A' + 10;
                     95:                        break;
                     96:                case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                     97:                        if (radix < 16)
                     98:                                goto done;
                     99:                        val = *ccp - 'a' + 10;
                    100:                        break;
                    101:                default:
                    102:                        goto done;
                    103:                }
                    104:                switch(radix){
                    105:                case 8:
                    106:                        ovf |= numshift(3, bcp, bcp);
                    107:                        break;
                    108:                case 16:
                    109:                        ovf |= numshift(4, bcp, bcp);
                    110:                        break;
                    111:                case 10:
                    112:                        ovf |= numshift(1, tcp, bcp);
                    113:                        ovf |= numshift(3, bcp, bcp);
                    114:                        ovf |= numaddv(bcp, tcp, bcp);
                    115:                        break;
                    116:                }
                    117:                ovf |= numaddd(bcp, bcp, val);
                    118:        }
                    119:   done: ;
                    120:        ovf |= posovf(bcp);
                    121:        if (sign){
                    122:                if (ovf & OVF_MAXINT) {
                    123:                        ovf &= ~(OVF_MAXINT | OVF_POSOVF);
                    124:                } else {
                    125:                        ovf |= numnegate(bcp, bcp);
                    126:                }
                    127:        }
                    128:        /*
                    129:         *      find the highest set unit of the number
                    130:         */
                    131:        val = sign ? -1 : 0;
                    132:        for (i = 0; i < CH_N; i++){
                    133:                if (bcp[i] == val)
                    134:                        break;
                    135:        }
                    136:        {
                    137:                static u_char tagtab[4][16] = {
                    138:                {       TYPB,
                    139:                        TYPW,
                    140:                        TYPL, TYPL,
                    141:                        TYPQ, TYPQ, TYPQ, TYPQ,
                    142:                        TYPO, TYPO, TYPO, TYPO, TYPO, TYPO, TYPO, TYPO},
                    143:                {       TYPW,
                    144:                        TYPL,
                    145:                        TYPQ, TYPQ,
                    146:                        TYPO, TYPO, TYPO, TYPO},
                    147:                {   0   },
                    148:                {       TYPL,
                    149:                        TYPQ,
                    150:                        TYPO, TYPO }
                    151:                };
                    152:                /*
                    153:                 *      i indexes to the null chunk; make it point to the
                    154:                 *      last non null chunk
                    155:                 */
                    156:                i -= 1;
                    157:                if (i < 0)
                    158:                        i = 0;
                    159:                n_n.num_tag = tagtab[HOC][i];
                    160:                assert(n_n.num_tag != 0, "Botch width computation");
                    161:        }
                    162:        *ovfp = ovf;
                    163:        return(n_n);
                    164: }
                    165: 
                    166: Ovf posovf(src)
                    167:        reg     chptr   src;
                    168: {
                    169:        reg     int     i;
                    170:        Ovf     overflow = 0;
                    171: 
                    172:        if (src[HOC] & SIGNBIT)
                    173:                overflow = OVF_POSOVF;
                    174:        if (src[HOC] == SIGNBIT){
                    175:                for (i = HOC - 1; i >= 0; --i){
                    176:                        if (src[i] != 0)
                    177:                                return(overflow);
                    178:                }
                    179:                overflow |= OVF_MAXINT;
                    180:        }
                    181:        return(overflow);
                    182: }
                    183: 
                    184: /*
                    185:  *     check if the number is clear
                    186:  */
                    187: int isclear(dst)
                    188:        reg     chptr   dst;
                    189: {
                    190:        return(!isunequal(dst, CH_FIELD(Znumber)));
                    191: }
                    192: 
                    193: int isunequal(src1, src2)
                    194:        reg     chptr   src1, src2;
                    195: {
                    196:        reg     int     i;
                    197: 
                    198:        i = CH_N;
                    199:        do{
                    200:                if (*src1++ != *src2++)
                    201:                        return(i);
                    202:        }while(--i);
                    203:        return(0);
                    204: }
                    205: 
                    206: Ovf numclear(dst)
                    207:        reg     chptr   dst;
                    208: {
                    209:        reg     int     i;
                    210:        i = CH_N;
                    211:        do{
                    212:                *dst++ = 0;
                    213:        }while(--i);
                    214:        return(0);
                    215: }
                    216: 
                    217: Ovf numshift(n, dst, src)
                    218:                int     n;
                    219:        reg     chptr   dst, src;
                    220: {
                    221:        reg     int     i;
                    222:        reg     u_int   carryi, carryo;
                    223:        reg     u_int   mask;
                    224:        reg     u_int   value;
                    225: 
                    226:        i = CH_N;
                    227:        if (n == 0){
                    228:                do{
                    229:                        *dst++ = *src++;
                    230:                } while(--i);
                    231:                return(0);
                    232:        }
                    233: 
                    234:        carryi = 0;
                    235:        mask = ONES(n);
                    236: 
                    237:        if (n > 0){
                    238:                do{
                    239:                        value = *src++;
                    240:                        carryo = (value >> (CH_BITS - n)) & mask; 
                    241:                        value <<= n;
                    242:                        value &= ~mask;
                    243:                        *dst++ = value | carryi;
                    244:                        carryi = carryo;
                    245:                } while (--i);
                    246:                return(carryi ? OVF_LSHIFT : 0);
                    247:        } else {
                    248:                n = -n;
                    249:                src += CH_N;
                    250:                dst += CH_N;
                    251:                do{
                    252:                        value = *--src;
                    253:                        carryo = value & mask; 
                    254:                        value >>= n;
                    255:                        value &= ONES(CH_BITS - n);
                    256:                        *--dst = value | carryi;
                    257:                        carryi = carryo << (CH_BITS - n);
                    258:                } while (--i);
                    259:                return(carryi ? OVF_LSHIFT : 0);
                    260:        }
                    261: }
                    262: 
                    263: Ovf numaddd(dst, src1, val)
                    264:        chptr   dst, src1;
                    265:        int     val;
                    266: {
                    267:        static  Bignum  work;
                    268: 
                    269:        work.num_uchar[0] = val;
                    270:        return (numaddv(dst, src1, CH_FIELD(work)));
                    271: }
                    272: 
                    273: Ovf numaddv(dst, src1, src2)
                    274:        reg     chptr   dst, src1, src2;
                    275: {
                    276:        reg     int     i;
                    277:        reg     int     carry;
                    278:        reg     u_int   A,B,value;
                    279: 
                    280:        carry = 0;
                    281:        i = CH_N;
                    282:        do{
                    283:                A = *src1++;
                    284:                B = *src2++;
                    285:                value = A + B + carry;
                    286:                *dst++ = value;
                    287:                carry = 0;
                    288:                if (value < A || value < B)
                    289:                        carry = 1;
                    290:        } while (--i);
                    291:        return(carry ? OVF_ADDV : 0);
                    292: }
                    293: 
                    294: Ovf numnegate(dst, src)
                    295:        chptr   dst, src;
                    296: {
                    297:        Ovf     ovf;
                    298: 
                    299:        ovf = num1comp(dst, src) ;
                    300:        ovf |= numaddd(dst, dst, 1);
                    301:        return(ovf);
                    302: }
                    303: 
                    304: Ovf num1comp(dst, src)
                    305:        reg     chptr   dst, src;
                    306: {
                    307:        reg     int     i;
                    308:        i = CH_N;
                    309:        do{
                    310:                *dst++ = ~ *src++;
                    311:        }while (--i);
                    312:        return(0);
                    313: }
                    314: 
                    315: /*
                    316:  *     Determine if floating point numbers are
                    317:  *     capable of being represented as a one byte immediate literal constant
                    318:  *     If it is, then stuff the value into *valuep.
                    319:  *     argtype is how the instruction will interpret the number.
                    320:  */
                    321: int slitflt(number, argtype, valuep)
                    322:        Bignum  number;         /* number presented */
                    323:        int     argtype;        /* what the instruction expects */
                    324:        int     *valuep;
                    325: {
                    326: #define        EXPPREC 3
                    327: #define        MANTPREC 3
                    328: 
                    329:                int     mask;
                    330:        reg     int     i;
                    331:                Bignum  unpacked;
                    332:                Ovf     ovf;
                    333: 
                    334:        *valuep = 0;
                    335:        if (!ty_float[argtype])
                    336:                return(0);
                    337:        unpacked = bignumunpack(number, &ovf);
                    338:        assert(ovf == 0, "overflow in unpacking floating #!?");
                    339:        if (unpacked.num_sign)
                    340:                return(0);
                    341:        if (unpacked.num_exponent < 0)
                    342:                return(0);
                    343:        if (unpacked.num_exponent > ONES(EXPPREC))
                    344:                return(0);
                    345:        for (i = 0; i < HOC; i++){
                    346:                if (CH_FIELD(unpacked)[i])
                    347:                        return(0);
                    348:        }
                    349:        if ((CH_FIELD(unpacked)[HOC]) & ONES(CH_BITS - MANTPREC))
                    350:                return(0);
                    351:        *valuep = (unpacked.num_exponent & ONES(EXPPREC)) << MANTPREC;
                    352:        mask = (CH_FIELD(unpacked)[HOC]) >> (CH_BITS - MANTPREC);
                    353:        mask &= ONES(MANTPREC);
                    354:        *valuep |= mask;
                    355:        *valuep &= ONES(MANTPREC + EXPPREC);
                    356:        return(1);
                    357: }
                    358: 
                    359: #ifndef STANDALONE
                    360: /*
                    361:  *     Output a big number to txtfil
                    362:  *     Called only when passno == 2
                    363:  *
                    364:  *     The conversion specifies the width of the number to be written out.
                    365:  *     The width is supplied from either an initialized data directive
                    366:  *     (for example .float, .double), or from the operand size
                    367:  *     defined by an operator.
                    368:  *     If the number is of type quad or octal,
                    369:  *     we just write it out; this allows one to specify bit
                    370:  *     patterns for floating point numbers.
                    371:  *     If the number is one of the floating types and the conversion
                    372:  *     is not the same type, then we complain, but do the conversion anyway.
                    373:  *     The conversion is strict.
                    374:  */
                    375: bignumwrite(number, toconv)
                    376:        Bignum  number;
                    377:        int     toconv;         /* one of TYP[QO FDGH] */
                    378: {
                    379:        reg     u_int   *bp;
                    380: 
                    381:        if (passno != 2)
                    382:                return;
                    383: 
                    384:        bp = &number.num_uint[0];
                    385:        switch(number.num_tag){
                    386:        case TYPB:
                    387:        case TYPW:
                    388:        case TYPL:
                    389:        case TYPQ:
                    390:        case TYPO:
                    391:                number = intconvert(number, toconv);
                    392:                break;
                    393:        default:
                    394:                number = floatconvert(number, toconv);
                    395:                break;
                    396:        }
                    397:        bwrite((char *)bp, ty_nbyte[toconv], txtfil);
                    398: }
                    399: #endif STANDALONE

unix.superglobalmegacorp.com

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