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