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