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.1 2005/12/20 19:28:49 christos Exp $") 10#endif 11 12#ifdef RINDEX 13ENTRY(rindex) 14#else 15ENTRY(strrchr) 16#endif 17 pushl %esi 18 pushl %edi 19 pushl %ebx 20 movl 16(%esp),%edx 21 movzbl 20(%esp),%ecx 22 23 /* zero return value */ 24 xorl %eax,%eax 25 26 /* 27 * Align to word boundary. 28 * Consider unrolling loop? 29 */ 30.Lalign: 31 testb $3,%dl 32 je .Lword_aligned 33 movb (%edx),%bl 34 cmpb %cl,%bl 35 jne 1f 36 movl %edx,%eax 371: testb %bl,%bl 38 je .Ldone 39 incl %edx 40 jmp .Lalign 41 42.Lword_aligned: 43 /* copy char to all bytes in word */ 44 movb %cl,%ch 45 movl %ecx,%edi 46 sall $16,%ecx 47 orl %edi,%ecx 48 49 /* Check whether any byte in the word is equal to ch or 0. */ 50 _ALIGN_TEXT 51.Lloop: 52 movl (%edx),%ebx 53 addl $4,%edx 54 movl %ebx,%esi 55 leal -0x01010101(%ebx),%edi 56 xorl %ecx,%esi 57 subl $0x01010101,%esi 58 orl %esi,%edi 59 testl $0x80808080,%edi 60 je .Lloop 61 62 /* 63 * In rare cases, the above loop may exit prematurely. We must 64 * return to the loop if none of the bytes in the word match 65 * ch or are equal to 0. 66 */ 67 68 _ALIGN_TEXT 69 cmpb %cl,%bl /* 1st byte == ch? */ 70 jne 1f 71 leal -4(%edx),%eax 721: testb %bl,%bl /* 1st byte == 0? */ 73 je .Ldone 74 75 cmpb %cl,%bh /* 2nd byte == ch? */ 76 jne 1f 77 leal -3(%edx),%eax 781: testb %bh,%bh /* 2nd byte == 0? */ 79 je .Ldone 80 81 shrl $16,%ebx 82 cmpb %cl,%bl /* 3rd byte == ch? */ 83 jne 1f 84 leal -2(%edx),%eax 851: testb %bl,%bl /* 3rd byte == 0? */ 86 je .Ldone 87 88 cmpb %cl,%bh /* 4th byte == ch? */ 89 jne 1f 90 leal -1(%edx),%eax 911: testb %bh,%bh /* 4th byte == 0? */ 92 jne .Lloop 93 94.Ldone: 95 popl %ebx 96 popl %edi 97 popl %esi 98 ret 99