strncmp.S revision 85437
1233294Sstas/*
2102644Snectar * Copyright (c) 1993,94 Winning Strategies, Inc.
355682Smarkm * All rights reserved.
4142403Snectar *
5233294Sstas * Redistribution and use in source and binary forms, with or without
6233294Sstas * modification, are permitted provided that the following conditions
755682Smarkm * are met:
855682Smarkm * 1. Redistributions of source code must retain the above copyright
955682Smarkm *    notice, this list of conditions and the following disclaimer.
1055682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer in the
1255682Smarkm *    documentation and/or other materials provided with the distribution.
1355682Smarkm * 3. All advertising materials mentioning features or use of this software
1455682Smarkm *    must display the following acknowledgement:
1555682Smarkm *      This product includes software developed by Winning Strategies, Inc.
1690926Snectar * 4. The name of the author may not be used to endorse or promote products
1790926Snectar *    derived from this software without specific prior written permission
18233294Sstas *
1990926Snectar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20233294Sstas * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2190926Snectar * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22233294Sstas * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2355682Smarkm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24142403Snectar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25142403Snectar * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2655682Smarkm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2755682Smarkm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28233294Sstas * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2955682Smarkm */
30233294Sstas
31102644Snectar#if defined(LIBC_RCS) && !defined(lint)
32102644Snectar	.text
33102644Snectar        .asciz "$FreeBSD: head/lib/libc/i386/string/strncmp.S 85437 2001-10-24 20:29:14Z peter $"
34127808Snectar#endif /* LIBC_RCS and not lint */
3590926Snectar
36127808Snectar#include <machine/asm.h>
3755682Smarkm
3855682Smarkm/*
3955682Smarkm * strncmp(s1, s2, n)
4055682Smarkm *	return an integer greater than, equal to, or less than 0,
4155682Smarkm *	according as the first n characters of string s1 is greater
4255682Smarkm *	than, equal to, or less than the string s2.
43178825Sdfr *
4455682Smarkm * %eax - pointer to s1
45178825Sdfr * %ecx - pointer to s2
46178825Sdfr * %edx - length
47178825Sdfr *
48142403Snectar * Written by:
49142403Snectar *	J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
50233294Sstas */
51233294Sstas
52233294Sstas/*
53178825Sdfr * I've unrolled the loop eight times: large enough to make a
54178825Sdfr * significant difference, and small enough not to totally trash the
55178825Sdfr * cache.
56233294Sstas *
57233294Sstas * TODO: change all the jz's back to je for consistency.
58233294Sstas */
59233294Sstas
60233294SstasENTRY(strncmp)
61233294Sstas	pushl	%ebx
62233294Sstas	movl	8(%esp),%eax
63233294Sstas	movl	12(%esp),%ecx
64233294Sstas	movl	16(%esp),%edx
65233294Sstas	testl	%edx,%edx
66233294Sstas	jmp	L2			/* Jump into the loop! */
67178825Sdfr
68142403Snectar	.align 2,0x90
69142403SnectarL1:	incl	%eax
70142403Snectar	incl	%ecx
71233294Sstas	decl	%edx
72142403SnectarL2:	jz	L4			/* strings are equal */
73142403Snectar	movb	(%eax),%bl
74142403Snectar	testb	%bl,%bl
75142403Snectar	jz	L3
76142403Snectar	cmpb	%bl,(%ecx)
77142403Snectar	jne	L3
78142403Snectar
79142403Snectar/*
80142403Snectar * XXX it might be best to move the next 4 instructions to the end of the
81142403Snectar * unrolled part of the loop.  The unrolled part would then be
82142403Snectar *	movb n(%eax),%bl; testb %bl, %bl; je L3; cmpb n(%ecx); jne L3
83142403Snectar * or maybe better
84142403Snectar *	movb n(%eax),%bl; cmpb n(%ecx); jne L3; testb %bl,%bl; je return_0
85142403Snectar * for n = 0, 1, ..., 8.  The end of the loop would be
86233294Sstas *	L1: addl $8,%eax; addl $8,%ecx; subl $8,%edx; cmpl $8,%edx; jae Lx
87142403Snectar * where residual counts of 0 to 7 are handled at Lx.  However, this would
88142403Snectar * be slower for short strings.  Cache effects are probably not so
89142403Snectar * important because we are only handling a byte at a time.
90142403Snectar */
91178825Sdfr	incl	%eax
92142403Snectar	incl	%ecx
93142403Snectar	decl	%edx
94142403Snectar	jz	L4
95142403Snectar	movb	(%eax),%bl
96142403Snectar	testb	%bl,%bl
97142403Snectar	jz	L3
98142403Snectar	cmpb	%bl,(%ecx)
99142403Snectar	jne	L3
100233294Sstas
101233294Sstas	incl	%eax
102233294Sstas	incl	%ecx
103233294Sstas	decl	%edx
104233294Sstas	jz	L4
105233294Sstas	movb	(%eax),%bl
106178825Sdfr	testb	%bl,%bl
107178825Sdfr	jz	L3
108178825Sdfr	cmpb	%bl,(%ecx)
109178825Sdfr	jne	L3
110178825Sdfr
111178825Sdfr	incl	%eax
112178825Sdfr	incl	%ecx
113233294Sstas	decl	%edx
114142403Snectar	jz	L4
115142403Snectar	movb	(%eax),%bl
116178825Sdfr	testb	%bl,%bl
117142403Snectar	jz	L3
118142403Snectar	cmpb	%bl,(%ecx)
119233294Sstas	jne	L3
120178825Sdfr
121178825Sdfr	incl	%eax
122178825Sdfr	incl	%ecx
123178825Sdfr	decl	%edx
124178825Sdfr	jz	L4
125233294Sstas	movb	(%eax),%bl
126233294Sstas	testb	%bl,%bl
127233294Sstas	jz	L3
128233294Sstas	cmpb	%bl,(%ecx)
129233294Sstas	jne	L3
130233294Sstas
131233294Sstas	incl	%eax
132233294Sstas	incl	%ecx
133233294Sstas	decl	%edx
134233294Sstas	jz	L4
135233294Sstas	movb	(%eax),%bl
136233294Sstas	testb	%bl,%bl
137233294Sstas	jz	L3
138233294Sstas	cmpb	%bl,(%ecx)
139233294Sstas	jne	L3
140233294Sstas
141178825Sdfr	incl	%eax
142178825Sdfr	incl	%ecx
143178825Sdfr	decl	%edx
144178825Sdfr	jz	L4
145233294Sstas	movb	(%eax),%bl
146142403Snectar	testb	%bl,%bl
147233294Sstas	jz	L3
148178825Sdfr	cmpb	%bl,(%ecx)
149178825Sdfr	jne	L3
150178825Sdfr
151178825Sdfr	incl	%eax
152178825Sdfr	incl	%ecx
153178825Sdfr	decl	%edx
154233294Sstas	jz	L4
155233294Sstas	movb	(%eax),%bl
156233294Sstas	testb	%bl,%bl
157233294Sstas	jz	L3
158233294Sstas	cmpb	%bl,(%ecx)
159233294Sstas	je	L1
160233294Sstas
161233294Sstas	.align 2,0x90
162233294SstasL3:	movzbl	(%eax),%eax		/* unsigned comparison */
163233294Sstas	movzbl	(%ecx),%ecx
164233294Sstas	subl	%ecx,%eax
165178825Sdfr	popl	%ebx
166233294Sstas	ret
167233294Sstas	.align 2,0x90
168233294SstasL4:	xorl	%eax,%eax
169178825Sdfr	popl	%ebx
170178825Sdfr	ret
171178825Sdfr