xref: /illumos-gate/usr/src/lib/libc/i386/gen/strchr.s (revision 7c478bd9)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27	.ident	"%Z%%M%	%I%	%E% SMI"
28
29	.file	"%M%"
30
31#include "SYS.h"
32
33	ENTRY(strchr)
34	mov 4(%esp), %ecx		/ src string here
35	mov 8(%esp), %edx		/ character to find
36	mov %ecx, %eax			/ save src
37	and $3, %ecx			/ check if src is aligned
38	jz prepword			/ search wordwise if it is
39
40	cmpb %dl, (%eax)		/ src == char?
41	jz done
42	cmpb $0, (%eax)			/ src == 0?
43	jz not_found
44	add $1, %eax			/ increment src
45	cmp $3, %ecx			/ check alignment
46	jz prepword
47	cmpb %dl, (%eax)		/ src byte contains char?
48	jz done
49	cmpb $0, (%eax)			/ src byte == 0?
50	jz not_found
51	add $1, %eax			/ increment src ptr
52	cmp $2, %ecx			/ check alignment
53	jz prepword
54	cmpb %dl, (%eax) 		/ check this byte
55	jz done
56	cmpb $0, (%eax)			/ is byte zero?
57	jz not_found
58	add $1, %eax			/ increment src ptr
59
60prepword:
61	push %ebx			/ save regs per calling convention
62	push %esi
63	and $0xff, %edx			/ only want 1st byte
64	mov %edx, %ebx			/ copy character across all bytes in wd
65	shl $8, %edx
66	or %ebx, %edx
67	mov %edx, %ebx
68	shl $16, %edx
69	or %ebx, %edx
70
71	.align 16			/ align loop for max performance
72
73searchchar:
74	mov (%eax), %esi		/ load src word
75	add $4, %eax			/ increment src by four
76	mov %esi, %ebx			/ copy word
77	lea -0x01010101(%esi), %ecx	/ (word - 0x01010101)
78	xor %edx, %ebx			/ tmpword = word ^ char
79	not %esi			/ ~word
80	and $0x80808080, %esi		/ ~word & 0x80808080
81	and %ecx, %esi			/ (wd - 0x01010101) & ~wd & 0x80808080
82	jnz has_zero_byte
83	lea -0x01010101(%ebx), %ecx	/ repeat with tmpword
84	not %ebx
85	and $0x80808080, %ebx
86	and %ecx, %ebx
87	jz searchchar			/ repeat if char not found
88
89found_char:
90	add $0x01010101, %ecx		/ restore tmpword
91	pop %esi			/ restore esi ebx as per calling cvntn
92	pop %ebx
93	test $0x000000ff, %ecx		/ look for character's position in word
94	jz done0
95	test $0x0000ff00, %ecx
96	jz done1
97	test $0x00ff0000, %ecx
98	jz done2
99done3:
100	sub $1, %eax
101	ret
102done2:
103	sub $2, %eax
104	ret
105done1:
106	sub $3, %eax
107	ret
108done0:
109	sub $4, %eax
110	ret
111has_zero_byte:
112	add $0x01010101, %ecx		/ restore registers here
113	pop %esi
114	pop %ebx
115	cmpb %dl, %cl			/ check for character
116	je done0
117	testb %cl, %cl			/ check for null byte
118	jz not_found
119	cmpb %dh, %ch			/ continue checking for char, null
120	je done1
121	testb %ch, %ch
122	jz not_found
123	shr $16, %ecx			/ put bytes 2,3 into 8-but registers
124	cmpb %dl, %cl
125	je done2
126	testb %cl, %cl
127	jz not_found
128	cmpb %dh, %ch			/ repeat checking last 2 bytes
129	je done3
130	testb %ch, %ch
131	jz not_found
132	sub $1, %eax			/ correct for last loop iteration
133done:
134	ret
135not_found:
136	xor %eax, %eax
137	ret
138	SET_SIZE(strchr)
139