|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.