X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Farmv7%2Flib.c;h=a1fbfb77cc4b906af07a18807bd33029200c4c3b;hb=95a9132bcc024715a0a87cb323d58967ea5b1803;hp=a44489aff2c82d415fd56d99f674bb9b2f5068d8;hpb=e31829ecc2b8ae2338745f4ed393748704a81531;p=tpg%2Facess2.git diff --git a/Kernel/arch/armv7/lib.c b/Kernel/arch/armv7/lib.c index a44489af..a1fbfb77 100644 --- a/Kernel/arch/armv7/lib.c +++ b/Kernel/arch/armv7/lib.c @@ -5,6 +5,11 @@ */ #include +// === 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; + while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --; - // DWORD copies - for( ; _length > 3; _length -= 4) - *dst++ = *src++; - - // 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; @@ -180,50 +189,44 @@ Uint64 __umoddi3(Uint64 Num, Uint64 Den) return ret; } -#define _divide_s_32(Num, Den, rem) __asm__ __volatile__ ( \ - "mov %0, #0\n" \ - " adds %1, %1, %1\n" \ - " .rept 32\n" \ - " adcs %0, %2, %0, lsl #1\n" \ - " subcc %0, %0, %3\n" \ - " adcs %1, %1, %1\n" \ - " .endr\n" \ - : "=r" (rem), "=r" (Num) \ - : "r" (Den) \ - : "cc" \ - ) 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; } -Sint32 __divsi3(Sint32 Num, Sint32 Den) +static inline Sint32 DivMod32S(Sint32 Num, Sint32 Den, Sint32 *Rem) { - if( (Num < 0) && (Den < 0) ) - return __udivsi3(-Num, -Den); - else if( Num < 0 ) - return __udivsi3(-Num, Den); - else if( Den < 0 ) - return __udivsi3(Den, -Den); + Sint32 ret = 1; + if( Num < 0 ) { + ret = -ret; + Num = -Num; + } + if( Den < 0 ) { + ret = -ret; + Den = -Den; + } + if(ret < 0) + ret = -__divmod32(Num, Den, (Uint32*)Rem); else - return __udivsi3(Den, Den); + ret = __divmod32(Num, Den, (Uint32*)Rem); + return ret; +} + +Sint32 __divsi3(Sint32 Num, Sint32 Den) +{ + return DivMod32S(Num, Den, NULL); } Sint32 __modsi3(Sint32 Num, Sint32 Den) { - if( (Num < 0) && (Den < 0) ) - return __umodsi3(-Num, -Den); - else if( Num < 0 ) - return __umodsi3(-Num, Den); - else if( Den < 0 ) - return __umodsi3(Den, -Den); - else - return __umodsi3(Den, Den); + Sint32 rem; + DivMod32S(Num, Den, &rem); + return rem; }