minix/common/lib/libc/arch/i386/string/strrchr.S
Lionel Sambuc 84d9c625bf Synchronize on NetBSD-CVS (2013/12/1 12:00:00 UTC)
- Fix for possible unset uid/gid in toproto
 - Fix for default mtree style
 - Update libelf
 - Importing libexecinfo
 - Resynchronize GCC, mpc, gmp, mpfr
 - build.sh: Replace params with show-params.
     This has been done as the make target has been renamed in the same
     way, while a new target named params has been added. This new
     target generates a file containing all the parameters, instead of
     printing it on the console.
 - Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org)
     get getservbyport() out of the inner loop

Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
2014-07-28 17:05:06 +02:00

96 lines
1.6 KiB
ArmAsm

/*
* Written by J.T. Conklin <jtc@acorntoolworks.com>
* Public domain.
*/
#include <machine/asm.h>
#if defined(LIBC_SCCS)
RCSID("$NetBSD: strrchr.S,v 1.2 2009/07/17 19:37:57 dsl Exp $")
#endif
ENTRY(strrchr)
pushl %esi
pushl %edi
pushl %ebx
movl 16(%esp),%edx
movzbl 20(%esp),%ecx
/* zero return value */
xorl %eax,%eax
/*
* Align to word boundary.
* Consider unrolling loop?
*/
.Lalign:
testb $3,%dl
je .Lword_aligned
movb (%edx),%bl
cmpb %cl,%bl
jne 1f
movl %edx,%eax
1: testb %bl,%bl
je .Ldone
incl %edx
jmp .Lalign
.Lword_aligned:
/* copy char to all bytes in word */
movb %cl,%ch
movl %ecx,%edi
sall $16,%ecx
orl %edi,%ecx
/* Check whether any byte in the word is equal to ch or 0. */
_ALIGN_TEXT
.Lloop:
movl (%edx),%ebx
addl $4,%edx
movl %ebx,%esi
leal -0x01010101(%ebx),%edi
xorl %ecx,%esi
subl $0x01010101,%esi
orl %esi,%edi
testl $0x80808080,%edi
je .Lloop
/*
* In rare cases, the above loop may exit prematurely. We must
* return to the loop if none of the bytes in the word match
* ch or are equal to 0.
*/
_ALIGN_TEXT
cmpb %cl,%bl /* 1st byte == ch? */
jne 1f
leal -4(%edx),%eax
1: testb %bl,%bl /* 1st byte == 0? */
je .Ldone
cmpb %cl,%bh /* 2nd byte == ch? */
jne 1f
leal -3(%edx),%eax
1: testb %bh,%bh /* 2nd byte == 0? */
je .Ldone
shrl $16,%ebx
cmpb %cl,%bl /* 3rd byte == ch? */
jne 1f
leal -2(%edx),%eax
1: testb %bl,%bl /* 3rd byte == 0? */
je .Ldone
cmpb %cl,%bh /* 4th byte == ch? */
jne 1f
leal -1(%edx),%eax
1: testb %bh,%bh /* 4th byte == 0? */
jne .Lloop
.Ldone:
popl %ebx
popl %edi
popl %esi
ret
STRONG_ALIAS(rindex,strrchr)