1/*
2 * ====================================================
3 * Copyright (C) 1998, 2002, 2008 by Red Hat Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this
6 * software is freely granted, provided that this notice
7 * is preserved.
8 * ====================================================
9 */
10
11	#include "i386mach.h"
12
13	.global SYM (strchr)
14       SOTYPE_FUNCTION(strchr)
15
16SYM (strchr):
17
18#ifdef __iamcu__
19	xorl ecx,ecx
20	movb dl,cl
21
22/* loop while (*s && *s++ != c) */
23	leal -1(eax),eax
24L15:
25	incl eax
26	movb (eax),dl
27	testb dl,dl
28	je L14
29	cmpb cl,dl
30	jne L15
31
32L14:
33/*  if (*s == c) return address otherwise return NULL */
34	cmpb cl,(eax)
35	je L19
36	xorl eax,eax
37
38L19:
39	ret
40#else
41	pushl ebp
42	movl esp,ebp
43	pushl edi
44	pushl ebx
45	xorl ebx,ebx
46	movl 8(ebp),edi
47	addb 12(ebp),bl
48
49#ifndef __OPTIMIZE_SIZE__
50/* Special case strchr(p,0).  */
51	je L25
52
53/* Do byte-wise checks until string is aligned.  */
54	test $3,edi
55	je L5
56	movl edi,eax
57	movb (eax),cl
58	testb cl,cl
59	je L14
60	cmpb bl,cl
61	je L19
62	incl edi
63
64	test $3,edi
65	je L5
66	movl edi,eax
67	movb (eax),cl
68	testb cl,cl
69	je L14
70	cmpb bl,cl
71	je L19
72	incl edi
73
74	test $3,edi
75	je L5
76	movl edi,eax
77	movb (eax),cl
78	testb cl,cl
79	je L14
80	cmpb bl,cl
81	je L19
82	incl edi
83
84/* create 4 byte mask which is just the desired byte repeated 4 times */
85L5:
86	movl ebx,ecx
87	sall $8,ebx
88	subl $4,edi
89	orl ecx,ebx
90	movl ebx,edx
91	sall $16,ebx
92	orl edx,ebx
93
94/* loop performing 4 byte mask checking for 0 byte or desired byte */
95	.p2align 4,,7
96L10:
97	addl $4,edi
98	movl (edi),ecx
99	leal -16843009(ecx),edx
100	movl ecx,eax
101	notl eax
102	andl eax,edx
103	testl $-2139062144,edx
104	jne L9
105
106	xorl ebx,ecx
107	leal -16843009(ecx),edx
108	notl ecx
109	andl ecx,edx
110	testl $-2139062144,edx
111	je L10
112#endif /* not __OPTIMIZE_SIZE__ */
113
114/* loop while (*s && *s++ != c) */
115L9:
116	leal -1(edi),eax
117	.p2align 4,,7
118L15:
119	incl eax
120	movb (eax),dl
121	testb dl,dl
122	je L14
123	cmpb bl,dl
124	jne L15
125
126L14:
127/*  if (*s == c) return address otherwise return NULL */
128	cmpb bl,(eax)
129	je L19
130	xorl eax,eax
131
132L19:
133	leal -8(ebp),esp
134	popl ebx
135	popl edi
136	leave
137	ret
138
139#ifndef __OPTIMIZE_SIZE__
140/* Special case strchr(p,0).  */
141#if 0
142	/* Hideous performance on modern machines.  */
143L25:
144	cld
145	movl $-1,ecx
146	xor eax,eax
147	repnz
148	scasb
149	leal -1(edi),eax
150	jmp L19
151#endif
152L25:
153/* Do byte-wise checks until string is aligned.  */
154	test $3,edi
155	je L26
156	movl edi,eax
157	movb (eax),cl
158	testb cl,cl
159	je L19
160	incl edi
161
162	test $3,edi
163	je L26
164	movl edi,eax
165	movb (eax),cl
166	testb cl,cl
167	je L19
168	incl edi
169
170	test $3,edi
171	je L26
172	movl edi,eax
173	movb (eax),cl
174	testb cl,cl
175	je L19
176	incl edi
177
178L26:
179	subl $4,edi
180
181/* loop performing 4 byte mask checking for desired 0 byte */
182	.p2align 4,,7
183L27:
184	addl $4,edi
185	movl (edi),ecx
186	leal -16843009(ecx),edx
187	movl ecx,eax
188	notl eax
189	andl eax,edx
190	testl $-2139062144,edx
191	je L27
192
193	jmp L9
194
195#endif /* !__OPTIMIZE_SIZE__ */
196
197#endif /* __iamcu__ */
198
199#if defined(__linux__) && defined(__ELF__)
200.section .note.GNU-stack,"",%progbits
201#endif
202