/*****************************************************************************/
/* */
/* 128/64 BIT DIVIDE (UNSIGNED) */
/* 01/12/07 (dkc) */
/* */
/*****************************************************************************/
unsigned int carry(unsigned int a, unsigned int b, unsigned int sum);
unsigned int lmbd(unsigned int mode, unsigned int a);
void div128_64(unsigned int a0, unsigned int a1, unsigned int a2,
unsigned int a3, unsigned int *quotient, unsigned int d2,
unsigned int d3) {
unsigned int i,d0,d1,dshift,ashift,count,flag;
unsigned int shift,c,c0,c1,c2,temp,temp0,temp1,temp2,temp3;
if (d2==0) {
if ((a0==0)&&(a1==0)&&(a2==0)&&(a3<d3)) {
*quotient=0;
*(quotient+1)=0;
*(quotient+2)=0;
*(quotient+3)=0;
return;
}
}
else {
if ((a0==0)&&(a1==0)&&(a2<d2)) {
*quotient=0;
*(quotient+1)=0;
*(quotient+2)=0;
*(quotient+3)=0;
return;
}
}
dshift=lmbd(1,d2);
if (d2==0)
dshift+=lmbd(1,d3);
dshift+=64;
ashift=lmbd(1,a0);
if (a0==0)
ashift+=lmbd(1,a1);
if ((a0|a1)==0)
ashift+=lmbd(1,a2);
if ((a0|a1|a2)==0)
ashift+=lmbd(1,a3);
shift=dshift-ashift;
count=shift+1;
d0=0;
d1=0;
if (shift<32) {
if (shift!=0) {
d1=d2>>(32-shift);
d2=(d2<<shift)|(d3>>(32-shift));
}
else
d1=0; // added to get MSVC to work
d3=d3<<shift;
flag=3;
shift=32-shift;
}
else {
shift=shift-32;
d1=d2;
d2=d3;
d3=0;
if (shift<32) {
if (shift!=0) {
d0=d1>>(32-shift);
d1=(d1<<shift)|(d2>>(32-shift));
}
else
d0=0; // added to get MSVC to work
d2=d2<<shift;
flag=2;
shift=32-shift;
}
else {
shift=shift-32;
d0=d1;
d1=d2;
d2=0;
if (shift<32) {
if (shift!=0) // added to get MSVC to work
d0=(d0<<shift)|(d1>>(32-shift));
d1=d1<<shift;
flag=1;
shift=32-shift;
}
else {
shift=shift-32;
d0=d1;
d1=0;
d0=d0<<shift;
flag=0;
shift=32-shift;
}
}
}
d0=~d0;
d1=~d1;
d2=~d2;
d3=~d3;
temp=d3+1;
c=carry(d3,1,temp);
d3=temp;
temp=d2+c;
c=carry(d2,c,temp);
d2=temp;
temp=d1+c;
c=carry(d1,c,temp);
d1=temp;
d0=d0+c;
for (i=0; i<count; i++) {
temp3=a3+d3;
c2=carry(a3,d3,temp3);
temp=a2+c2;
c1=carry(a2,c2,temp);
temp2=temp+d2;
c1+=carry(temp,d2,temp2);
temp=a1+c1;
c0=carry(a1,c1,temp);
temp1=temp+d1;
c0+=carry(temp,d1,temp1);
temp0=a0+d0+c0;
if ((temp0>>31)==0) {
a0=temp0<<1;
if ((temp1>>31)!=0)
c=1;
else
c=0;
a0=a0+c;
a1=temp1<<1;
if ((temp2>>31)!=0)
c=1;
else
c=0;
a1=a1+c;
a2=temp2<<1;
if ((temp3>>31)!=0)
c=1;
else
c=0;
a2=a2+c;
a3=temp3<<1;
a3=a3+1;
}
else {
a0=a0<<1;
if ((a1>>31)!=0)
c=1;
else
c=0;
a0=a0+c;
a1=a1<<1;
if ((a2>>31)!=0)
c=1;
else
c=0;
a1=a1+c;
a2=a2<<1;
if ((a3>>31)!=0)
c=1;
else
c=0;
a2=a2+c;
a3=a3<<1;
}
}
shift=shift-1;
if (flag==3) {
a0=0;
a1=0;
a2=0;
a3=a3<<shift;
a3=a3>>shift;
}
else {
if (flag==2) {
a0=0;
a1=0;
a2=a2<<shift;
a2=a2>>shift;
}
else {
if (flag==1) {
a0=0;
a1=a1<<shift;
a1=a1>>shift;
}
else {
a0=a0<<shift;
a0=a0>>shift;
}
}
}
*quotient=a0;
*(quotient+1)=a1;
*(quotient+2)=a2;
*(quotient+3)=a3;
return;
}