[ros-diffs] [tkreuzer] 50116: [RTL} Replace RtlMoveMemory x86 asm code with the code from CRT's memmove, which is better. Now we can close bug #1941

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Thu Dec 23 19:11:20 UTC 2010


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=50116&r1=50115&r2=50116&view=diff
==============================================================================
--- 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 at 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 at 8:




More information about the Ros-diffs mailing list