Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1626 → Rev 1627

/drivers/ddk/string/memcmp.S
1,59 → 1,57
# memcmp() Author: Kees J. Bot
# 2 Jan 1994
/* memcmp() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
# int memcmp(const void *s1, const void *s2, size_t n)
# Compare two chunks of memory.
#
/* int memcmp(const void *s1, const void *s2, size_t n) */
/* Compare two chunks of memory. */
/* */
#include "asm.h"
 
.intel_syntax
ENTRY(memcmp)
cld
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl 8(%ebp), %esi /* String s1 */
movl 12(%ebp), %edi /* String s2 */
movl 16(%ebp), %ecx /* Length */
cmpl $16, %ecx
jb cbyte /* Don't bother being smart with short arrays */
movl %esi, %eax
orl %edi, %eax
testb $1, %al
jne cbyte /* Bit 0 set, use byte compare */
testb $2, %al
jne cword /* Bit 1 set, use word compare */
clword:
shrdl $2, %ecx, %eax /* Save low two bits of ecx in eax */
shrl $2, %ecx
 
.globl _memcmp
repe cmpsl /* Compare longwords */
subl $4, %esi
subl $4, %edi
incl %ecx /* Recompare the last longword */
shldl $2, %eax, %ecx /* And any excess bytes */
jmp last
cword:
shrdl $1, %ecx, %eax /* Save low bit of ecx in eax */
shrl $1, %ecx
 
.text
.align 16
_memcmp:
cld
push ebp
mov ebp, esp
push esi
push edi
mov esi, [8+ebp] # String s1
mov edi, [12+ebp] # String s2
mov ecx, [16+ebp] # Length
cmp ecx, 16
jb cbyte # Don't bother being smart with short arrays
mov eax, esi
or eax, edi
testb al, 1
jnz cbyte # Bit 0 set, use byte compare
testb al, 2
jnz cword # Bit 1 set, use word compare
clword: shrd eax, ecx, 2 # Save low two bits of ecx in eax
shr ecx, 2
repe
cmpsd # Compare longwords
sub esi, 4
sub edi, 4
inc ecx # Recompare the last longword
shld ecx, eax, 2 # And any excess bytes
jmp last
cword: shrd eax, ecx, 1 # Save low bit of ecx in eax
shr ecx, 1
repe
cmpsw # Compare words
sub esi, 2
sub edi, 2
inc ecx # Recompare the last word
shld ecx, eax, 1 # And one more byte?
cbyte: test ecx, ecx # Set 'Z' flag if ecx = 0
last: repe
cmpsb # Look for the first differing byte
seta al # al = (s1 > s2)
setb ah # ah = (s1 < s2)
subb al, ah
movsxb eax, al # eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
mov edx, esi # For bcmp() to play with
pop edi
pop esi
pop ebp
repe cmpsw /* Compare words */
subl $2, %esi
subl $2, %edi
incl %ecx /* Recompare the last word */
shldl $1, %eax, %ecx /* And one more byte? */
cbyte:
testl %ecx, %ecx /* Set 'Z' flag if ecx = 0 */
last:
repe cmpsb /* Look for the first differing byte */
seta %al /* al = (s1 > s2) */
setb %ah /* ah = (s1 < s2) */
subb %ah, %al
movsbl %al, %eax /* eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 */
movl %esi, %edx /* For bcmp() to play with */
pop %edi
pop %esi
pop %ebp
ret