strncmp.S revision 81586
1189251Ssam/*
2214734Srpaulo * Copyright (c) 1993,94 Winning Strategies, Inc.
3252726Srpaulo * All rights reserved.
4189251Ssam *
5252726Srpaulo * Redistribution and use in source and binary forms, with or without
6252726Srpaulo * modification, are permitted provided that the following conditions
7189251Ssam * are met:
8189251Ssam * 1. Redistributions of source code must retain the above copyright
9189251Ssam *    notice, this list of conditions and the following disclaimer.
10189251Ssam * 2. Redistributions in binary form must reproduce the above copyright
11189251Ssam *    notice, this list of conditions and the following disclaimer in the
12189251Ssam *    documentation and/or other materials provided with the distribution.
13189251Ssam * 3. All advertising materials mentioning features or use of this software
14189251Ssam *    must display the following acknowledgement:
15189251Ssam *      This product includes software developed by Winning Strategies, Inc.
16189251Ssam * 4. The name of the author may not be used to endorse or promote products
17189251Ssam *    derived from this software without specific prior written permission
18214734Srpaulo *
19214734Srpaulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20214734Srpaulo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21189251Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22214734Srpaulo * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23214734Srpaulo * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24214734Srpaulo * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25214734Srpaulo * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26189251Ssam * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27214734Srpaulo * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28214734Srpaulo * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29214734Srpaulo */
30214734Srpaulo
31189251Ssam#if defined(LIBC_RCS) && !defined(lint)
32189251Ssam	.text
33189251Ssam        .asciz "$FreeBSD: head/lib/libc/i386/string/strncmp.S 81586 2001-08-13 14:06:34Z ru $"
34189251Ssam#endif /* LIBC_RCS and not lint */
35189251Ssam
36189251Ssam#include "DEFS.h"
37189251Ssam
38214734Srpaulo/*
39214734Srpaulo * strncmp(s1, s2, n)
40214734Srpaulo *	return an integer greater than, equal to, or less than 0,
41189251Ssam *	according as the first n characters of string s1 is greater
42189251Ssam *	than, equal to, or less than the string s2.
43189251Ssam *
44189251Ssam * %eax - pointer to s1
45189251Ssam * %ecx - pointer to s2
46189251Ssam * %edx - length
47189251Ssam *
48189251Ssam * Written by:
49189251Ssam *	J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
50189251Ssam */
51189251Ssam
52189251Ssam/*
53189251Ssam * I've unrolled the loop eight times: large enough to make a
54214734Srpaulo * significant difference, and small enough not to totally trash the
55214734Srpaulo * cache.
56214734Srpaulo *
57189251Ssam * TODO: change all the jz's back to je for consistency.
58189251Ssam */
59189251Ssam
60189251SsamENTRY(strncmp)
61189251Ssam	pushl	%ebx
62189251Ssam	movl	8(%esp),%eax
63189251Ssam	movl	12(%esp),%ecx
64189251Ssam	movl	16(%esp),%edx
65189251Ssam	testl	%edx,%edx
66189251Ssam	jmp	L2			/* Jump into the loop! */
67189251Ssam
68189251Ssam	.align 2,0x90
69189251SsamL1:	incl	%eax
70189251Ssam	incl	%ecx
71189251Ssam	decl	%edx
72189251SsamL2:	jz	L4			/* strings are equal */
73189251Ssam	movb	(%eax),%bl
74189251Ssam	testb	%bl,%bl
75214734Srpaulo	jz	L3
76214734Srpaulo	cmpb	%bl,(%ecx)
77214734Srpaulo	jne	L3
78189251Ssam
79189251Ssam/*
80189251Ssam * XXX it might be best to move the next 4 instructions to the end of the
81189251Ssam * unrolled part of the loop.  The unrolled part would then be
82189251Ssam *	movb n(%eax),%bl; testb %bl, %bl; je L3; cmpb n(%ecx); jne L3
83189251Ssam * or maybe better
84189251Ssam *	movb n(%eax),%bl; cmpb n(%ecx); jne L3; testb %bl,%bl; je return_0
85189251Ssam * for n = 0, 1, ..., 8.  The end of the loop would be
86189251Ssam *	L1: addl $8,%eax; addl $8,%ecx; subl $8,%edx; cmpl $8,%edx; jae Lx
87189251Ssam * where residual counts of 0 to 7 are handled at Lx.  However, this would
88189251Ssam * be slower for short strings.  Cache effects are probably not so
89189251Ssam * important because we are only handling a byte at a time.
90189251Ssam */
91189251Ssam	incl	%eax
92214734Srpaulo	incl	%ecx
93214734Srpaulo	decl	%edx
94214734Srpaulo	jz	L4
95189251Ssam	movb	(%eax),%bl
96214734Srpaulo	testb	%bl,%bl
97214734Srpaulo	jz	L3
98214734Srpaulo	cmpb	%bl,(%ecx)
99189251Ssam	jne	L3
100214734Srpaulo
101214734Srpaulo	incl	%eax
102214734Srpaulo	incl	%ecx
103214734Srpaulo	decl	%edx
104189251Ssam	jz	L4
105214734Srpaulo	movb	(%eax),%bl
106214734Srpaulo	testb	%bl,%bl
107214734Srpaulo	jz	L3
108214734Srpaulo	cmpb	%bl,(%ecx)
109189251Ssam	jne	L3
110214734Srpaulo
111214734Srpaulo	incl	%eax
112214734Srpaulo	incl	%ecx
113214734Srpaulo	decl	%edx
114214734Srpaulo	jz	L4
115214734Srpaulo	movb	(%eax),%bl
116189251Ssam	testb	%bl,%bl
117214734Srpaulo	jz	L3
118214734Srpaulo	cmpb	%bl,(%ecx)
119214734Srpaulo	jne	L3
120214734Srpaulo
121189251Ssam	incl	%eax
122214734Srpaulo	incl	%ecx
123214734Srpaulo	decl	%edx
124214734Srpaulo	jz	L4
125214734Srpaulo	movb	(%eax),%bl
126214734Srpaulo	testb	%bl,%bl
127214734Srpaulo	jz	L3
128214734Srpaulo	cmpb	%bl,(%ecx)
129189251Ssam	jne	L3
130214734Srpaulo
131214734Srpaulo	incl	%eax
132214734Srpaulo	incl	%ecx
133214734Srpaulo	decl	%edx
134214734Srpaulo	jz	L4
135214734Srpaulo	movb	(%eax),%bl
136214734Srpaulo	testb	%bl,%bl
137189251Ssam	jz	L3
138214734Srpaulo	cmpb	%bl,(%ecx)
139214734Srpaulo	jne	L3
140214734Srpaulo
141214734Srpaulo	incl	%eax
142214734Srpaulo	incl	%ecx
143214734Srpaulo	decl	%edx
144214734Srpaulo	jz	L4
145214734Srpaulo	movb	(%eax),%bl
146189251Ssam	testb	%bl,%bl
147214734Srpaulo	jz	L3
148214734Srpaulo	cmpb	%bl,(%ecx)
149214734Srpaulo	jne	L3
150214734Srpaulo
151214734Srpaulo	incl	%eax
152214734Srpaulo	incl	%ecx
153214734Srpaulo	decl	%edx
154214734Srpaulo	jz	L4
155214734Srpaulo	movb	(%eax),%bl
156214734Srpaulo	testb	%bl,%bl
157189251Ssam	jz	L3
158214734Srpaulo	cmpb	%bl,(%ecx)
159214734Srpaulo	je	L1
160214734Srpaulo
161214734Srpaulo	.align 2,0x90
162189251SsamL3:	movzbl	(%eax),%eax		/* unsigned comparison */
163214734Srpaulo	movzbl	(%ecx),%ecx
164214734Srpaulo	subl	%ecx,%eax
165214734Srpaulo	popl	%ebx
166214734Srpaulo	ret
167214734Srpaulo	.align 2,0x90
168214734SrpauloL4:	xorl	%eax,%eax
169214734Srpaulo	popl	%ebx
170214734Srpaulo	ret
171214734Srpaulo