X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Farm7%2Flib.c;h=94c1a3af3c6416f84bfadb661eacdeb696af987a;hb=6e41a8a3aa767cd5aeddbad393ce4f637a47a367;hp=6f11f012d6fd3b4f44aa51d9c86211c8a31da6fb;hpb=2337aa1fb9c4289294e1e4f23d0318faac5450ce;p=tpg%2Facess2.git diff --git a/Kernel/arch/arm7/lib.c b/Kernel/arch/arm7/lib.c index 6f11f012..94c1a3af 100644 --- a/Kernel/arch/arm7/lib.c +++ b/Kernel/arch/arm7/lib.c @@ -6,6 +6,7 @@ #include // === PROTOTYPES === +Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem); Uint64 __udivdi3(Uint64 Num, Uint64 Den); Uint64 __umoddi3(Uint64 Num, Uint64 Den); Uint32 __udivsi3(Uint32 Num, Uint32 Den); @@ -112,6 +113,36 @@ void *memset(void *_dest, int _value, size_t _length) return _dest; } +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; @@ -132,6 +163,10 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem) 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; @@ -156,17 +191,23 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem) Den >>= 1; tmp >>= 1; while( } - #else + if(Rem) *Rem = Num; + return ret; + #elif 0 for( ret = 0; Num > Den; ret ++, Num -= Den) ; - #endif if(Rem) *Rem = Num; return ret; + #else + ret = __divmod64(Num, Den, Rem); + return ret; + #endif } // Unsigned Divide 64-bit Integer Uint64 __udivdi3(Uint64 Num, Uint64 Den) { return DivMod64U(Num, Den, NULL); + #if 0 // if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0 if( Den == 16 ) return Num >> 4; if( Den == 256 ) return Num >> 8; @@ -186,11 +227,16 @@ Uint64 __udivdi3(Uint64 Num, Uint64 Den) Uint64 ret = 0; for( ret = 0; Num > Den; ret ++, Num -= Den ); return ret; + #endif } // Unsigned Modulus 64-bit Integer Uint64 __umoddi3(Uint64 Num, Uint64 Den) { + Uint64 ret = 0; + DivMod64U(Num, Den, &ret); + return ret; + #if 0 if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0 if( Num < Den ) return Num; if( Den == 1 ) return 0; @@ -211,6 +257,7 @@ Uint64 __umoddi3(Uint64 Num, Uint64 Den) #endif for( ; Num > Den; Num -= Den ); return Num; + #endif } #define _divide_s_32(Num, Den, rem) __asm__ __volatile__ ( \