xref: /titanic_52/usr/src/lib/libc/sparcv9/gen/strlen.s (revision 9a70fc3be3b1e966bf78825cdb8d509963a6f0a1)
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
57257d1b4Sraf * Common Development and Distribution License (the "License").
67257d1b4Sraf * 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 */
217257d1b4Sraf
227c478bd9Sstevel@tonic-gate/*
237257d1b4Sraf * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
27*9a70fc3bSMark J. Nelson	.file	"strlen.s"
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate/*
307c478bd9Sstevel@tonic-gate * strlen(s)
317c478bd9Sstevel@tonic-gate *
327c478bd9Sstevel@tonic-gate * Given string s, return length (not including the terminating null).
337c478bd9Sstevel@tonic-gate *
347c478bd9Sstevel@tonic-gate * Fast assembler language version of the following C-program strlen
357c478bd9Sstevel@tonic-gate * which represents the `standard' for the C-library.
367c478bd9Sstevel@tonic-gate *
377c478bd9Sstevel@tonic-gate *	size_t
387c478bd9Sstevel@tonic-gate *	strlen(s)
397c478bd9Sstevel@tonic-gate *	register const char *s;
407c478bd9Sstevel@tonic-gate *	{
417c478bd9Sstevel@tonic-gate *		register const char *s0 = s + 1;
427c478bd9Sstevel@tonic-gate *
437c478bd9Sstevel@tonic-gate *		while (*s++ != '\0')
447c478bd9Sstevel@tonic-gate *			;
457c478bd9Sstevel@tonic-gate *		return (s - s0);
467c478bd9Sstevel@tonic-gate *	}
477c478bd9Sstevel@tonic-gate */
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate	! The object of strlen is to, as quickly as possible, find the
527c478bd9Sstevel@tonic-gate	! null byte.  To this end, we attempt to get our string aligned
537c478bd9Sstevel@tonic-gate	! and then blast across it using Alan Mycroft's algorithm for
547c478bd9Sstevel@tonic-gate	! finding null bytes. If we are not aligned, the string is
557c478bd9Sstevel@tonic-gate	! checked a byte at a time until it is.  Once this occurs,
567c478bd9Sstevel@tonic-gate	! we can proceed word-wise across it.  Once a word with a
577c478bd9Sstevel@tonic-gate	! zero byte has been found, we then check the word a byte
587c478bd9Sstevel@tonic-gate	! at a time until we've located the zero byte, and return
597c478bd9Sstevel@tonic-gate	! the proper length.
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate	.align 32
627c478bd9Sstevel@tonic-gate	ENTRY(strlen)
637c478bd9Sstevel@tonic-gate	andcc		%o0, 3, %o4	! is src word aligned
647c478bd9Sstevel@tonic-gate	bz,pt		%icc, .nowalgnd
657c478bd9Sstevel@tonic-gate	mov		%o0, %o2
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate	cmp		%o4, 2		! is src half-word aligned
687c478bd9Sstevel@tonic-gate	be,a,pn		%icc, .s2algn
697c478bd9Sstevel@tonic-gate	lduh		[%o2], %o1
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate	ldub		[%o2], %o1
727c478bd9Sstevel@tonic-gate	tst		%o1		! byte zero?
737c478bd9Sstevel@tonic-gate	bz,pn		%icc, .done
747c478bd9Sstevel@tonic-gate	cmp		%o4, 3		! src is byte aligned
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate	be,pn		%icc, .nowalgnd
777c478bd9Sstevel@tonic-gate	inc		1, %o2
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate	lduh		[%o2], %o1
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate.s2algn:
827c478bd9Sstevel@tonic-gate	srl		%o1, 8, %o4
837c478bd9Sstevel@tonic-gate	tst		%o4
847c478bd9Sstevel@tonic-gate	bz,pn		%icc, .done
857c478bd9Sstevel@tonic-gate	andcc		%o1, 0xff, %g0
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate	bz,pn		%icc, .done
887c478bd9Sstevel@tonic-gate	inc		1, %o2
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate	inc		1, %o2
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate.nowalgnd:
937c478bd9Sstevel@tonic-gate	ld		[%o2], %o1
947c478bd9Sstevel@tonic-gate	sethi		%hi(0x01010101), %o4
957c478bd9Sstevel@tonic-gate	sethi		%hi(0x80808080), %o5
967c478bd9Sstevel@tonic-gate	or		%o4, %lo(0x01010101), %o4
977c478bd9Sstevel@tonic-gate	or		%o5, %lo(0x80808080), %o5
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate	andn		%o5, %o1, %o3
1007c478bd9Sstevel@tonic-gate	sub		%o1, %o4, %g1
1017c478bd9Sstevel@tonic-gate	andcc		%o3, %g1, %g0
1027c478bd9Sstevel@tonic-gate	bnz,a,pn	%icc, .nullfound
1037c478bd9Sstevel@tonic-gate	sethi		%hi(0xff000000), %o4
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate	ld		[%o2+4], %o1
1067c478bd9Sstevel@tonic-gate	inc		4, %o2
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate.loop:						! this should be aligned to 32
1097c478bd9Sstevel@tonic-gate	inc		4, %o2
1107c478bd9Sstevel@tonic-gate	andn		%o5, %o1, %o3		! %o5 = ~word & 0x80808080
1117c478bd9Sstevel@tonic-gate	sub		%o1, %o4, %g1		! %g1 = word - 0x01010101
1127c478bd9Sstevel@tonic-gate	andcc		%o3, %g1, %g0
1137c478bd9Sstevel@tonic-gate	bz,a,pt		%icc, .loop
1147c478bd9Sstevel@tonic-gate	ld		[%o2], %o1
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate	dec		4, %o2
1177c478bd9Sstevel@tonic-gate	sethi		%hi(0xff000000), %o4
1187c478bd9Sstevel@tonic-gate.nullfound:
1197c478bd9Sstevel@tonic-gate	andcc		%o1, %o4, %g0
1207c478bd9Sstevel@tonic-gate	bz,pn		%icc, .done		! first byte zero
1217c478bd9Sstevel@tonic-gate	srl		%o4, 8, %o4
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate	andcc		%o1, %o4, %g0
1247c478bd9Sstevel@tonic-gate	bz,pn		%icc, .done		! second byte zero
1257c478bd9Sstevel@tonic-gate	inc		1, %o2
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate	srl		%o4, 8, %o4
1287c478bd9Sstevel@tonic-gate	andcc		%o1, %o4, %g0
1297c478bd9Sstevel@tonic-gate	bz,pn		%icc, .done		! thrid byte zero
1307c478bd9Sstevel@tonic-gate	inc		1, %o2
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate	inc		1, %o2			! fourth byte zero
1337c478bd9Sstevel@tonic-gate.done:
1347c478bd9Sstevel@tonic-gate	retl
1357c478bd9Sstevel@tonic-gate	sub		%o2, %o0, %o0
1367c478bd9Sstevel@tonic-gate	SET_SIZE(strlen)
1377c478bd9Sstevel@tonic-gate
138