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

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

unix.superglobalmegacorp.com

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