Annotation of 42BSD/bin/as/bignum1.c, revision 1.1

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

unix.superglobalmegacorp.com

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