static char *sccsid
= "@(#)divbig.c 34.1 10/3/80";
#define toint(p) ((int) (p))
divbig(dividend
, divisor
, quotient
, remainder
)
lispval dividend
, divisor
, *quotient
, *remainder
;
int *sp(), *alloca(), d
, negflag
= 0, m
, n
, carry
, rem
, qhat
, j
;
int *utop
= sp(), *ubot
, *vbot
, *qbot
;
register lispval work
; lispval
export();
for(work
= dividend
; work
; work
= work
->s
.CDR
)
if(*ubot
< 0) { /* knuth's division alg works only for pos
for(work
= divisor
; work
; work
= work
->s
.CDR
)
/* check validity of data */
/* do destructive division by a single. */
rem
= dsdiv(utop
-1,ubot
,*vbot
);
*remainder
= inewint(rem
);
*quotient
= export(utop
,ubot
);
qbot
= alloca(toint(utop
) + toint(vbot
) - 2 * toint(ubot
));
d2
: for(j
=0,ujp
=ubot
; j
<= m
; j
++,ujp
++) {
qhat
= calqhat(ujp
,vbot
);
if((borrow
= mlsb(ujp
+ n
, ujp
, ubot
, -qhat
)) < 0) {
adback(ujp
+ n
, ujp
, ubot
);
dsdiv(utop
, utop
- n
, d
);
if(negrem
) dsmult(utop
-1,utop
-n
,-1);
*remainder
= export(utop
,utop
-n
);
*quotient
= export(qbot
+ m
+ 1, qbot
);
* asm code commented out due to optimizer bug
asm(" movl $0x3fffffff,r0");
asm(" cmpl (r10),(r11)");
asm(" emul (r11),$0x40000000,4(r11),r1");
asm(" ediv (r10),r1,r0,r5");
asm(" emul r0,4(r10),$0,r1");
asm(" emul r5,$0x40000000,8(r11),r3");
mlsb(utop,ubot,vtop,nqhat)
register int *utop, *ubot, *vtop;
asm("loop2: addl2 (r11),r0");
asm(" emul r8,-(r9),r0,r2");
asm(" extzv $0,$30,r2,(r11)");
asm(" extv $30,$32,r2,r0");
asm(" acbl r10,$-4,r11,loop2");
register int *utop, *ubot, *vtop;
asm("loop3: addl2 -(r9),r0");
asm(" extzv $0,$30,r0,(r11)");
asm(" extv $30,$2,r0,r0");
asm(" acbl r10,$-4,r11,loop3");
asm("loop4: emul r0,$0x40000000,(r11),r1");
asm(" ediv 12(ap),r1,(r11),r0");
asm(" acbl 4(ap),$4,r11,loop4");
asm("loop5: emul 12(ap),(r11),r0,r1");
asm(" extzv $0,$30,r1,(r11)");
asm(" extv $30,$32,r1,r0");
asm(" acbl 8(ap),$-4,r11,loop5");
register r10, r9, r8, r7, r6;
asm(" movl $0xC0000000,r4");
#define MAXINT 0x8000000L
for(count
= 0; fix
; count
++)
register struct argent
*lbot
, *np
;
for(count
= 0; handy
->s
.CDR
!=((lispval
) 0); handy
= handy
->s
.CDR
)
count
+= Ihau(handy
->s
.I
);
handy
= errorh(Vermisc
,"Haulong: bad argument",nil
,
register int *top
= sp() - 1;
register struct argent
*lbot
, *np
;
/* copy data onto stack */
for(; work
!=((lispval
) 0); work
= work
->s
.CDR
)
work
= errorh(Vermisc
,"Haipart: bad first argument",nil
,
for(; *bot
==0 && bot
< top
; bot
++);
/* recalculate haulong internally */
mylen
= (top
- bot
) * 30 + Ihau(*bot
);
/* get second argument */
work
= errorh(Vermisc
,"Haipart: 2nd arg not int",nil
,
if(n
>= mylen
|| -n
>= mylen
)
if(n
==0) return(inewint(0));
/* Here we want n most significant bits
so chop off mylen - n bits */
error("Internal error in haipart #1",FALSE
);
/* here we want abs(n) low order bits */
return(export(top
+ 1,bot
));