1/* 2 * Written by J.T. Conklin <jtc@acorntoolworks.com> 3 * Public domain. 4 */ 5 6#include <machine/asm.h> 7 8#if defined(LIBC_SCCS) 9 RCSID("$NetBSD: strrchr.S,v 1.3 2014/03/22 19:38:46 jakllsch Exp $") 10#endif 11 12ENTRY(strrchr) 13 pushl %esi 14 pushl %edi 15 pushl %ebx 16 movl 16(%esp),%edx 17 movzbl 20(%esp),%ecx 18 19 /* zero return value */ 20 xorl %eax,%eax 21 22 /* 23 * Align to word boundary. 24 * Consider unrolling loop? 25 */ 26.Lalign: 27 testb $3,%dl 28 je .Lword_aligned 29 movb (%edx),%bl 30 cmpb %cl,%bl 31 jne 1f 32 movl %edx,%eax 331: testb %bl,%bl 34 je .Ldone 35 incl %edx 36 jmp .Lalign 37 38.Lword_aligned: 39 /* copy char to all bytes in word */ 40 movb %cl,%ch 41 movl %ecx,%edi 42 sall $16,%ecx 43 orl %edi,%ecx 44 45 /* Check whether any byte in the word is equal to ch or 0. */ 46 _ALIGN_TEXT 47.Lloop: 48 movl (%edx),%ebx 49 addl $4,%edx 50 movl %ebx,%esi 51 leal -0x01010101(%ebx),%edi 52 xorl %ecx,%esi 53 subl $0x01010101,%esi 54 orl %esi,%edi 55 testl $0x80808080,%edi 56 je .Lloop 57 58 /* 59 * In rare cases, the above loop may exit prematurely. We must 60 * return to the loop if none of the bytes in the word match 61 * ch or are equal to 0. 62 */ 63 64 _ALIGN_TEXT 65 cmpb %cl,%bl /* 1st byte == ch? */ 66 jne 1f 67 leal -4(%edx),%eax 681: testb %bl,%bl /* 1st byte == 0? */ 69 je .Ldone 70 71 cmpb %cl,%bh /* 2nd byte == ch? */ 72 jne 1f 73 leal -3(%edx),%eax 741: testb %bh,%bh /* 2nd byte == 0? */ 75 je .Ldone 76 77 shrl $16,%ebx 78 cmpb %cl,%bl /* 3rd byte == ch? */ 79 jne 1f 80 leal -2(%edx),%eax 811: testb %bl,%bl /* 3rd byte == 0? */ 82 je .Ldone 83 84 cmpb %cl,%bh /* 4th byte == ch? */ 85 jne 1f 86 leal -1(%edx),%eax 871: testb %bh,%bh /* 4th byte == 0? */ 88 jne .Lloop 89 90.Ldone: 91 popl %ebx 92 popl %edi 93 popl %esi 94 ret 95END(strrchr) 96 97STRONG_ALIAS(rindex,strrchr) 98