/*****************************************************************************/ /* */ /* 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; }