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