xref: /illumos-gate/usr/src/lib/libc/i386/gen/strchr.s (revision 9a70fc3b)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*9a70fc3bSMark J. Nelson * Common Development and Distribution License (the "License").
6*9a70fc3bSMark J. Nelson * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate/*
227c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
26*9a70fc3bSMark J. Nelson	.file	"strchr.s"
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate#include "SYS.h"
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate	ENTRY(strchr)
317c478bd9Sstevel@tonic-gate	mov 4(%esp), %ecx		/ src string here
327c478bd9Sstevel@tonic-gate	mov 8(%esp), %edx		/ character to find
337c478bd9Sstevel@tonic-gate	mov %ecx, %eax			/ save src
347c478bd9Sstevel@tonic-gate	and $3, %ecx			/ check if src is aligned
357c478bd9Sstevel@tonic-gate	jz prepword			/ search wordwise if it is
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate	cmpb %dl, (%eax)		/ src == char?
387c478bd9Sstevel@tonic-gate	jz done
397c478bd9Sstevel@tonic-gate	cmpb $0, (%eax)			/ src == 0?
407c478bd9Sstevel@tonic-gate	jz not_found
417c478bd9Sstevel@tonic-gate	add $1, %eax			/ increment src
427c478bd9Sstevel@tonic-gate	cmp $3, %ecx			/ check alignment
437c478bd9Sstevel@tonic-gate	jz prepword
447c478bd9Sstevel@tonic-gate	cmpb %dl, (%eax)		/ src byte contains char?
457c478bd9Sstevel@tonic-gate	jz done
467c478bd9Sstevel@tonic-gate	cmpb $0, (%eax)			/ src byte == 0?
477c478bd9Sstevel@tonic-gate	jz not_found
487c478bd9Sstevel@tonic-gate	add $1, %eax			/ increment src ptr
497c478bd9Sstevel@tonic-gate	cmp $2, %ecx			/ check alignment
507c478bd9Sstevel@tonic-gate	jz prepword
517c478bd9Sstevel@tonic-gate	cmpb %dl, (%eax) 		/ check this byte
527c478bd9Sstevel@tonic-gate	jz done
537c478bd9Sstevel@tonic-gate	cmpb $0, (%eax)			/ is byte zero?
547c478bd9Sstevel@tonic-gate	jz not_found
557c478bd9Sstevel@tonic-gate	add $1, %eax			/ increment src ptr
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gateprepword:
587c478bd9Sstevel@tonic-gate	push %ebx			/ save regs per calling convention
597c478bd9Sstevel@tonic-gate	push %esi
607c478bd9Sstevel@tonic-gate	and $0xff, %edx			/ only want 1st byte
617c478bd9Sstevel@tonic-gate	mov %edx, %ebx			/ copy character across all bytes in wd
627c478bd9Sstevel@tonic-gate	shl $8, %edx
637c478bd9Sstevel@tonic-gate	or %ebx, %edx
647c478bd9Sstevel@tonic-gate	mov %edx, %ebx
657c478bd9Sstevel@tonic-gate	shl $16, %edx
667c478bd9Sstevel@tonic-gate	or %ebx, %edx
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate	.align 16			/ align loop for max performance
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gatesearchchar:
717c478bd9Sstevel@tonic-gate	mov (%eax), %esi		/ load src word
727c478bd9Sstevel@tonic-gate	add $4, %eax			/ increment src by four
737c478bd9Sstevel@tonic-gate	mov %esi, %ebx			/ copy word
747c478bd9Sstevel@tonic-gate	lea -0x01010101(%esi), %ecx	/ (word - 0x01010101)
757c478bd9Sstevel@tonic-gate	xor %edx, %ebx			/ tmpword = word ^ char
767c478bd9Sstevel@tonic-gate	not %esi			/ ~word
777c478bd9Sstevel@tonic-gate	and $0x80808080, %esi		/ ~word & 0x80808080
787c478bd9Sstevel@tonic-gate	and %ecx, %esi			/ (wd - 0x01010101) & ~wd & 0x80808080
797c478bd9Sstevel@tonic-gate	jnz has_zero_byte
807c478bd9Sstevel@tonic-gate	lea -0x01010101(%ebx), %ecx	/ repeat with tmpword
817c478bd9Sstevel@tonic-gate	not %ebx
827c478bd9Sstevel@tonic-gate	and $0x80808080, %ebx
837c478bd9Sstevel@tonic-gate	and %ecx, %ebx
847c478bd9Sstevel@tonic-gate	jz searchchar			/ repeat if char not found
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gatefound_char:
877c478bd9Sstevel@tonic-gate	add $0x01010101, %ecx		/ restore tmpword
887c478bd9Sstevel@tonic-gate	pop %esi			/ restore esi ebx as per calling cvntn
897c478bd9Sstevel@tonic-gate	pop %ebx
907c478bd9Sstevel@tonic-gate	test $0x000000ff, %ecx		/ look for character's position in word
917c478bd9Sstevel@tonic-gate	jz done0
927c478bd9Sstevel@tonic-gate	test $0x0000ff00, %ecx
937c478bd9Sstevel@tonic-gate	jz done1
947c478bd9Sstevel@tonic-gate	test $0x00ff0000, %ecx
957c478bd9Sstevel@tonic-gate	jz done2
967c478bd9Sstevel@tonic-gatedone3:
977c478bd9Sstevel@tonic-gate	sub $1, %eax
987c478bd9Sstevel@tonic-gate	ret
997c478bd9Sstevel@tonic-gatedone2:
1007c478bd9Sstevel@tonic-gate	sub $2, %eax
1017c478bd9Sstevel@tonic-gate	ret
1027c478bd9Sstevel@tonic-gatedone1:
1037c478bd9Sstevel@tonic-gate	sub $3, %eax
1047c478bd9Sstevel@tonic-gate	ret
1057c478bd9Sstevel@tonic-gatedone0:
1067c478bd9Sstevel@tonic-gate	sub $4, %eax
1077c478bd9Sstevel@tonic-gate	ret
1087c478bd9Sstevel@tonic-gatehas_zero_byte:
1097c478bd9Sstevel@tonic-gate	add $0x01010101, %ecx		/ restore registers here
1107c478bd9Sstevel@tonic-gate	pop %esi
1117c478bd9Sstevel@tonic-gate	pop %ebx
1127c478bd9Sstevel@tonic-gate	cmpb %dl, %cl			/ check for character
1137c478bd9Sstevel@tonic-gate	je done0
1147c478bd9Sstevel@tonic-gate	testb %cl, %cl			/ check for null byte
1157c478bd9Sstevel@tonic-gate	jz not_found
1167c478bd9Sstevel@tonic-gate	cmpb %dh, %ch			/ continue checking for char, null
1177c478bd9Sstevel@tonic-gate	je done1
1187c478bd9Sstevel@tonic-gate	testb %ch, %ch
1197c478bd9Sstevel@tonic-gate	jz not_found
1207c478bd9Sstevel@tonic-gate	shr $16, %ecx			/ put bytes 2,3 into 8-but registers
1217c478bd9Sstevel@tonic-gate	cmpb %dl, %cl
1227c478bd9Sstevel@tonic-gate	je done2
1237c478bd9Sstevel@tonic-gate	testb %cl, %cl
1247c478bd9Sstevel@tonic-gate	jz not_found
1257c478bd9Sstevel@tonic-gate	cmpb %dh, %ch			/ repeat checking last 2 bytes
1267c478bd9Sstevel@tonic-gate	je done3
1277c478bd9Sstevel@tonic-gate	testb %ch, %ch
1287c478bd9Sstevel@tonic-gate	jz not_found
1297c478bd9Sstevel@tonic-gate	sub $1, %eax			/ correct for last loop iteration
1307c478bd9Sstevel@tonic-gatedone:
1317c478bd9Sstevel@tonic-gate	ret
1327c478bd9Sstevel@tonic-gatenot_found:
1337c478bd9Sstevel@tonic-gate	xor %eax, %eax
1347c478bd9Sstevel@tonic-gate	ret
1357c478bd9Sstevel@tonic-gate	SET_SIZE(strchr)
136