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