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:16:34 jakllsch Exp $") 10#endif 11 12ENTRY(strrchr) 13 movzbq %sil,%rcx 14 15 /* zero return value */ 16 xorq %rax,%rax 17 18 /* 19 * Align to word boundary. 20 * Consider unrolling loop? 21 */ 22.Lalign: 23 testb $7,%dil 24 je .Lword_aligned 25 movb (%rdi),%dl 26 cmpb %cl,%dl 27 cmoveq %rdi,%rax 28 incq %rdi 29 testb %dl,%dl 30 jne .Lalign 31 jmp .Ldone 32 33.Lword_aligned: 34 /* copy char to all bytes in word */ 35 movb %cl,%ch 36 movq %rcx,%rdx 37 salq $16,%rcx 38 orq %rdx,%rcx 39 movq %rcx,%rdx 40 salq $32,%rcx 41 orq %rdx,%rcx 42 43 movabsq $0x0101010101010101,%r8 44 movabsq $0x8080808080808080,%r9 45 46 /* Check whether any byte in the word is equal to ch or 0. */ 47 _ALIGN_TEXT 48.Lloop: 49 movq (%rdi),%rdx 50 addq $8,%rdi 51 movq %rdx,%rsi 52 subq %r8,%rdx 53 xorq %rcx,%rsi 54 subq %r8,%rsi 55 orq %rsi,%rdx 56 testq %r9,%rdx 57 je .Lloop 58 59 /* 60 * In rare cases, the above loop may exit prematurely. We must 61 * return to the loop if none of the bytes in the word match 62 * ch or are equal to 0. 63 */ 64 65 movb -8(%rdi),%dl 66 cmpb %cl,%dl /* 1st byte == ch? */ 67 jne 1f 68 leaq -8(%rdi),%rax 691: testb %dl,%dl /* 1st byte == 0? */ 70 je .Ldone 71 72 movb -7(%rdi),%dl 73 cmpb %cl,%dl /* 2nd byte == ch? */ 74 jne 1f 75 leaq -7(%rdi),%rax 761: testb %dl,%dl /* 2nd byte == 0? */ 77 je .Ldone 78 79 movb -6(%rdi),%dl 80 cmpb %cl,%dl /* 3rd byte == ch? */ 81 jne 1f 82 leaq -6(%rdi),%rax 831: testb %dl,%dl /* 3rd byte == 0? */ 84 je .Ldone 85 86 movb -5(%rdi),%dl 87 cmpb %cl,%dl /* 4th byte == ch? */ 88 jne 1f 89 leaq -5(%rdi),%rax 901: testb %dl,%dl /* 4th byte == 0? */ 91 je .Ldone 92 93 movb -4(%rdi),%dl 94 cmpb %cl,%dl /* 5th byte == ch? */ 95 jne 1f 96 leaq -4(%rdi),%rax 971: testb %dl,%dl /* 5th byte == 0? */ 98 je .Ldone 99 100 movb -3(%rdi),%dl 101 cmpb %cl,%dl /* 6th byte == ch? */ 102 jne 1f 103 leaq -3(%rdi),%rax 1041: testb %dl,%dl /* 6th byte == 0? */ 105 je .Ldone 106 107 movb -2(%rdi),%dl 108 cmpb %cl,%dl /* 7th byte == ch? */ 109 jne 1f 110 leaq -2(%rdi),%rax 1111: testb %dl,%dl /* 7th byte == 0? */ 112 je .Ldone 113 114 movb -1(%rdi),%dl 115 cmpb %cl,%dl /* 8th byte == ch? */ 116 jne 1f 117 leaq -1(%rdi),%rax 1181: testb %dl,%dl /* 8th byte == 0? */ 119 jne .Lloop 120 121.Ldone: 122 ret 123END(strrchr) 124 125STRONG_ALIAS(rindex,strrchr) 126