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