+Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem)
+{
+ Uint64 ret, add;
+
+ ret = 0;
+ add = 1;
+
+ // Find what power of two times Den is > Num
+ while( Num >= Den )
+ {
+ Den <<= 1;
+ add <<= 1;
+ }
+
+ // Search backwards
+ while( add > 1 )
+ {
+ add >>= 1;
+ Den >>= 1;
+ // If the numerator is > Den, subtract and add to return value
+ if( Num > Den )
+ {
+ ret += add;
+ Num -= Den;
+ }
+ }
+ if(Rem) *Rem = Num;
+ return ret;
+}
+
+Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
+{
+ Uint64 ret;
+ if(Den == 0) return 0; // TODO: #div0
+ if(Num == 0) {
+ if(Rem) *Rem = 0;
+ return 0;
+ }
+ if(Den == 1) {
+ if(Rem) *Rem = 0;
+ return Num;
+ }
+ if(Den == 2) {
+ if(Rem) *Rem = Num & 1;
+ return Num >> 1;
+ }
+ if(Den == 16) {
+ if(Rem) *Rem = Num & 0xF;
+ return Num >> 4;
+ }
+ if(Den == 32) {
+ if(Rem) *Rem = Num & 0x1F;
+ return Num >> 5;
+ }
+ if(Den == 0x1000) {
+ if(Rem) *Rem = Num & 0xFFF;
+ return Num >> 12;
+ }
+
+ #if 0
+ {
+ // http://www.tofla.iconbar.com/tofla/arm/arm02/index.htm
+ Uint64 tmp = 1;
+ __asm__ __volatile__(
+ "1:"
+ "cmpl %2,%1"
+ "movls %2,%2,lsl#1"
+ "movls %3,%3,lsl#1"
+ "bls 1b"
+ "2:"
+ "cmpl %"
+ while(Num > Den) {
+ Den <<= 1;
+ tmp <<= 1;
+ }
+ Den >>= 1; tmp >>= 1;
+ while(
+ }
+ if(Rem) *Rem = Num;
+ return ret;
+ #elif 0
+ for( ret = 0; Num > Den; ret ++, Num -= Den) ;
+ if(Rem) *Rem = Num;
+ return ret;
+ #else
+ ret = __divmod64(Num, Den, Rem);
+ return ret;
+ #endif
+}
+