strchr.S revision 1.2 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.2 2009/07/17 19:37:57 dsl Exp $")
10 #endif
11
12 ENTRY(strchr)
13 pushl %esi
14 pushl %ebx
15 movl 12(%esp),%eax
16 movzbl 16(%esp),%ecx
17
18 /*
19 * Align to word boundary.
20 * Consider unrolling loop?
21 */
22 .Lalign:
23 testb $3,%al
24 je .Lword_aligned
25 movb (%eax),%bl
26 cmpb %cl,%bl
27 je .Ldone
28 testb %bl,%bl
29 je .Lzero
30 incl %eax
31 jmp .Lalign
32
33 .Lword_aligned:
34 /* copy char to all bytes in word */
35 movb %cl,%ch
36 movl %ecx,%edx
37 sall $16,%ecx
38 orl %edx,%ecx
39
40 /* Check whether any byte in the word is equal to ch or 0. */
41 _ALIGN_TEXT
42 .Lloop:
43 movl (%eax),%ebx
44 addl $4,%eax
45 movl %ebx,%esi
46 leal -0x01010101(%ebx),%edx
47 xorl %ecx,%esi
48 subl $0x01010101,%esi
49 orl %esi,%edx
50 testl $0x80808080,%edx
51 je .Lloop
52
53 /*
54 * In rare cases, the above loop may exit prematurely. We must
55 * return to the loop if none of the bytes in the word match
56 * ch or are equal to 0.
57 */
58
59 /*
60 * Alignment here avoids a stall on the Athlon, even though
61 * it's not a branch target.
62 */
63
64 _ALIGN_TEXT
65 cmpb %cl,%bl /* 1st byte == ch? */
66 jne 1f
67 subl $4,%eax
68 jmp .Ldone
69 1: testb %bl,%bl /* 1st byte == 0? */
70 je .Lzero
71
72 cmpb %cl,%bh /* 2nd byte == ch? */
73 jne 1f
74 subl $3,%eax
75 jmp .Ldone
76 1: testb %bh,%bh /* 2nd byte == 0? */
77 je .Lzero
78
79 shrl $16,%ebx
80 cmpb %cl,%bl /* 3rd byte == ch? */
81 jne 1f
82 subl $2,%eax
83 jmp .Ldone
84 1: testb %bl,%bl /* 3rd byte == 0? */
85 je .Lzero
86
87 cmpb %cl,%bh /* 4th byte == ch? */
88 jne 1f
89 decl %eax
90 jmp .Ldone
91 1: testb %bh,%bh /* 4th byte == 0? */
92 jne .Lloop
93
94 .Lzero:
95 /* If a ch wasn't found, return 0. */
96 xorl %eax,%eax
97
98 .Ldone:
99 popl %ebx
100 popl %esi
101 ret
102
103 STRONG_ALIAS(index,strchr)
104