/*****************************************************************************/
/* */
/* 64/32 UNSIGNED DIVIDE */
/* 11/14/06 (dkc) */
/* */
/*****************************************************************************/
unsigned int lmbd(unsigned int mode, unsigned int a);
unsigned int carry(unsigned int a, unsigned int b, unsigned int sum);
void quotient(unsigned int *dividend, unsigned int *quotient,
unsigned int divisor) {
unsigned int i;
unsigned int shift,dshift,ashift,d0,d1,div0,div1,c,temp0,temp1,t0,t1;
d0=*dividend;
d1=*(dividend+1);
if ((d0==0)&&(d1<divisor)) {
*quotient=0;
*(quotient+1)=0;
return;
}
dshift=lmbd(1, divisor);
dshift=dshift+32;
ashift=lmbd(1, d0);
if (d0==0)
ashift+=lmbd(1, d1);
shift=dshift-ashift;
if (shift<32) {
div1=divisor<<shift;
if (shift!=0)
div0=divisor>>(32-shift);
else // added to get MSVC to work
div0=0; //
}
else {
if (shift!=32)
div0=divisor<<(shift-32);
else // added to get MSVC to work
div0=divisor;
div1=0;
}
t0=~div0;
t1=~div1;
temp1=t1+1;
c=carry(t1,1,temp1);
t1=temp1;
t0=t0+c;
shift+=1;
for (i=0; i<shift; i++) {
temp1=d1+t1;
c=carry(d1,t1,temp1);
temp0=d0+t0+c;
if ((temp0>>31)==0) {
d0=temp0<<1;
if ((temp1>>31)!=0)
c=1;
else
c=0;
d0=d0+c;
d1=temp1<<1;
d1=d1+1;
}
else {
d0=d0<<1;
if ((d1>>31)!=0)
c=1;
else
c=0;
d0=d0+c;
d1=d1<<1;
}
}
if (shift>32) {
d0=d0<<(64-shift);
d0=d0>>(64-shift);
}
else {
d0=0;
if (shift!=32) { // added to get MSVC to work
d1=d1<<(32-shift);
d1=d1>>(32-shift);
}
}
*quotient=d0;
*(quotient+1)=d1;
return;
}