Author: tkreuzer Date: Thu Dec 23 19:11:19 2010 New Revision: 50116
URL: http://svn.reactos.org/svn/reactos?rev=50116&view=rev Log: [RTL} Replace RtlMoveMemory x86 asm code with the code from CRT's memmove, which is better. Now we can close bug #1941
Modified: trunk/reactos/lib/rtl/i386/rtlmem.s
Modified: trunk/reactos/lib/rtl/i386/rtlmem.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/i386/rtlmem.s?rev=5... ============================================================================== --- trunk/reactos/lib/rtl/i386/rtlmem.s [iso-8859-1] (original) +++ trunk/reactos/lib/rtl/i386/rtlmem.s [iso-8859-1] Thu Dec 23 19:11:19 2010 @@ -210,70 +210,124 @@
_RtlMoveMemory@12: - - /* Save volatiles */ + push ebp + mov ebp, esp + + /* Save non-volatiles */ push esi push edi
/* Get pointers and size */ - mov esi, [esp+16] - mov edi, [esp+12] - mov ecx, [esp+20] - cld - - /* Check if the destination is higher (or equal) */ - cmp esi, edi - jbe Overlap - - /* Set ULONG size and UCHAR remainder */ -DoMove: - mov edx, ecx - and edx, 3 - shr ecx, 2 - - /* Do the move */ - rep movsd - or ecx, edx - jnz ByteMove - - /* Return */ - pop edi - pop esi - ret 12 - -ByteMove: - /* Move what's left */ - rep movsb - -DoneMove: - /* Restore volatiles */ - pop edi - pop esi - ret 12 - -Overlap: - /* Don't copy if they're equal */ - jz DoneMove - - /* Compare pointer distance with given length and check for overlap */ - mov eax, edi - sub eax, esi - cmp ecx, eax - jbe DoMove - - /* Set direction flag for backward move */ - std - - /* Copy byte-by-byte the non-overlapping distance */ - add esi, ecx - add edi, ecx - dec esi - dec edi - - /* Do the move, reset flag and return */ - rep movsb - cld - jmp DoneMove + mov edi, [ebp + 8] + mov esi, [ebp + 12] + mov ecx, [ebp + 16] + + /* Use downward copy if source < dest and overlapping */ + cmp edi, esi + jbe .CopyUp + mov eax, ecx + add eax, esi + cmp edi, eax + jb .CopyDown + +.CopyUp: + cld + + /* Check for small moves */ + cmp ecx, 16 + jb .CopyUpBytes + + /* Check if its already aligned */ + mov edx, ecx + test edi, 3 + je .CopyUpDwords + + /* Make the destination dword aligned */ + mov ecx, edi + and ecx, 3 + sub ecx, 5 + not ecx + sub edx, ecx + rep movsb + mov ecx, edx + +.CopyUpDwords: + shr ecx, 2 + rep movsd + mov ecx, edx + and ecx, 3 + +.CopyUpBytes: + test ecx, ecx + je .CopyUpEnd + rep movsb + +.CopyUpEnd: + mov eax, [ebp + 8] + pop edi + pop esi + pop ebp + ret 12 + +.CopyDown: + std + + /* Go to the end of the region */ + add edi, ecx + add esi, ecx + + /* Check for small moves */ + cmp ecx, 16 + jb .CopyDownSmall + + /* Check if its already aligned */ + mov edx, ecx + test edi, 3 + je .CopyDownAligned + + /* Make the destination dword aligned */ + mov ecx, edi + and ecx, 3 + sub edx, ecx + dec esi + dec edi + rep movsb + mov ecx, edx + sub esi, 3 + sub edi, 3 + +.CopyDownDwords: + shr ecx, 2 + rep movsd + mov ecx, edx + and ecx, 3 + je .CopyDownEnd + add esi, 3 + add edi, 3 + +.CopyDownBytes: + rep movsb + +.CopyDownEnd: + cld + mov eax, [ebp + 8] + pop edi + pop esi + pop ebp + ret 12 + +.CopyDownAligned: + sub edi, 4 + sub esi, 4 + jmp .CopyDownDwords + +.CopyDownSmall: + test ecx, ecx + je .CopyDownEnd + dec esi + dec edi + jmp .CopyDownBytes +
@RtlPrefetchMemoryNonTemporal@8: