Annotation of 43BSD/bin/as/bignum1.c, revision 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.