Kernel/armv7 - Moved to asssembly 32-bit divide
[tpg/acess2.git] / Kernel / arch / armv7 / lib.c
index a59c062..a1fbfb7 100644 (file)
@@ -5,6 +5,11 @@
  */
 #include <acess.h>
 
+// === IMPORTS ===
+extern void    __memcpy_align4(void *_dest, const void *_src, size_t _length);
+extern void    __memcpy_byte(void *_dest, const void *_src, size_t _length);
+extern Uint32  __divmod32_asm(Uint32 Num, Uint32 Den, Uint32 *Rem);
+
 // === PROTOTYPES ===
 Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
 Uint32 __divmod32(Uint32 Num, Uint32 Den, Uint32 *Rem);
@@ -18,31 +23,26 @@ Sint32      __modsi3(Sint32 Num, Sint32 Den);
 // === CODE ===
 void *memcpy(void *_dest, const void *_src, size_t _length)
 {
-       Uint32  *dst;
-       const Uint32    *src;
        Uint8   *dst8 = _dest;
        const Uint8     *src8 = _src;
 
+       if( ((tVAddr)_dest & 3) == 0 && ((tVAddr)_src & 3) == 0 )
+       {
+               __memcpy_align4(_dest, _src, _length);
+               return _dest;
+       }
+
        // Handle small copies / Non-aligned
        if( _length < 4 || ((tVAddr)_dest & 3) != ((tVAddr)_src & 3) )
        {
-               for( ; _length--; dst8++,src8++ )
-                       *dst8 = *src8;
+               __memcpy_byte(_dest, _src, _length);
                return _dest;
        }
 
        // Force alignment
-       while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++;
-       dst = (void *)dst8;     src = (void *)src8;
-
-       // DWORD copies
-       for( ; _length > 3; _length -= 4)
-               *dst++ = *src++;
+       while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --;
 
-       // Trailing bytes
-       dst8 = (void*)dst;      src8 = (void*)src;
-       for( ; _length; _length -- )
-               *dst8 ++ = *src8 ++;
+       __memcpy_align4(dst8, src8, _length);
        
        return _dest;
 }
@@ -86,7 +86,7 @@ void *memset(void *_dest, int _value, size_t _length)
 
        _value = (Uint8)_value;
 
-       // Handle small copies / Non-aligned
+       // Handle small copies
        if( _length < 4 )
        {
                for( ; _length--; dst8++ )
@@ -137,6 +137,10 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
 {
        Uint64  ret;
        if(Den == 0)    return 0;       // TODO: #div0
+       if(Num < Den) {
+               if(Rem) *Rem = Num;
+               return 0;
+       }
        if(Num == 0) {
                if(Rem) *Rem = 0;
                return 0;
@@ -161,6 +165,11 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
                if(Rem) *Rem = Num & 0xFFF;
                return Num >> 12;
        }
+       
+       if( !(Den >> 32) && !(Num >> 32) ) {
+               if(Rem) *Rem = 0;       // Clear high bits
+               return __divmod32_asm(Num, Den, (Uint32*)Rem);
+       }
 
        ret = __divmod64(Num, Den, Rem);
        return ret;
@@ -182,13 +191,13 @@ Uint64 __umoddi3(Uint64 Num, Uint64 Den)
 
 Uint32 __udivsi3(Uint32 Num, Uint32 Den)
 {
-       return __divmod32(Num, Den, NULL);
+       return __divmod32_asm(Num, Den, NULL);
 }
 
 Uint32 __umodsi3(Uint32 Num, Uint32 Den)
 {
        Uint32  rem;
-       __divmod32(Num, Den, &rem);
+       __divmod32_asm(Num, Den, &rem);
        return rem;
 }
 

UCC git Repository :: git.ucc.asn.au