Replace RtlMoveMemory x86 asm code with the code from CRT's memmove, which is better. Now we can close bug #1941

svn path=/trunk/; revision=50116
This commit is contained in:
Timo Kreuzer 2010-12-23 19:11:19 +00:00
parent c884962fb3
commit e7f8fba710

View file

@ -210,70 +210,124 @@ ByteZero:
_RtlMoveMemory@12: _RtlMoveMemory@12:
push ebp
mov ebp, esp
/* Save volatiles */ /* Save non-volatiles */
push esi push esi
push edi push edi
/* Get pointers and size */ /* Get pointers and size */
mov esi, [esp+16] mov edi, [ebp + 8]
mov edi, [esp+12] mov esi, [ebp + 12]
mov ecx, [esp+20] 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 cld
/* Check if the destination is higher (or equal) */ /* Check for small moves */
cmp esi, edi cmp ecx, 16
jbe Overlap jb .CopyUpBytes
/* Set ULONG size and UCHAR remainder */ /* Check if its already aligned */
DoMove:
mov edx, ecx mov edx, ecx
and edx, 3 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 shr ecx, 2
/* Do the move */
rep movsd rep movsd
or ecx, edx mov ecx, edx
jnz ByteMove and ecx, 3
/* Return */ .CopyUpBytes:
pop edi test ecx, ecx
pop esi je .CopyUpEnd
ret 12
ByteMove:
/* Move what's left */
rep movsb rep movsb
DoneMove: .CopyUpEnd:
/* Restore volatiles */ mov eax, [ebp + 8]
pop edi pop edi
pop esi pop esi
pop ebp
ret 12 ret 12
Overlap: .CopyDown:
/* 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 std
/* Copy byte-by-byte the non-overlapping distance */ /* Go to the end of the region */
add esi, ecx
add edi, ecx 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 esi
dec edi dec edi
/* Do the move, reset flag and return */
rep movsb 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 cld
jmp DoneMove 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: @RtlPrefetchMemoryNonTemporal@8: