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