strrchr.S revision 1.3 1 /*
2 * Written by J.T. Conklin <jtc (at) 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
12 ENTRY(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
69 1: 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
76 1: 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
83 1: 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
90 1: 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
97 1: 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
104 1: 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
111 1: 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
118 1: testb %dl,%dl /* 8th byte == 0? */
119 jne .Lloop
120
121 .Ldone:
122 ret
123 END(strrchr)
124
125 STRONG_ALIAS(rindex,strrchr)
126