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