reactos/lib/rtl/i386/rtlmem.s
Amine Khaldi 527f2f9057 [SHELL/EXPERIMENTS]
* Create a branch for some evul shell experiments.

svn path=/branches/shell-experiments/; revision=61927
2014-02-02 19:37:27 +00:00

363 lines
5.5 KiB
ArmAsm

/*
* COPYRIGHT: GNU GPL - See COPYING in the top level directory
* PROJECT: ReactOS Run-Time Library
* PURPOSE: Memory functions
* FILE: lib/rtl/i386/rtlswap.S
* PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
#include <asm.inc>
/* GLOBALS *******************************************************************/
PUBLIC _RtlCompareMemory@12
PUBLIC _RtlCompareMemoryUlong@12
PUBLIC _RtlFillMemory@12
PUBLIC _RtlFillMemoryUlong@12
PUBLIC _RtlMoveMemory@12
PUBLIC _RtlZeroMemory@8
PUBLIC @RtlPrefetchMemoryNonTemporal@8
/* FUNCTIONS *****************************************************************/
.code
_RtlCompareMemory@12:
/* Save volatiles */
push esi
push edi
/* Clear direction flag and load pointers and size in ULONGs */
cld
mov esi, [esp+12]
mov edi, [esp+16]
mov ecx, [esp+20]
shr ecx, 2
jz NoUlongs
/* Compare the ULONGs */
repe cmpsd
jnz NotEqual
NoUlongs:
/* Compare what's left */
mov ecx, [esp+20]
and ecx, 3
jz NoneLeft
repe cmpsb
jnz NotEqual2
NoneLeft:
/* We're done, return full count */
mov eax, [esp+20]
pop edi
pop esi
ret 12
NotEqual:
/* Compare the last ULONG */
sub esi, 4
sub edi, 4
mov ecx, 5
repe cmpsb
NotEqual2:
/* Remember how many matched */
dec esi
sub esi, [esp+12]
/* Return count */
mov eax, esi
pop edi
pop esi
ret 12
_RtlCompareMemoryUlong@12:
/* Get pointers and size in ULONGs */
push edi
mov edi, [esp+8]
mov ecx, [esp+12]
mov eax, [esp+16]
shr ecx, 2
/* Do the compare and check result */
repe scasd
jz Done
sub edi, 4
/* Return count */
Done:
sub edi, [esp+8]
mov eax, edi
pop edi
ret 12
_RtlFillMemory@12:
/* Get pointers and size */
push edi
mov edi, [esp+8]
mov ecx, [esp+12]
/* Get pattern */
mov al, [esp+16]
mov ah, al
shl eax, 16
mov al, [esp+16]
mov ah, al
/* Clear direction flag and set ULONG size and UCHAR remainder */
cld
mov edx, ecx
and edx, 3
shr ecx, 2
/* Do the fill */
rep stosd
or ecx, edx
jnz ByteFill
/* Return */
pop edi
ret 12
ByteFill:
/* Fill what's left */
rep stosb
pop edi
ret 12
_RtlFillMemoryUlong@12:
/* Get pointer, size and pattern */
push edi
mov edi, [esp+8]
mov ecx, [esp+12]
mov eax, [esp+16]
shr ecx, 2
/* Do the fill and return */
rep stosd
pop edi
ret 12
_RtlFillMemoryUlonglong@16:
/* Save volatiles */
push edi
push esi
/* Get pointer, size and pattern */
mov ecx, [esp+16]
mov esi, [esp+12]
mov eax, [esp+20]
shr ecx, 2
sub ecx, 2
/* Save the first part */
mov [esi], eax
/* Read second part */
mov eax, [esp+24]
lea edi, [esi+8]
mov [esi+4], eax
/* Do the fill and return */
rep movsd
pop esi
pop edi
ret 16
_RtlZeroMemory@8:
/* Get pointers and size */
push edi
mov edi, [esp+8]
mov ecx, [esp+12]
/* Get pattern */
xor eax, eax
/* Clear direction flag and set ULONG size and UCHAR remainder */
cld
mov edx, ecx
and edx, 3
shr ecx, 2
/* Do the fill */
rep stosd
or ecx, edx
jnz ByteZero
/* Return */
pop edi
ret 8
ByteZero:
/* Fill what's left */
rep stosb
pop edi
ret 8
_RtlMoveMemory@12:
push ebp
mov ebp, esp
/* Save non-volatiles */
push esi
push edi
/* Get pointers and size */
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:
/*
* Overwritten by ntoskrnl/ke/i386/kernel.c if SSE is supported
* (see Ki386SetProcessorFeatures())
*/
ret
/* Get granularity */
mov eax, [_Ke386CacheAlignment]
FetchLine:
/* Prefetch this line */
prefetchnta byte ptr [ecx]
/* Update address and count */
add ecx, eax
sub edx, eax
/* Keep looping for the next line, or return if done */
ja FetchLine
ret
/* FIXME: HACK */
_Ke386CacheAlignment:
.long 64
END