Annotation of 41BSD/cmd/lisp/divbig.c, revision 1.1.1.1

1.1       root        1: 
                      2: static char *sccsid = "@(#)divbig.c    34.1 10/3/80";
                      3: 
                      4: #include "global.h"
                      5: 
                      6: #define b 0x40000000
                      7: #define toint(p) ((int) (p))
                      8: 
                      9: divbig(dividend, divisor, quotient, remainder)
                     10: lispval dividend, divisor, *quotient, *remainder;
                     11: {
                     12:        register *ujp, *vip;
                     13:        int *sp(), *alloca(), d, negflag = 0, m, n, carry, rem, qhat, j;
                     14:        int borrow, negrem = 0;
                     15:        int *utop = sp(), *ubot, *vbot, *qbot;
                     16:        register lispval work; lispval export();
                     17:        snpand(3);
                     18: 
                     19:        /* copy dividend */
                     20:        for(work = dividend; work; work = work ->s.CDR)
                     21:                stack(work->s.I);
                     22:        ubot = sp();
                     23:        if(*ubot < 0) {         /* knuth's division alg works only for pos
                     24:                                        bignums                         */
                     25:                negflag ^= 1;
                     26:                negrem = 1;
                     27:                dsmult(utop-1,ubot,-1);
                     28:        }
                     29:        stack(0);
                     30:        ubot = sp();
                     31: 
                     32:        
                     33:        /*copy divisor */
                     34:        for(work = divisor; work; work = work->s.CDR)
                     35:                stack(work->s.I);
                     36: 
                     37:        vbot = sp();
                     38:        stack(0);
                     39:        if(*vbot < 0) {
                     40:                negflag ^= 1;
                     41:                dsmult(ubot-1,vbot,-1);
                     42:        }
                     43: 
                     44:        /* check validity of data */
                     45:        n = ubot - vbot;
                     46:        m = utop - ubot - n - 1;
                     47:        if (n == 1) {
                     48:                /* do destructive division by  a single. */
                     49:                rem = dsdiv(utop-1,ubot,*vbot);
                     50:                if(negrem)
                     51:                        rem = -rem;
                     52:                if(negflag)
                     53:                        dsmult(utop-1,ubot,-1);
                     54:                if(remainder)
                     55:                        *remainder = inewint(rem);
                     56:                if(quotient)
                     57:                        *quotient = export(utop,ubot);
                     58:                return;
                     59:        }
                     60:        if (m < 0) {
                     61:                if (remainder)
                     62:                        *remainder = dividend;
                     63:                if(quotient)
                     64:                        *quotient = inewint(0);
                     65:                return;
                     66:        }
                     67:        qbot = alloca(toint(utop) + toint(vbot) - 2 * toint(ubot));
                     68: d1:
                     69:        d = b /(*vbot +1);
                     70:        dsmult(utop-1,ubot,d);
                     71:        dsmult(ubot-1,vbot,d);
                     72: 
                     73: d2:    for(j=0,ujp=ubot; j <= m; j++,ujp++) {
                     74: 
                     75:        d3:     
                     76:                qhat = calqhat(ujp,vbot);
                     77:        d4:
                     78:                if((borrow = mlsb(ujp + n, ujp, ubot, -qhat)) < 0) {
                     79:                        adback(ujp + n, ujp, ubot);
                     80:                        qhat--;
                     81:                }
                     82:                qbot[j] = qhat;
                     83:        }
                     84: d8:    if(remainder) {
                     85:                dsdiv(utop, utop - n, d);
                     86:                if(negrem) dsmult(utop-1,utop-n,-1);
                     87:                *remainder = export(utop,utop-n);
                     88:        }
                     89:        if(quotient) {
                     90:                if(negflag)
                     91:                        dsmult(qbot+m,qbot,-1);
                     92:                *quotient = export(qbot + m + 1, qbot);
                     93:        }
                     94: }
                     95: /*
                     96:  * asm code commented out due to optimizer bug
                     97: calqhat(ujp,v1p)
                     98: register int *ujp, *v1p;
                     99: {
                    100: asm("  movl    $0x3fffffff,r0");
                    101: asm("  cmpl    (r10),(r11)");
                    102: asm("  beql    on1");
                    103: asm("  emul    (r11),$0x40000000,4(r11),r1");
                    104: asm("  ediv    (r10),r1,r0,r5");
                    105: asm("on1:");
                    106: asm("  emul    r0,4(r10),$0,r1");
                    107: asm("  emul    r5,$0x40000000,8(r11),r3");
                    108: asm("  subl2   r3,r1");
                    109: asm("  sbwc    r4,r2");
                    110: asm("  bleq    out1");
                    111: asm("  decl    r0");
                    112: asm("out1:");
                    113: }
                    114: mlsb(utop,ubot,vtop,nqhat)
                    115: register int *utop, *ubot, *vtop;
                    116: register int nqhat;
                    117: {
                    118: asm("  clrl    r0");
                    119: asm("loop2:    addl2   (r11),r0");
                    120: asm("  emul    r8,-(r9),r0,r2");
                    121: asm("  extzv   $0,$30,r2,(r11)");
                    122: asm("  extv    $30,$32,r2,r0");
                    123: asm("  acbl    r10,$-4,r11,loop2");
                    124: }
                    125: adback(utop,ubot,vtop)
                    126: register int *utop, *ubot, *vtop;
                    127: {
                    128: asm("  clrl    r0");
                    129: asm("loop3:    addl2   -(r9),r0");
                    130: asm("  addl2   (r11),r0");
                    131: asm("  extzv   $0,$30,r0,(r11)");
                    132: asm("  extv    $30,$2,r0,r0");
                    133: asm("  acbl    r10,$-4,r11,loop3");
                    134: }
                    135: dsdiv(top,bot,div)
                    136: register int* bot;
                    137: {
                    138: asm("  clrl    r0");
                    139: asm("loop4:    emul    r0,$0x40000000,(r11),r1");
                    140: asm("  ediv    12(ap),r1,(r11),r0");
                    141: asm("  acbl    4(ap),$4,r11,loop4");
                    142: }
                    143: dsmult(top,bot,mult)
                    144: register int* top;
                    145: {
                    146: asm("  clrl    r0");
                    147: asm("loop5:    emul    12(ap),(r11),r0,r1");
                    148: asm("  extzv   $0,$30,r1,(r11)");
                    149: asm("  extv    $30,$32,r1,r0");
                    150: asm("  acbl    8(ap),$-4,r11,loop5");
                    151: asm("  movl    r1,4(r11)");
                    152: }
                    153: lispval export(top,bot)
                    154: register lispval bot;
                    155: {
                    156:        register r10, r9, r8, r7, r6;
                    157: asm("  movl    4(ap),r10");
                    158: asm("  movl    $0xC0000000,r4");
                    159: asm("  jmp     Bexport");
                    160: }
                    161: */
                    162: 
                    163: #define MAXINT 0x8000000L
                    164: 
                    165: Ihau(fix)
                    166: register int fix;
                    167: {
                    168:        register count;
                    169:        if(fix==MAXINT)
                    170:                return(32);
                    171:        if(fix < 0)
                    172:                fix = -fix;
                    173:        for(count = 0; fix; count++)
                    174:                fix /= 2;
                    175:        return(count);
                    176: }
                    177: lispval
                    178: Lhau()
                    179: {
                    180:        register count;
                    181:        register lispval handy;
                    182:        register dum1,dum2;
                    183:        register struct argent *lbot, *np;
                    184:        lispval Labsval();
                    185: 
                    186:        handy = lbot->val;
                    187: top:
                    188:        switch(TYPE(handy)) {
                    189:        case INT:
                    190:                count = Ihau(handy->i);
                    191:                break;
                    192:        case SDOT:
                    193:                lbot->val = Labsval();
                    194:                for(count = 0; handy->s.CDR!=((lispval) 0); handy = handy->s.CDR)
                    195:                        count += 30;
                    196:                count += Ihau(handy->s.I);
                    197:                break;
                    198:        default:
                    199:                handy = errorh(Vermisc,"Haulong: bad argument",nil,
                    200:                               TRUE,997,handy);
                    201:                goto top;
                    202:        }
                    203:        return(inewint(count));
                    204: }
                    205: lispval
                    206: Lhaipar()
                    207: {
                    208:        int *sp();
                    209:        register lispval work;
                    210:        register n;
                    211:        register int *top = sp() - 1;
                    212:        register int *bot;
                    213:        register struct argent *lbot, *np;
                    214:        int mylen;
                    215: 
                    216:        /*chkarg(2);*/
                    217:        work = lbot->val;
                    218:                                        /* copy data onto stack */
                    219: on1:
                    220:        switch(TYPE(work)) {
                    221:        case INT:
                    222:                stack(work->i);
                    223:                break;
                    224:        case SDOT:
                    225:                for(; work!=((lispval) 0); work = work->s.CDR)
                    226:                        stack(work->s.I);
                    227:                break;
                    228:        default:
                    229:                work = errorh(Vermisc,"Haipart: bad first argument",nil,
                    230:                                TRUE,996,work);
                    231:                goto on1;
                    232:        }
                    233:        bot = sp();
                    234:        if(*bot < 0) {
                    235:                stack(0);
                    236:                dsmult(top,bot,-1);
                    237:                bot--;
                    238:        }
                    239:        for(; *bot==0 && bot < top; bot++);
                    240:                                /* recalculate haulong internally */
                    241:        mylen = (top - bot) * 30 + Ihau(*bot);
                    242:                                /* get second argument            */
                    243:        work = lbot[1].val;
                    244:        while(TYPE(work)!=INT)
                    245:                work = errorh(Vermisc,"Haipart: 2nd arg not int",nil,
                    246:                                TRUE,995,work);
                    247:        n = work->i;
                    248:        if(n >= mylen || -n >= mylen)
                    249:                goto done;
                    250:        if(n==0) return(inewint(0));
                    251:        if(n > 0) {
                    252:                                /* Here we want n most significant bits
                    253:                                   so chop off mylen - n bits */
                    254:                stack(0);
                    255:                n = mylen - n;
                    256:                for(n; n >= 30; n -= 30)
                    257:                        top--;
                    258:                if(top < bot)
                    259:                        error("Internal error in haipart #1",FALSE);
                    260:                dsdiv(top,bot,1<<n);
                    261: 
                    262:        } else {
                    263:                                /* here we want abs(n) low order bits */
                    264:                stack(0);
                    265:                bot = top + 1;
                    266:                for(; n <= 0; n += 30)
                    267:                        bot--;
                    268:                n = 30 - n;
                    269:                *bot &= ~ (-1<<n);
                    270:        }
                    271: done:
                    272:        return(export(top + 1,bot));
                    273: }

unix.superglobalmegacorp.com

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