xref: /onnv-gate/usr/src/lib/libc/amd64/gen/strcmp.s (revision 10583:1058268e7f53)
10Sstevel@tonic-gate/*
2*10583SEdward.Gillett@Sun.COM * CDDL HEADER START
3*10583SEdward.Gillett@Sun.COM *
4*10583SEdward.Gillett@Sun.COM * The contents of this file are subject to the terms of the
5*10583SEdward.Gillett@Sun.COM * Common Development and Distribution License (the "License").
6*10583SEdward.Gillett@Sun.COM * You may not use this file except in compliance with the License.
7*10583SEdward.Gillett@Sun.COM *
8*10583SEdward.Gillett@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10583SEdward.Gillett@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*10583SEdward.Gillett@Sun.COM * See the License for the specific language governing permissions
11*10583SEdward.Gillett@Sun.COM * and limitations under the License.
12*10583SEdward.Gillett@Sun.COM *
13*10583SEdward.Gillett@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*10583SEdward.Gillett@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10583SEdward.Gillett@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*10583SEdward.Gillett@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*10583SEdward.Gillett@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*10583SEdward.Gillett@Sun.COM *
19*10583SEdward.Gillett@Sun.COM * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate
220Sstevel@tonic-gate/*
23*10583SEdward.Gillett@Sun.COM * Copyright (c) 2009, Intel Corporation
240Sstevel@tonic-gate * All rights reserved.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
27*10583SEdward.Gillett@Sun.COM/*
28*10583SEdward.Gillett@Sun.COM *	str[n]cmp - compare chars between two string
29*10583SEdward.Gillett@Sun.COM */
300Sstevel@tonic-gate
310Sstevel@tonic-gate#include "SYS.h"
32*10583SEdward.Gillett@Sun.COM#include "proc64_id.h"
330Sstevel@tonic-gate
340Sstevel@tonic-gate#define LABEL(s) .strcmp/**/s
350Sstevel@tonic-gate
360Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
37*10583SEdward.Gillett@Sun.COM	/*
38*10583SEdward.Gillett@Sun.COM	 * Since the counter, %r11, is unsigned, we branch to strcmp_exitz
39*10583SEdward.Gillett@Sun.COM	 * if the new counter > the old one or is 0.
40*10583SEdward.Gillett@Sun.COM	 */
41*10583SEdward.Gillett@Sun.COM#define UPDATE_STRNCMP_COUNTER				\
42*10583SEdward.Gillett@Sun.COM	/* calculate left number to compare */		\
43*10583SEdward.Gillett@Sun.COM	lea	-16(%rcx, %r11), %r9;			\
44*10583SEdward.Gillett@Sun.COM	cmp	%r9, %r11;				\
45*10583SEdward.Gillett@Sun.COM	jb	LABEL(strcmp_exitz);			\
46*10583SEdward.Gillett@Sun.COM	test	%r9, %r9;				\
47*10583SEdward.Gillett@Sun.COM	je	LABEL(strcmp_exitz);			\
48*10583SEdward.Gillett@Sun.COM	mov	%r9, %r11
49*10583SEdward.Gillett@Sun.COM#else
50*10583SEdward.Gillett@Sun.COM#define UPDATE_STRNCMP_COUNTER
51*10583SEdward.Gillett@Sun.COM#endif
52*10583SEdward.Gillett@Sun.COM
53*10583SEdward.Gillett@Sun.COM	/*
54*10583SEdward.Gillett@Sun.COM	 * This implementation uses SSE to compare up to 16 bytes at a time.
55*10583SEdward.Gillett@Sun.COM	 */
56*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
570Sstevel@tonic-gate	ENTRY(strncmp)
58*10583SEdward.Gillett@Sun.COM	test	%rdx, %rdx
59*10583SEdward.Gillett@Sun.COM	je	LABEL(strcmp_exitz)
60*10583SEdward.Gillett@Sun.COM	mov	%rdx, %r11
610Sstevel@tonic-gate#else
620Sstevel@tonic-gate	ENTRY(strcmp)			/* (const char *, const char *) */
630Sstevel@tonic-gate#endif
64*10583SEdward.Gillett@Sun.COM	mov	%esi, %ecx
65*10583SEdward.Gillett@Sun.COM	mov	%edi, %eax
66*10583SEdward.Gillett@Sun.COM	and	$0x3f, %rcx		/* rsi alignment in cache line */
67*10583SEdward.Gillett@Sun.COM	and	$0x3f, %rax		/* rdi alignment in cache line */
68*10583SEdward.Gillett@Sun.COM	cmp	$0x30, %ecx
69*10583SEdward.Gillett@Sun.COM	ja	LABEL(crosscache)	/* rsi: 16-byte load will cross cache line */
70*10583SEdward.Gillett@Sun.COM	cmp	$0x30, %eax
71*10583SEdward.Gillett@Sun.COM	ja	LABEL(crosscache)	/* rdi: 16-byte load will cross cache line */
72*10583SEdward.Gillett@Sun.COM	movlpd	(%rdi), %xmm1
73*10583SEdward.Gillett@Sun.COM	movlpd	(%rsi), %xmm2
74*10583SEdward.Gillett@Sun.COM	movhpd	8(%rdi), %xmm1
75*10583SEdward.Gillett@Sun.COM	movhpd	8(%rsi), %xmm2
76*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0		/* clear %xmm0 for null char checks */
77*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0		/* Any null chars? */
78*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1		/* compare first 16 bytes for equality */
79*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1		/* packed sub of comparison results*/
80*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
81*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx		/* if first 16 bytes are same, edx == 0xffff */
82*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less16bytes)	/* If not, found mismatch or null char */
83*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
84*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
85*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)	/* finish comparision */
86*10583SEdward.Gillett@Sun.COM#endif
87*10583SEdward.Gillett@Sun.COM	add	$16, %rsi		/* prepare to search next 16 bytes */
88*10583SEdward.Gillett@Sun.COM	add	$16, %rdi		/* prepare to search next 16 bytes */
89*10583SEdward.Gillett@Sun.COM
90*10583SEdward.Gillett@Sun.COM	/*
91*10583SEdward.Gillett@Sun.COM	 * Determine rdi and rsi string offsets from 16-byte alignment.
92*10583SEdward.Gillett@Sun.COM	 * Use relative offset difference between the two to determine which case
93*10583SEdward.Gillett@Sun.COM	 * below to use.
94*10583SEdward.Gillett@Sun.COM	 */
95*10583SEdward.Gillett@Sun.COM	.p2align 4
96*10583SEdward.Gillett@Sun.COMLABEL(crosscache):
97*10583SEdward.Gillett@Sun.COM	and	$0xfffffffffffffff0, %rsi	/* force %rsi to be 16 byte aligned */
98*10583SEdward.Gillett@Sun.COM	and	$0xfffffffffffffff0, %rdi	/* force %rdi to be 16 byte aligned */
99*10583SEdward.Gillett@Sun.COM	mov	$0xffff, %edx			/* for equivalent offset */
100*10583SEdward.Gillett@Sun.COM	xor	%r8d, %r8d
101*10583SEdward.Gillett@Sun.COM	and	$0xf, %ecx			/* offset of rsi */
102*10583SEdward.Gillett@Sun.COM	and	$0xf, %eax			/* offset of rdi */
103*10583SEdward.Gillett@Sun.COM	cmp	%eax, %ecx
104*10583SEdward.Gillett@Sun.COM	je	LABEL(ashr_0)			/* both strings have the same alignment */
105*10583SEdward.Gillett@Sun.COM	ja	LABEL(bigger)
106*10583SEdward.Gillett@Sun.COM	mov	%edx, %r8d			/* r8d is offset flag for exit tail */
107*10583SEdward.Gillett@Sun.COM	xchg	%ecx, %eax
108*10583SEdward.Gillett@Sun.COM	xchg	%rsi, %rdi
109*10583SEdward.Gillett@Sun.COMLABEL(bigger):
110*10583SEdward.Gillett@Sun.COM	mov	%rcx, %r9
111*10583SEdward.Gillett@Sun.COM	sub	%rax, %r9
112*10583SEdward.Gillett@Sun.COM	lea	LABEL(unaligned_table)(%rip), %r10
113*10583SEdward.Gillett@Sun.COM	movslq	(%r10, %r9, 4), %r9
114*10583SEdward.Gillett@Sun.COM	lea	(%r10, %r9), %r10
115*10583SEdward.Gillett@Sun.COM	jmp	*%r10				/* jump to corresponding case */
116*10583SEdward.Gillett@Sun.COM
117*10583SEdward.Gillett@Sun.COM/*
118*10583SEdward.Gillett@Sun.COM * ashr_0 handles the following cases:
119*10583SEdward.Gillett@Sun.COM * 	str1 offset = str2 offset
120*10583SEdward.Gillett@Sun.COM */
121*10583SEdward.Gillett@Sun.COM	.p2align 4
122*10583SEdward.Gillett@Sun.COMLABEL(ashr_0):
123*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
124*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0			/* clear %xmm0 for null char check */
125*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0			/* Any null chars? */
126*10583SEdward.Gillett@Sun.COM	pcmpeqb	(%rdi), %xmm1			/* compare 16 bytes for equality */
127*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1			/* packed sub of comparison results*/
128*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %r9d
129*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx			/* adjust 0xffff for offset */
130*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d			/* adjust for 16-byte offset */
131*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
132*10583SEdward.Gillett@Sun.COM	/*
133*10583SEdward.Gillett@Sun.COM	 * edx must be the same with r9d if in left byte (16-rcx) is equal to
134*10583SEdward.Gillett@Sun.COM	 * the start from (16-rax) and no null char was seen.
135*10583SEdward.Gillett@Sun.COM	 */
136*10583SEdward.Gillett@Sun.COM	jne	LABEL(less32bytes)		/* mismatch or null char */
137*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
138*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx
139*10583SEdward.Gillett@Sun.COM	mov	$16, %r9
140*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0			/* clear xmm0, may have changed above */
141*10583SEdward.Gillett@Sun.COM
142*10583SEdward.Gillett@Sun.COM	/*
143*10583SEdward.Gillett@Sun.COM	 * Now both strings are aligned at 16-byte boundary. Loop over strings
144*10583SEdward.Gillett@Sun.COM	 * checking 32-bytes per iteration.
145*10583SEdward.Gillett@Sun.COM	 */
146*10583SEdward.Gillett@Sun.COM	.p2align 4
147*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_0):
148*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
149*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
150*10583SEdward.Gillett@Sun.COM
151*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
152*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
153*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
154*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
155*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
156*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)		/* mismatch or null char seen */
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
159*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
160*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1610Sstevel@tonic-gate#endif
162*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
163*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
164*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
165*10583SEdward.Gillett@Sun.COM
166*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
167*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
168*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
169*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
170*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
171*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
172*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
173*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
174*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
175*10583SEdward.Gillett@Sun.COM#endif
176*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
177*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_0)
1780Sstevel@tonic-gate
179*10583SEdward.Gillett@Sun.COM/*
180*10583SEdward.Gillett@Sun.COM * ashr_1 handles the following cases:
181*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 15
182*10583SEdward.Gillett@Sun.COM */
183*10583SEdward.Gillett@Sun.COM	.p2align 4
184*10583SEdward.Gillett@Sun.COMLABEL(ashr_1):
185*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
186*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
187*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
188*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0		/* Any null chars? */
189*10583SEdward.Gillett@Sun.COM	pslldq	$15, %xmm2		/* shift first string to align with second */
190*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2		/* compare 16 bytes for equality */
191*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2		/* packed sub of comparison results*/
192*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
193*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx		/* adjust 0xffff for offset */
194*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d		/* adjust for 16-byte offset */
195*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
196*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)	/* mismatch or null char seen */
197*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
198*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
1990Sstevel@tonic-gate
200*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
201*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx		/* index for loads */
202*10583SEdward.Gillett@Sun.COM	mov	$1, %r9d		/* rdi bytes already examined. Used in exit code */
203*10583SEdward.Gillett@Sun.COM	/*
204*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
205*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
206*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
207*10583SEdward.Gillett@Sun.COM	 */
208*10583SEdward.Gillett@Sun.COM	lea	1(%rdi), %r10
209*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10		/* offset into 4K page */
210*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K pagesize */
211*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
2120Sstevel@tonic-gate
213*10583SEdward.Gillett@Sun.COM	.p2align 4
214*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_1):
215*10583SEdward.Gillett@Sun.COM	add	$16, %r10
216*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_1)	/* cross page boundary */
217*10583SEdward.Gillett@Sun.COM
218*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_1):
219*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
220*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
221*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4		 /* store for next cycle */
2220Sstevel@tonic-gate
223*10583SEdward.Gillett@Sun.COM	psrldq	$1, %xmm3
224*10583SEdward.Gillett@Sun.COM	pslldq	$15, %xmm2
225*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2		/* merge into one 16byte value */
226*10583SEdward.Gillett@Sun.COM
227*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
228*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
229*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
230*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
231*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
232*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
235*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
236*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
2370Sstevel@tonic-gate#endif
238*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
239*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
240*10583SEdward.Gillett@Sun.COM
241*10583SEdward.Gillett@Sun.COM	add	$16, %r10
242*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_1)	/* cross page boundary */
2430Sstevel@tonic-gate
244*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
245*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
246*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4		/* store for next cycle */
2470Sstevel@tonic-gate
248*10583SEdward.Gillett@Sun.COM	psrldq	$1, %xmm3
249*10583SEdward.Gillett@Sun.COM	pslldq 	$15, %xmm2
250*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2		/* merge into one 16byte value */
2510Sstevel@tonic-gate
252*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
253*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
254*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
255*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
256*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
257*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
2580Sstevel@tonic-gate
2597953SNobutomo.Nakano@Sun.COM#ifdef USE_AS_STRNCMP
260*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
261*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
262*10583SEdward.Gillett@Sun.COM#endif
263*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
264*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
265*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_1)
266*10583SEdward.Gillett@Sun.COM
267*10583SEdward.Gillett@Sun.COM	/*
268*10583SEdward.Gillett@Sun.COM	 * Nibble avoids loads across page boundary. This is to avoid a potential
269*10583SEdward.Gillett@Sun.COM	 * access into unmapped memory.
270*10583SEdward.Gillett@Sun.COM	 */
271*10583SEdward.Gillett@Sun.COM	.p2align 4
272*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_1):
273*10583SEdward.Gillett@Sun.COM	psrldq	$1, %xmm4
274*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
275*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
276*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
277*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
278*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
279*10583SEdward.Gillett@Sun.COM	sub	$0x7fff, %edx
280*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
281*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
282*10583SEdward.Gillett@Sun.COM	cmp	$15, %r11
283*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
284*10583SEdward.Gillett@Sun.COM#endif
285*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
286*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
287*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_1)
288*10583SEdward.Gillett@Sun.COM
289*10583SEdward.Gillett@Sun.COM/*
290*10583SEdward.Gillett@Sun.COM * ashr_2 handles the following cases:
291*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 14
292*10583SEdward.Gillett@Sun.COM */
293*10583SEdward.Gillett@Sun.COM	.p2align 4
294*10583SEdward.Gillett@Sun.COMLABEL(ashr_2):
295*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
296*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
297*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
298*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
299*10583SEdward.Gillett@Sun.COM	pslldq	$14, %xmm2
300*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
301*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
302*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
303*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
304*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
305*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
306*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
307*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
308*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
309*10583SEdward.Gillett@Sun.COM
310*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
311*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
312*10583SEdward.Gillett@Sun.COM	mov	$2, %r9d	/* rdi bytes already examined. Used in exit code */
313*10583SEdward.Gillett@Sun.COM	/*
314*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
315*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
316*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
317*10583SEdward.Gillett@Sun.COM	 */
318*10583SEdward.Gillett@Sun.COM	lea	2(%rdi), %r10
319*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
320*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
321*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
322*10583SEdward.Gillett@Sun.COM
323*10583SEdward.Gillett@Sun.COM	.p2align 4
324*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_2):
325*10583SEdward.Gillett@Sun.COM	add	$16, %r10
326*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_2)
327*10583SEdward.Gillett@Sun.COM
328*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_2):
329*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
330*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
331*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
332*10583SEdward.Gillett@Sun.COM
333*10583SEdward.Gillett@Sun.COM	psrldq	$2, %xmm3
334*10583SEdward.Gillett@Sun.COM	pslldq	$14, %xmm2
335*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
336*10583SEdward.Gillett@Sun.COM
337*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
338*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
339*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
340*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
341*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
342*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
343*10583SEdward.Gillett@Sun.COM
344*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
345*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
346*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
3477953SNobutomo.Nakano@Sun.COM#endif
3487953SNobutomo.Nakano@Sun.COM
349*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
350*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
3510Sstevel@tonic-gate
352*10583SEdward.Gillett@Sun.COM	add	$16, %r10
353*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_2)	/* cross page boundary */
354*10583SEdward.Gillett@Sun.COM
355*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
356*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
357*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
3580Sstevel@tonic-gate
359*10583SEdward.Gillett@Sun.COM	psrldq	$2, %xmm3
360*10583SEdward.Gillett@Sun.COM	pslldq 	$14, %xmm2
361*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
3620Sstevel@tonic-gate
363*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
364*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
365*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
366*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
367*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
368*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
371*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
372*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
3730Sstevel@tonic-gate#endif
3740Sstevel@tonic-gate
375*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
376*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
377*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_2)
3780Sstevel@tonic-gate
379*10583SEdward.Gillett@Sun.COM	.p2align 4
380*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_2):
381*10583SEdward.Gillett@Sun.COM	psrldq	$2, %xmm4
382*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
383*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
384*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
385*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
386*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
387*10583SEdward.Gillett@Sun.COM	sub	$0x3fff, %edx
388*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
389*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
390*10583SEdward.Gillett@Sun.COM	cmp	$14, %r11
391*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
392*10583SEdward.Gillett@Sun.COM#endif
393*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
394*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
395*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_2)
3960Sstevel@tonic-gate
397*10583SEdward.Gillett@Sun.COM/*
398*10583SEdward.Gillett@Sun.COM * ashr_3 handles the following cases:
399*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 13
400*10583SEdward.Gillett@Sun.COM */
401*10583SEdward.Gillett@Sun.COM	.p2align 4
402*10583SEdward.Gillett@Sun.COMLABEL(ashr_3):
403*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
404*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
405*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
406*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
407*10583SEdward.Gillett@Sun.COM	pslldq	$13, %xmm2
408*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
409*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
410*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
411*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
412*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
413*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
414*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
415*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
416*10583SEdward.Gillett@Sun.COM
417*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
4180Sstevel@tonic-gate
419*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
420*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
421*10583SEdward.Gillett@Sun.COM	mov	$3, %r9d	/* rdi bytes already examined. Used in exit code */
422*10583SEdward.Gillett@Sun.COM	/*
423*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
424*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
425*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
426*10583SEdward.Gillett@Sun.COM	 */
427*10583SEdward.Gillett@Sun.COM	lea	3(%rdi), %r10
428*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
429*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
430*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
4310Sstevel@tonic-gate
432*10583SEdward.Gillett@Sun.COM	.p2align 4
433*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_3):
434*10583SEdward.Gillett@Sun.COM	add	$16, %r10
435*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_3)
436*10583SEdward.Gillett@Sun.COM
437*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_3):
438*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
439*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
440*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
441*10583SEdward.Gillett@Sun.COM
442*10583SEdward.Gillett@Sun.COM	psrldq	$3, %xmm3
443*10583SEdward.Gillett@Sun.COM	pslldq	$13, %xmm2
444*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
445*10583SEdward.Gillett@Sun.COM
446*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
447*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
448*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
449*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
450*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
451*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
4520Sstevel@tonic-gate
4530Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
454*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
455*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
456*10583SEdward.Gillett@Sun.COM#endif
457*10583SEdward.Gillett@Sun.COM
458*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
459*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
460*10583SEdward.Gillett@Sun.COM
461*10583SEdward.Gillett@Sun.COM	add	$16, %r10
462*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_3)	/* cross page boundary */
463*10583SEdward.Gillett@Sun.COM
464*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
465*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
466*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
467*10583SEdward.Gillett@Sun.COM
468*10583SEdward.Gillett@Sun.COM	psrldq	$3, %xmm3
469*10583SEdward.Gillett@Sun.COM	pslldq 	$13, %xmm2
470*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
471*10583SEdward.Gillett@Sun.COM
472*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
473*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
474*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
475*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
476*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
477*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
478*10583SEdward.Gillett@Sun.COM
479*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
480*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
481*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
4820Sstevel@tonic-gate#endif
4830Sstevel@tonic-gate
484*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
485*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
486*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_3)
487*10583SEdward.Gillett@Sun.COM
488*10583SEdward.Gillett@Sun.COM	.p2align 4
489*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_3):
490*10583SEdward.Gillett@Sun.COM	psrldq	$3, %xmm4
491*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
492*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
493*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
494*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
495*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
496*10583SEdward.Gillett@Sun.COM	sub	$0x1fff, %edx
497*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
498*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
499*10583SEdward.Gillett@Sun.COM	cmp	$13, %r11
500*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
501*10583SEdward.Gillett@Sun.COM#endif
502*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
503*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
504*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_3)
5050Sstevel@tonic-gate
506*10583SEdward.Gillett@Sun.COM/*
507*10583SEdward.Gillett@Sun.COM * ashr_4 handles the following cases:
508*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 12
509*10583SEdward.Gillett@Sun.COM */
510*10583SEdward.Gillett@Sun.COM	.p2align 4
511*10583SEdward.Gillett@Sun.COMLABEL(ashr_4):
512*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
513*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
514*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
515*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
516*10583SEdward.Gillett@Sun.COM	pslldq	$12, %xmm2
517*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
518*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
519*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
520*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
521*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
522*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
523*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
524*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
525*10583SEdward.Gillett@Sun.COM
526*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
5270Sstevel@tonic-gate
528*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
529*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
530*10583SEdward.Gillett@Sun.COM	mov	$4, %r9d	/* rdi bytes already examined. Used in exit code */
531*10583SEdward.Gillett@Sun.COM	/*
532*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
533*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
534*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
535*10583SEdward.Gillett@Sun.COM	 */
536*10583SEdward.Gillett@Sun.COM	lea	4(%rdi), %r10
537*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
538*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
539*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
540*10583SEdward.Gillett@Sun.COM
541*10583SEdward.Gillett@Sun.COM	.p2align 4
542*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_4):
543*10583SEdward.Gillett@Sun.COM	add	$16, %r10
544*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_4)
545*10583SEdward.Gillett@Sun.COM
546*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_4):
547*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
548*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
549*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
550*10583SEdward.Gillett@Sun.COM
551*10583SEdward.Gillett@Sun.COM	psrldq	$4, %xmm3
552*10583SEdward.Gillett@Sun.COM	pslldq	$12, %xmm2
553*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
5540Sstevel@tonic-gate
555*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
556*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
557*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
558*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
559*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
560*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
561*10583SEdward.Gillett@Sun.COM
562*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
563*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
564*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
565*10583SEdward.Gillett@Sun.COM#endif
566*10583SEdward.Gillett@Sun.COM
567*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
568*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
5690Sstevel@tonic-gate
570*10583SEdward.Gillett@Sun.COM	add	$16, %r10
571*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_4)	/* cross page boundary */
572*10583SEdward.Gillett@Sun.COM
573*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
574*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
575*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
5760Sstevel@tonic-gate
577*10583SEdward.Gillett@Sun.COM	psrldq	$4, %xmm3
578*10583SEdward.Gillett@Sun.COM	pslldq 	$12, %xmm2
579*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
580*10583SEdward.Gillett@Sun.COM
581*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
582*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
583*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
584*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
585*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
586*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
589*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
590*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
5910Sstevel@tonic-gate#endif
5920Sstevel@tonic-gate
593*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
594*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
595*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_4)
596*10583SEdward.Gillett@Sun.COM
597*10583SEdward.Gillett@Sun.COM	.p2align 4
598*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_4):
599*10583SEdward.Gillett@Sun.COM	psrldq	$4, %xmm4
600*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
601*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
602*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
603*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
604*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
605*10583SEdward.Gillett@Sun.COM	sub	$0x0fff, %edx
606*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
607*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
608*10583SEdward.Gillett@Sun.COM	cmp	$12, %r11
609*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
610*10583SEdward.Gillett@Sun.COM#endif
611*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
612*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
613*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_4)
6140Sstevel@tonic-gate
615*10583SEdward.Gillett@Sun.COM/*
616*10583SEdward.Gillett@Sun.COM * ashr_5 handles the following cases:
617*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 11
618*10583SEdward.Gillett@Sun.COM */
619*10583SEdward.Gillett@Sun.COM	.p2align 4
620*10583SEdward.Gillett@Sun.COMLABEL(ashr_5):
621*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
622*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
623*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
624*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
625*10583SEdward.Gillett@Sun.COM	pslldq	$11, %xmm2
626*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
627*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
628*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
629*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
630*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
631*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
632*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
633*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
634*10583SEdward.Gillett@Sun.COM
635*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
6360Sstevel@tonic-gate
637*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
638*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
639*10583SEdward.Gillett@Sun.COM	mov	$5, %r9d	/* rdi bytes already examined. Used in exit code */
640*10583SEdward.Gillett@Sun.COM	/*
641*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
642*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
643*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
644*10583SEdward.Gillett@Sun.COM	 */
645*10583SEdward.Gillett@Sun.COM	lea	5(%rdi), %r10
646*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
647*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
648*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
649*10583SEdward.Gillett@Sun.COM
650*10583SEdward.Gillett@Sun.COM	.p2align 4
651*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_5):
652*10583SEdward.Gillett@Sun.COM	add	$16, %r10
653*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_5)
654*10583SEdward.Gillett@Sun.COM
655*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_5):
656*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
657*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
658*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
659*10583SEdward.Gillett@Sun.COM
660*10583SEdward.Gillett@Sun.COM	psrldq	$5, %xmm3
661*10583SEdward.Gillett@Sun.COM	pslldq	$11, %xmm2
662*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
6630Sstevel@tonic-gate
664*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
665*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
666*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
667*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
668*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
669*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
670*10583SEdward.Gillett@Sun.COM
671*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
672*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
673*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
674*10583SEdward.Gillett@Sun.COM#endif
675*10583SEdward.Gillett@Sun.COM
676*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
677*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
6780Sstevel@tonic-gate
679*10583SEdward.Gillett@Sun.COM	add	$16, %r10
680*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_5)	/* cross page boundary */
681*10583SEdward.Gillett@Sun.COM
682*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
683*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
684*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
6850Sstevel@tonic-gate
686*10583SEdward.Gillett@Sun.COM	psrldq	$5, %xmm3
687*10583SEdward.Gillett@Sun.COM	pslldq 	$11, %xmm2
688*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
689*10583SEdward.Gillett@Sun.COM
690*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
691*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
692*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
693*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
694*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
695*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
6960Sstevel@tonic-gate
6970Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
698*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
699*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
7000Sstevel@tonic-gate#endif
7010Sstevel@tonic-gate
702*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
703*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
704*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_5)
705*10583SEdward.Gillett@Sun.COM
706*10583SEdward.Gillett@Sun.COM	.p2align 4
707*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_5):
708*10583SEdward.Gillett@Sun.COM	psrldq	$5, %xmm4
709*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
710*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
711*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
712*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
713*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
714*10583SEdward.Gillett@Sun.COM	sub	$0x07ff, %edx
715*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
716*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
717*10583SEdward.Gillett@Sun.COM	cmp	$11, %r11
718*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
719*10583SEdward.Gillett@Sun.COM#endif
720*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
721*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
722*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_5)
7230Sstevel@tonic-gate
724*10583SEdward.Gillett@Sun.COM/*
725*10583SEdward.Gillett@Sun.COM * ashr_6 handles the following cases:
726*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 10
727*10583SEdward.Gillett@Sun.COM */
728*10583SEdward.Gillett@Sun.COM	.p2align 4
729*10583SEdward.Gillett@Sun.COMLABEL(ashr_6):
730*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
731*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
732*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
733*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
734*10583SEdward.Gillett@Sun.COM	pslldq	$10, %xmm2
735*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
736*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
737*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
738*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
739*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
740*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
741*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
742*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
743*10583SEdward.Gillett@Sun.COM
744*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
7450Sstevel@tonic-gate
746*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
747*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
748*10583SEdward.Gillett@Sun.COM	mov	$6, %r9d	/* rdi bytes already examined. Used in exit code */
749*10583SEdward.Gillett@Sun.COM	/*
750*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
751*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
752*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
753*10583SEdward.Gillett@Sun.COM	 */
754*10583SEdward.Gillett@Sun.COM	lea	6(%rdi), %r10
755*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
756*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
757*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
758*10583SEdward.Gillett@Sun.COM
759*10583SEdward.Gillett@Sun.COM	.p2align 4
760*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_6):
761*10583SEdward.Gillett@Sun.COM	add	$16, %r10
762*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_6)
763*10583SEdward.Gillett@Sun.COM
764*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_6):
765*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
766*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
767*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
768*10583SEdward.Gillett@Sun.COM
769*10583SEdward.Gillett@Sun.COM	psrldq	$6, %xmm3
770*10583SEdward.Gillett@Sun.COM	pslldq	$10, %xmm2
771*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
7720Sstevel@tonic-gate
773*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
774*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
775*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
776*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
777*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
778*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
779*10583SEdward.Gillett@Sun.COM
780*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
781*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
782*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
783*10583SEdward.Gillett@Sun.COM#endif
784*10583SEdward.Gillett@Sun.COM
785*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
786*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
7870Sstevel@tonic-gate
788*10583SEdward.Gillett@Sun.COM	add	$16, %r10
789*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_6)	/* cross page boundary */
790*10583SEdward.Gillett@Sun.COM
791*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
792*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
793*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
7940Sstevel@tonic-gate
795*10583SEdward.Gillett@Sun.COM	psrldq	$6, %xmm3
796*10583SEdward.Gillett@Sun.COM	pslldq 	$10, %xmm2
797*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
798*10583SEdward.Gillett@Sun.COM
799*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
800*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
801*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
802*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
803*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
804*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
8050Sstevel@tonic-gate
8060Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
807*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
808*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
809*10583SEdward.Gillett@Sun.COM#endif
810*10583SEdward.Gillett@Sun.COM
811*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
812*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
813*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_6)
814*10583SEdward.Gillett@Sun.COM
815*10583SEdward.Gillett@Sun.COM	.p2align 4
816*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_6):
817*10583SEdward.Gillett@Sun.COM	psrldq	$6, %xmm4
818*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
819*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
820*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
821*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
822*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
823*10583SEdward.Gillett@Sun.COM	sub	$0x03ff, %edx
824*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
825*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
826*10583SEdward.Gillett@Sun.COM	cmp	$10, %r11
827*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
828*10583SEdward.Gillett@Sun.COM#endif
829*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
830*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
831*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_6)
832*10583SEdward.Gillett@Sun.COM
833*10583SEdward.Gillett@Sun.COM/*
834*10583SEdward.Gillett@Sun.COM * ashr_7 handles the following cases:
835*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 9
836*10583SEdward.Gillett@Sun.COM */
837*10583SEdward.Gillett@Sun.COM	.p2align 4
838*10583SEdward.Gillett@Sun.COMLABEL(ashr_7):
839*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
840*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
841*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
842*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
843*10583SEdward.Gillett@Sun.COM	pslldq	$9, %xmm2
844*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
845*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
846*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
847*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
848*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
849*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
850*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
851*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
852*10583SEdward.Gillett@Sun.COM
853*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
854*10583SEdward.Gillett@Sun.COM
855*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
856*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
857*10583SEdward.Gillett@Sun.COM	mov	$7, %r9d	/* rdi bytes already examined. Used in exit code */
858*10583SEdward.Gillett@Sun.COM	/*
859*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
860*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
861*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
862*10583SEdward.Gillett@Sun.COM	 */
863*10583SEdward.Gillett@Sun.COM	lea	7(%rdi), %r10
864*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
865*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
866*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
867*10583SEdward.Gillett@Sun.COM
868*10583SEdward.Gillett@Sun.COM	.p2align 4
869*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_7):
870*10583SEdward.Gillett@Sun.COM	add	$16, %r10
871*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_7)
872*10583SEdward.Gillett@Sun.COM
873*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_7):
874*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
875*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
876*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
877*10583SEdward.Gillett@Sun.COM
878*10583SEdward.Gillett@Sun.COM	psrldq	$7, %xmm3
879*10583SEdward.Gillett@Sun.COM	pslldq	$9, %xmm2
880*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
881*10583SEdward.Gillett@Sun.COM
882*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
883*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
884*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
885*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
886*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
887*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
888*10583SEdward.Gillett@Sun.COM
889*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
890*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
891*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
8920Sstevel@tonic-gate#endif
8930Sstevel@tonic-gate
894*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
895*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
8960Sstevel@tonic-gate
897*10583SEdward.Gillett@Sun.COM	add	$16, %r10
898*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_7)	/* cross page boundary */
899*10583SEdward.Gillett@Sun.COM
900*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
901*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
902*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
9030Sstevel@tonic-gate
904*10583SEdward.Gillett@Sun.COM	psrldq	$7, %xmm3
905*10583SEdward.Gillett@Sun.COM	pslldq 	$9, %xmm2
906*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
9070Sstevel@tonic-gate
908*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
909*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
910*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
911*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
912*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
913*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
9140Sstevel@tonic-gate
9150Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
916*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
917*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
918*10583SEdward.Gillett@Sun.COM#endif
919*10583SEdward.Gillett@Sun.COM
920*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
921*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
922*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_7)
923*10583SEdward.Gillett@Sun.COM
924*10583SEdward.Gillett@Sun.COM	.p2align 4
925*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_7):
926*10583SEdward.Gillett@Sun.COM	psrldq	$7, %xmm4
927*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
928*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
929*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
930*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
931*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
932*10583SEdward.Gillett@Sun.COM	sub	$0x01ff, %edx
933*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
934*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
935*10583SEdward.Gillett@Sun.COM	cmp	$9, %r11
936*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
937*10583SEdward.Gillett@Sun.COM#endif
938*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
939*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
940*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_7)
941*10583SEdward.Gillett@Sun.COM
942*10583SEdward.Gillett@Sun.COM/*
943*10583SEdward.Gillett@Sun.COM * ashr_8 handles the following cases:
944*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 8
945*10583SEdward.Gillett@Sun.COM */
946*10583SEdward.Gillett@Sun.COM	.p2align 4
947*10583SEdward.Gillett@Sun.COMLABEL(ashr_8):
948*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
949*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
950*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
951*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
952*10583SEdward.Gillett@Sun.COM	pslldq	$8, %xmm2
953*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
954*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
955*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
956*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
957*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
958*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
959*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
960*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
961*10583SEdward.Gillett@Sun.COM
962*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
963*10583SEdward.Gillett@Sun.COM
964*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
965*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
966*10583SEdward.Gillett@Sun.COM	mov	$8, %r9d	/* rdi bytes already examined. Used in exit code */
967*10583SEdward.Gillett@Sun.COM	/*
968*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
969*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
970*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
971*10583SEdward.Gillett@Sun.COM	 */
972*10583SEdward.Gillett@Sun.COM	lea	8(%rdi), %r10
973*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
974*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
975*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
976*10583SEdward.Gillett@Sun.COM
977*10583SEdward.Gillett@Sun.COM	.p2align 4
978*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_8):
979*10583SEdward.Gillett@Sun.COM	add	$16, %r10
980*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_8)
981*10583SEdward.Gillett@Sun.COM
982*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_8):
983*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
984*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
985*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
986*10583SEdward.Gillett@Sun.COM
987*10583SEdward.Gillett@Sun.COM	psrldq	$8, %xmm3
988*10583SEdward.Gillett@Sun.COM	pslldq	$8, %xmm2
989*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
990*10583SEdward.Gillett@Sun.COM
991*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
992*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
993*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
994*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
995*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
996*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
997*10583SEdward.Gillett@Sun.COM
998*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
999*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1000*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1001*10583SEdward.Gillett@Sun.COM#endif
1002*10583SEdward.Gillett@Sun.COM
1003*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1004*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1005*10583SEdward.Gillett@Sun.COM
1006*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1007*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_8)	/* cross page boundary */
1008*10583SEdward.Gillett@Sun.COM
1009*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1010*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1011*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1012*10583SEdward.Gillett@Sun.COM
1013*10583SEdward.Gillett@Sun.COM	psrldq	$8, %xmm3
1014*10583SEdward.Gillett@Sun.COM	pslldq 	$8, %xmm2
1015*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1016*10583SEdward.Gillett@Sun.COM
1017*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1018*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1019*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1020*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1021*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1022*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1023*10583SEdward.Gillett@Sun.COM
1024*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1025*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1026*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
10270Sstevel@tonic-gate#endif
10280Sstevel@tonic-gate
1029*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1030*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1031*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_8)
10320Sstevel@tonic-gate
1033*10583SEdward.Gillett@Sun.COM	.p2align 4
1034*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_8):
1035*10583SEdward.Gillett@Sun.COM	psrldq	$8, %xmm4
1036*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1037*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1038*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
1039*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1040*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1041*10583SEdward.Gillett@Sun.COM	sub	$0x00ff, %edx
1042*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1043*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1044*10583SEdward.Gillett@Sun.COM	cmp	$8, %r11
1045*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1046*10583SEdward.Gillett@Sun.COM#endif
1047*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
1048*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
1049*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_8)
10500Sstevel@tonic-gate
1051*10583SEdward.Gillett@Sun.COM/*
1052*10583SEdward.Gillett@Sun.COM * ashr_9 handles the following cases:
1053*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 7
1054*10583SEdward.Gillett@Sun.COM */
1055*10583SEdward.Gillett@Sun.COM	.p2align 4
1056*10583SEdward.Gillett@Sun.COMLABEL(ashr_9):
1057*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1058*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
1059*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
1060*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1061*10583SEdward.Gillett@Sun.COM	pslldq	$7, %xmm2
1062*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
1063*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
1064*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
1065*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
1066*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
1067*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
1068*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
1069*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
1070*10583SEdward.Gillett@Sun.COM
1071*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
10720Sstevel@tonic-gate
1073*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1074*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
1075*10583SEdward.Gillett@Sun.COM	mov	$9, %r9d	/* rdi bytes already examined. Used in exit code */
1076*10583SEdward.Gillett@Sun.COM	/*
1077*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
1078*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
1079*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
1080*10583SEdward.Gillett@Sun.COM	 */
1081*10583SEdward.Gillett@Sun.COM	lea	9(%rdi), %r10
1082*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
1083*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
1084*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
10850Sstevel@tonic-gate
1086*10583SEdward.Gillett@Sun.COM	.p2align 4
1087*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_9):
1088*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1089*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_9)
1090*10583SEdward.Gillett@Sun.COM
1091*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_9):
1092*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1093*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1094*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
10950Sstevel@tonic-gate
1096*10583SEdward.Gillett@Sun.COM	psrldq	$9, %xmm3
1097*10583SEdward.Gillett@Sun.COM	pslldq	$7, %xmm2
1098*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1099*10583SEdward.Gillett@Sun.COM
1100*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1101*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1102*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1103*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1104*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1105*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
11060Sstevel@tonic-gate
11070Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1108*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1109*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1110*10583SEdward.Gillett@Sun.COM#endif
1111*10583SEdward.Gillett@Sun.COM
1112*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1113*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1114*10583SEdward.Gillett@Sun.COM
1115*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1116*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_9)	/* cross page boundary */
1117*10583SEdward.Gillett@Sun.COM
1118*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1119*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1120*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1121*10583SEdward.Gillett@Sun.COM
1122*10583SEdward.Gillett@Sun.COM	psrldq	$9, %xmm3
1123*10583SEdward.Gillett@Sun.COM	pslldq 	$7, %xmm2
1124*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1125*10583SEdward.Gillett@Sun.COM
1126*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1127*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1128*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1129*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1130*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1131*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1132*10583SEdward.Gillett@Sun.COM
1133*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1134*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1135*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1136*10583SEdward.Gillett@Sun.COM#endif
1137*10583SEdward.Gillett@Sun.COM
1138*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1139*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3		/* store for next cycle */
1140*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_9)
1141*10583SEdward.Gillett@Sun.COM
1142*10583SEdward.Gillett@Sun.COM	.p2align 4
1143*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_9):
1144*10583SEdward.Gillett@Sun.COM	psrldq	$9, %xmm4
1145*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1146*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1147*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
1148*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1149*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1150*10583SEdward.Gillett@Sun.COM	sub	$0x007f, %edx
1151*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1152*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1153*10583SEdward.Gillett@Sun.COM	cmp	$7, %r11
1154*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1155*10583SEdward.Gillett@Sun.COM#endif
1156*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
1157*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
1158*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_9)
1159*10583SEdward.Gillett@Sun.COM
1160*10583SEdward.Gillett@Sun.COM/*
1161*10583SEdward.Gillett@Sun.COM * ashr_10 handles the following cases:
1162*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 6
1163*10583SEdward.Gillett@Sun.COM */
1164*10583SEdward.Gillett@Sun.COM	.p2align 4
1165*10583SEdward.Gillett@Sun.COMLABEL(ashr_10):
1166*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1167*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
1168*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
1169*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1170*10583SEdward.Gillett@Sun.COM	pslldq	$6, %xmm2
1171*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
1172*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
1173*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
1174*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
1175*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
1176*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
1177*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
1178*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
1179*10583SEdward.Gillett@Sun.COM
1180*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
1181*10583SEdward.Gillett@Sun.COM
1182*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1183*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
1184*10583SEdward.Gillett@Sun.COM	mov	$10, %r9d	/* rdi bytes already examined. Used in exit code */
1185*10583SEdward.Gillett@Sun.COM	/*
1186*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
1187*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
1188*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
1189*10583SEdward.Gillett@Sun.COM	 */
1190*10583SEdward.Gillett@Sun.COM	lea	10(%rdi), %r10
1191*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
1192*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
1193*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
1194*10583SEdward.Gillett@Sun.COM
1195*10583SEdward.Gillett@Sun.COM	.p2align 4
1196*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_10):
1197*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1198*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_10)
1199*10583SEdward.Gillett@Sun.COM
1200*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_10):
1201*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1202*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1203*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1204*10583SEdward.Gillett@Sun.COM
1205*10583SEdward.Gillett@Sun.COM	psrldq	$10, %xmm3
1206*10583SEdward.Gillett@Sun.COM	pslldq	$6, %xmm2
1207*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1208*10583SEdward.Gillett@Sun.COM
1209*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1210*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1211*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1212*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1213*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1214*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1215*10583SEdward.Gillett@Sun.COM
1216*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1217*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1218*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
12190Sstevel@tonic-gate#endif
12200Sstevel@tonic-gate
1221*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1222*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1223*10583SEdward.Gillett@Sun.COM
1224*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1225*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_10)	/* cross page boundary */
1226*10583SEdward.Gillett@Sun.COM
1227*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1228*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1229*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1230*10583SEdward.Gillett@Sun.COM
1231*10583SEdward.Gillett@Sun.COM	psrldq	$10, %xmm3
1232*10583SEdward.Gillett@Sun.COM	pslldq 	$6, %xmm2
1233*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1234*10583SEdward.Gillett@Sun.COM
1235*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1236*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1237*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1238*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1239*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1240*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
12410Sstevel@tonic-gate
1242*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1243*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1244*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1245*10583SEdward.Gillett@Sun.COM#endif
1246*10583SEdward.Gillett@Sun.COM
1247*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1248*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1249*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_10)
1250*10583SEdward.Gillett@Sun.COM
1251*10583SEdward.Gillett@Sun.COM	.p2align 4
1252*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_10):
1253*10583SEdward.Gillett@Sun.COM	psrldq	$10, %xmm4
1254*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1255*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1256*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
1257*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1258*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1259*10583SEdward.Gillett@Sun.COM	sub	$0x003f, %edx
1260*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1261*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1262*10583SEdward.Gillett@Sun.COM	cmp	$6, %r11
1263*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1264*10583SEdward.Gillett@Sun.COM#endif
1265*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
1266*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
1267*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_10)
12680Sstevel@tonic-gate
1269*10583SEdward.Gillett@Sun.COM/*
1270*10583SEdward.Gillett@Sun.COM * ashr_11 handles the following cases:
1271*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 5
1272*10583SEdward.Gillett@Sun.COM */
1273*10583SEdward.Gillett@Sun.COM	.p2align 4
1274*10583SEdward.Gillett@Sun.COMLABEL(ashr_11):
1275*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1276*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
1277*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
1278*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1279*10583SEdward.Gillett@Sun.COM	pslldq	$5, %xmm2
1280*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
1281*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
1282*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
1283*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
1284*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
1285*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
1286*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
1287*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
1288*10583SEdward.Gillett@Sun.COM
1289*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
12900Sstevel@tonic-gate
1291*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1292*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
1293*10583SEdward.Gillett@Sun.COM	mov	$11, %r9d	/* rdi bytes already examined. Used in exit code */
1294*10583SEdward.Gillett@Sun.COM	/*
1295*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
1296*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
1297*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
1298*10583SEdward.Gillett@Sun.COM	 */
1299*10583SEdward.Gillett@Sun.COM	lea	11(%rdi), %r10
1300*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
1301*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
1302*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
13030Sstevel@tonic-gate
1304*10583SEdward.Gillett@Sun.COM	.p2align 4
1305*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_11):
1306*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1307*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_11)
1308*10583SEdward.Gillett@Sun.COM
1309*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_11):
1310*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1311*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1312*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
13130Sstevel@tonic-gate
1314*10583SEdward.Gillett@Sun.COM	psrldq	$11, %xmm3
1315*10583SEdward.Gillett@Sun.COM	pslldq	$5, %xmm2
1316*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1317*10583SEdward.Gillett@Sun.COM
1318*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1319*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1320*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1321*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1322*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1323*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
13240Sstevel@tonic-gate
13250Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1326*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1327*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1328*10583SEdward.Gillett@Sun.COM#endif
1329*10583SEdward.Gillett@Sun.COM
1330*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1331*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1332*10583SEdward.Gillett@Sun.COM
1333*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1334*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_11)	/* cross page boundary */
1335*10583SEdward.Gillett@Sun.COM
1336*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1337*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1338*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1339*10583SEdward.Gillett@Sun.COM
1340*10583SEdward.Gillett@Sun.COM	psrldq	$11, %xmm3
1341*10583SEdward.Gillett@Sun.COM	pslldq 	$5, %xmm2
1342*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1343*10583SEdward.Gillett@Sun.COM
1344*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1345*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1346*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1347*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1348*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1349*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1350*10583SEdward.Gillett@Sun.COM
1351*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1352*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1353*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
13540Sstevel@tonic-gate#endif
13550Sstevel@tonic-gate
1356*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1357*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1358*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_11)
13590Sstevel@tonic-gate
1360*10583SEdward.Gillett@Sun.COM	.p2align 4
1361*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_11):
1362*10583SEdward.Gillett@Sun.COM	psrldq	$11, %xmm4
1363*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1364*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1365*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
1366*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1367*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1368*10583SEdward.Gillett@Sun.COM	sub	$0x001f, %edx
1369*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1370*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1371*10583SEdward.Gillett@Sun.COM	cmp	$5, %r11
1372*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1373*10583SEdward.Gillett@Sun.COM#endif
1374*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
1375*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
1376*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_11)
13770Sstevel@tonic-gate
1378*10583SEdward.Gillett@Sun.COM/*
1379*10583SEdward.Gillett@Sun.COM * ashr_12 handles the following cases:
1380*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 4
1381*10583SEdward.Gillett@Sun.COM */
1382*10583SEdward.Gillett@Sun.COM	.p2align 4
1383*10583SEdward.Gillett@Sun.COMLABEL(ashr_12):
1384*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1385*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
1386*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
1387*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1388*10583SEdward.Gillett@Sun.COM	pslldq	$4, %xmm2
1389*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
1390*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
1391*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
1392*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
1393*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
1394*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
1395*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
1396*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
1397*10583SEdward.Gillett@Sun.COM
1398*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
13990Sstevel@tonic-gate
1400*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1401*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
1402*10583SEdward.Gillett@Sun.COM	mov	$12, %r9d	/* rdi bytes already examined. Used in exit code */
1403*10583SEdward.Gillett@Sun.COM	/*
1404*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
1405*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
1406*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
1407*10583SEdward.Gillett@Sun.COM	 */
1408*10583SEdward.Gillett@Sun.COM	lea	12(%rdi), %r10
1409*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
1410*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
1411*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
14120Sstevel@tonic-gate
1413*10583SEdward.Gillett@Sun.COM	.p2align 4
1414*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_12):
1415*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1416*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_12)
1417*10583SEdward.Gillett@Sun.COM
1418*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_12):
1419*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1420*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1421*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
14220Sstevel@tonic-gate
1423*10583SEdward.Gillett@Sun.COM	psrldq	$12, %xmm3
1424*10583SEdward.Gillett@Sun.COM	pslldq	$4, %xmm2
1425*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1426*10583SEdward.Gillett@Sun.COM
1427*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1428*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1429*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1430*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1431*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1432*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
14330Sstevel@tonic-gate
14340Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1435*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1436*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1437*10583SEdward.Gillett@Sun.COM#endif
1438*10583SEdward.Gillett@Sun.COM
1439*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1440*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1441*10583SEdward.Gillett@Sun.COM
1442*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1443*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_12)	/* cross page boundary */
1444*10583SEdward.Gillett@Sun.COM
1445*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1446*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1447*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1448*10583SEdward.Gillett@Sun.COM
1449*10583SEdward.Gillett@Sun.COM	psrldq	$12, %xmm3
1450*10583SEdward.Gillett@Sun.COM	pslldq 	$4, %xmm2
1451*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1452*10583SEdward.Gillett@Sun.COM
1453*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1454*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1455*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1456*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1457*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1458*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1459*10583SEdward.Gillett@Sun.COM
1460*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1461*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1462*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
14630Sstevel@tonic-gate#endif
14640Sstevel@tonic-gate
1465*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1466*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1467*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_12)
14680Sstevel@tonic-gate
1469*10583SEdward.Gillett@Sun.COM	.p2align 4
1470*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_12):
1471*10583SEdward.Gillett@Sun.COM	psrldq	$12, %xmm4
1472*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1473*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1474*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
1475*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1476*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1477*10583SEdward.Gillett@Sun.COM	sub	$0x000f, %edx
1478*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1479*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1480*10583SEdward.Gillett@Sun.COM	cmp	$4, %r11
1481*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1482*10583SEdward.Gillett@Sun.COM#endif
1483*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
1484*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
1485*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_12)
14860Sstevel@tonic-gate
1487*10583SEdward.Gillett@Sun.COM/*
1488*10583SEdward.Gillett@Sun.COM * ashr_13 handles the following cases:
1489*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 3
1490*10583SEdward.Gillett@Sun.COM */
1491*10583SEdward.Gillett@Sun.COM	.p2align 4
1492*10583SEdward.Gillett@Sun.COMLABEL(ashr_13):
1493*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1494*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
1495*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
1496*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1497*10583SEdward.Gillett@Sun.COM	pslldq	$3, %xmm2
1498*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
1499*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
1500*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
1501*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
1502*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
1503*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
1504*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
1505*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
15060Sstevel@tonic-gate
1507*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
15080Sstevel@tonic-gate
1509*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1510*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
1511*10583SEdward.Gillett@Sun.COM	mov	$13, %r9d	/* rdi bytes already examined. Used in exit code */
1512*10583SEdward.Gillett@Sun.COM	/*
1513*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
1514*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
1515*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
1516*10583SEdward.Gillett@Sun.COM	 */
1517*10583SEdward.Gillett@Sun.COM	lea	13(%rdi), %r10
1518*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
1519*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
1520*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
15210Sstevel@tonic-gate
1522*10583SEdward.Gillett@Sun.COM	.p2align 4
1523*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_13):
1524*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1525*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_13)
15260Sstevel@tonic-gate
1527*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_13):
1528*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1529*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1530*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1531*10583SEdward.Gillett@Sun.COM
1532*10583SEdward.Gillett@Sun.COM	psrldq	$13, %xmm3
1533*10583SEdward.Gillett@Sun.COM	pslldq	$3, %xmm2
1534*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
15350Sstevel@tonic-gate
1536*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1537*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1538*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1539*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1540*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1541*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1542*10583SEdward.Gillett@Sun.COM
15430Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1544*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1545*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
15460Sstevel@tonic-gate#endif
15470Sstevel@tonic-gate
1548*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1549*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1550*10583SEdward.Gillett@Sun.COM
1551*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1552*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_13)	/* cross page boundary */
1553*10583SEdward.Gillett@Sun.COM
1554*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1555*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1556*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
15570Sstevel@tonic-gate
1558*10583SEdward.Gillett@Sun.COM	psrldq	$13, %xmm3
1559*10583SEdward.Gillett@Sun.COM	pslldq 	$3, %xmm2
1560*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1561*10583SEdward.Gillett@Sun.COM
1562*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1563*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1564*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1565*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1566*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1567*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
15680Sstevel@tonic-gate
15690Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1570*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1571*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
15720Sstevel@tonic-gate#endif
15730Sstevel@tonic-gate
1574*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1575*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1576*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_13)
1577*10583SEdward.Gillett@Sun.COM
1578*10583SEdward.Gillett@Sun.COM	.p2align 4
1579*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_13):
1580*10583SEdward.Gillett@Sun.COM	psrldq	$13, %xmm4
1581*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1582*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1583*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
1584*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1585*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1586*10583SEdward.Gillett@Sun.COM	sub	$0x0007, %edx
1587*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1588*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1589*10583SEdward.Gillett@Sun.COM	cmp	$3, %r11
1590*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1591*10583SEdward.Gillett@Sun.COM#endif
1592*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
1593*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
1594*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_13)
15950Sstevel@tonic-gate
1596*10583SEdward.Gillett@Sun.COM/*
1597*10583SEdward.Gillett@Sun.COM * ashr_14 handles the following cases:
1598*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 2
1599*10583SEdward.Gillett@Sun.COM */
1600*10583SEdward.Gillett@Sun.COM	.p2align 4
1601*10583SEdward.Gillett@Sun.COMLABEL(ashr_14):
1602*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1603*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
1604*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
1605*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1606*10583SEdward.Gillett@Sun.COM	pslldq  $2, %xmm2
1607*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
1608*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
1609*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
1610*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
1611*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
1612*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
1613*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
1614*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
1615*10583SEdward.Gillett@Sun.COM
1616*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
1617*10583SEdward.Gillett@Sun.COM
1618*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1619*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
1620*10583SEdward.Gillett@Sun.COM	mov	$14, %r9d	/* rdi bytes already examined. Used in exit code */
1621*10583SEdward.Gillett@Sun.COM	/*
1622*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
1623*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
1624*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
1625*10583SEdward.Gillett@Sun.COM	 */
1626*10583SEdward.Gillett@Sun.COM	lea	14(%rdi), %r10
1627*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
1628*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
1629*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
1630*10583SEdward.Gillett@Sun.COM
1631*10583SEdward.Gillett@Sun.COM	.p2align 4
1632*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_14):
1633*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1634*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_14)
1635*10583SEdward.Gillett@Sun.COM
1636*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_14):
1637*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1638*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1639*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1640*10583SEdward.Gillett@Sun.COM
1641*10583SEdward.Gillett@Sun.COM	psrldq	$14, %xmm3
1642*10583SEdward.Gillett@Sun.COM	pslldq	$2, %xmm2
1643*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1644*10583SEdward.Gillett@Sun.COM
1645*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1646*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1647*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1648*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1649*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1650*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
16510Sstevel@tonic-gate
16520Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1653*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1654*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
16550Sstevel@tonic-gate#endif
16560Sstevel@tonic-gate
1657*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1658*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1659*10583SEdward.Gillett@Sun.COM
1660*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1661*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_14)	/* cross page boundary */
1662*10583SEdward.Gillett@Sun.COM
1663*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1664*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1665*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
16660Sstevel@tonic-gate
1667*10583SEdward.Gillett@Sun.COM	psrldq	$14, %xmm3
1668*10583SEdward.Gillett@Sun.COM	pslldq 	$2, %xmm2
1669*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1670*10583SEdward.Gillett@Sun.COM
1671*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1672*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1673*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1674*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1675*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1676*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
16770Sstevel@tonic-gate
16780Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1679*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1680*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
16810Sstevel@tonic-gate#endif
16820Sstevel@tonic-gate
1683*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1684*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1685*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_14)
1686*10583SEdward.Gillett@Sun.COM
1687*10583SEdward.Gillett@Sun.COM	.p2align 4
1688*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_14):
1689*10583SEdward.Gillett@Sun.COM	psrldq	$14, %xmm4
1690*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1691*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1692*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
1693*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1694*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1695*10583SEdward.Gillett@Sun.COM	sub	$0x0003, %edx
1696*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1697*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1698*10583SEdward.Gillett@Sun.COM	cmp	$2, %r11
1699*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1700*10583SEdward.Gillett@Sun.COM#endif
1701*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
1702*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
1703*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_14)
17040Sstevel@tonic-gate
1705*10583SEdward.Gillett@Sun.COM/*
1706*10583SEdward.Gillett@Sun.COM * ashr_15 handles the following cases:
1707*10583SEdward.Gillett@Sun.COM * 	abs(str1 offset - str2 offset) = 1
1708*10583SEdward.Gillett@Sun.COM */
1709*10583SEdward.Gillett@Sun.COM	.p2align 4
1710*10583SEdward.Gillett@Sun.COMLABEL(ashr_15):
1711*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1712*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm2
1713*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi), %xmm1
1714*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1715*10583SEdward.Gillett@Sun.COM	pslldq	$1, %xmm2
1716*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm2
1717*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm2
1718*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm2, %r9d
1719*10583SEdward.Gillett@Sun.COM	shr	%cl, %edx
1720*10583SEdward.Gillett@Sun.COM	shr	%cl, %r9d
1721*10583SEdward.Gillett@Sun.COM	sub	%r9d, %edx
1722*10583SEdward.Gillett@Sun.COM	jnz	LABEL(less32bytes)
1723*10583SEdward.Gillett@Sun.COM
1724*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi), %xmm3
1725*10583SEdward.Gillett@Sun.COM
1726*10583SEdward.Gillett@Sun.COM	UPDATE_STRNCMP_COUNTER
1727*10583SEdward.Gillett@Sun.COM
1728*10583SEdward.Gillett@Sun.COM	pxor	%xmm0, %xmm0
1729*10583SEdward.Gillett@Sun.COM	mov	$16, %rcx	/* index for loads */
1730*10583SEdward.Gillett@Sun.COM	mov	$15, %r9d	/* rdi bytes already examined. Used in exit code */
1731*10583SEdward.Gillett@Sun.COM	/*
1732*10583SEdward.Gillett@Sun.COM	 * Setup %r10 value allows us to detect crossing a page boundary.
1733*10583SEdward.Gillett@Sun.COM	 * When %r10 goes positive we are crossing a page boundary and
1734*10583SEdward.Gillett@Sun.COM	 * need to do a nibble.
1735*10583SEdward.Gillett@Sun.COM	 */
1736*10583SEdward.Gillett@Sun.COM	lea	15(%rdi), %r10
1737*10583SEdward.Gillett@Sun.COM	and	$0xfff, %r10	/* offset into 4K page */
1738*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10	/* subtract 4K pagesize */
1739*10583SEdward.Gillett@Sun.COM	movdqa	%xmm3, %xmm4
1740*10583SEdward.Gillett@Sun.COM
1741*10583SEdward.Gillett@Sun.COM	.p2align 4
1742*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_15):
1743*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1744*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_15)
1745*10583SEdward.Gillett@Sun.COM
1746*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_15):
1747*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1748*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1749*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
1750*10583SEdward.Gillett@Sun.COM
1751*10583SEdward.Gillett@Sun.COM	psrldq	$15, %xmm3
1752*10583SEdward.Gillett@Sun.COM	pslldq	$1, %xmm2
1753*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1754*10583SEdward.Gillett@Sun.COM
1755*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1756*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1757*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1758*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1759*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1760*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
17610Sstevel@tonic-gate
17620Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1763*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1764*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
17650Sstevel@tonic-gate#endif
17660Sstevel@tonic-gate
1767*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1768*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1769*10583SEdward.Gillett@Sun.COM
1770*10583SEdward.Gillett@Sun.COM	add	$16, %r10
1771*10583SEdward.Gillett@Sun.COM	jg	LABEL(nibble_ashr_15)	/* cross page boundary */
1772*10583SEdward.Gillett@Sun.COM
1773*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1774*10583SEdward.Gillett@Sun.COM	movdqa	(%rdi, %rcx), %xmm2
1775*10583SEdward.Gillett@Sun.COM	movdqa	%xmm2, %xmm4
17760Sstevel@tonic-gate
1777*10583SEdward.Gillett@Sun.COM	psrldq	$15, %xmm3
1778*10583SEdward.Gillett@Sun.COM	pslldq 	$1, %xmm2
1779*10583SEdward.Gillett@Sun.COM	por	%xmm3, %xmm2
1780*10583SEdward.Gillett@Sun.COM
1781*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1782*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm2, %xmm1
1783*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1784*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1785*10583SEdward.Gillett@Sun.COM	sub	$0xffff, %edx
1786*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
17870Sstevel@tonic-gate
17880Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1789*10583SEdward.Gillett@Sun.COM	sub	$16, %r11
1790*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
17910Sstevel@tonic-gate#endif
17920Sstevel@tonic-gate
1793*10583SEdward.Gillett@Sun.COM	add	$16, %rcx
1794*10583SEdward.Gillett@Sun.COM	movdqa	%xmm4, %xmm3
1795*10583SEdward.Gillett@Sun.COM	jmp	LABEL(loop_ashr_15)
17960Sstevel@tonic-gate
1797*10583SEdward.Gillett@Sun.COM	.p2align 4
1798*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_15):
1799*10583SEdward.Gillett@Sun.COM	psrldq	$15, %xmm4
1800*10583SEdward.Gillett@Sun.COM	movdqa	(%rsi, %rcx), %xmm1
1801*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm1, %xmm0
1802*10583SEdward.Gillett@Sun.COM	pcmpeqb	%xmm4, %xmm1
1803*10583SEdward.Gillett@Sun.COM	psubb	%xmm0, %xmm1
1804*10583SEdward.Gillett@Sun.COM	pmovmskb %xmm1, %edx
1805*10583SEdward.Gillett@Sun.COM	sub	$0x0001, %edx
1806*10583SEdward.Gillett@Sun.COM	jnz	LABEL(exit)
1807*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1808*10583SEdward.Gillett@Sun.COM	cmp	$1, %r11
1809*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1810*10583SEdward.Gillett@Sun.COM#endif
1811*10583SEdward.Gillett@Sun.COM 	pxor	%xmm0, %xmm0
1812*10583SEdward.Gillett@Sun.COM	sub	$0x1000, %r10		/* subtract 4K from %r10 */
1813*10583SEdward.Gillett@Sun.COM	jmp	LABEL(gobble_ashr_15)
1814*10583SEdward.Gillett@Sun.COM
1815*10583SEdward.Gillett@Sun.COM	.p2align 4
1816*10583SEdward.Gillett@Sun.COMLABEL(exit):
1817*10583SEdward.Gillett@Sun.COM	lea	-16(%r9, %rcx), %rax	/* locate the exact offset for rdi */
1818*10583SEdward.Gillett@Sun.COMLABEL(less32bytes):
1819*10583SEdward.Gillett@Sun.COM	lea	(%rdi, %rax), %rdi	/* locate the exact address for first operand(rdi) */
1820*10583SEdward.Gillett@Sun.COM	lea	(%rsi, %rcx), %rsi	/* locate the exact address for second operand(rsi) */
1821*10583SEdward.Gillett@Sun.COM	test	%r8d, %r8d
1822*10583SEdward.Gillett@Sun.COM	jz	LABEL(ret)
1823*10583SEdward.Gillett@Sun.COM	xchg	%rsi, %rdi		/* recover original order according to flag(%r8d) */
1824*10583SEdward.Gillett@Sun.COM
1825*10583SEdward.Gillett@Sun.COM	.p2align 4
1826*10583SEdward.Gillett@Sun.COMLABEL(ret):
1827*10583SEdward.Gillett@Sun.COMLABEL(less16bytes):
1828*10583SEdward.Gillett@Sun.COM	/*
1829*10583SEdward.Gillett@Sun.COM	 * Check to see if BSF is fast on this processor. If not, use a different
1830*10583SEdward.Gillett@Sun.COM	 * exit tail.
1831*10583SEdward.Gillett@Sun.COM	 */
1832*10583SEdward.Gillett@Sun.COM	testl	$USE_BSF,.memops_method(%rip)
1833*10583SEdward.Gillett@Sun.COM	jz	LABEL(AMD_exit)
1834*10583SEdward.Gillett@Sun.COM	bsf	%rdx, %rdx		/* find and store bit index in %rdx */
18350Sstevel@tonic-gate
18360Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1837*10583SEdward.Gillett@Sun.COM	sub	%rdx, %r11
1838*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1839*10583SEdward.Gillett@Sun.COM#endif
1840*10583SEdward.Gillett@Sun.COM	xor	%ecx, %ecx		/* clear %ecx */
1841*10583SEdward.Gillett@Sun.COM	xor	%eax, %eax		/* clear %eax */
1842*10583SEdward.Gillett@Sun.COM
1843*10583SEdward.Gillett@Sun.COM	movb	(%rsi, %rdx), %cl
1844*10583SEdward.Gillett@Sun.COM	movb	(%rdi, %rdx), %al
1845*10583SEdward.Gillett@Sun.COM
1846*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1847*10583SEdward.Gillett@Sun.COM	ret
1848*10583SEdward.Gillett@Sun.COM
1849*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1850*10583SEdward.Gillett@Sun.COMLABEL(strcmp_exitz):
1851*10583SEdward.Gillett@Sun.COM	xor	%eax, %eax
1852*10583SEdward.Gillett@Sun.COM	ret
18530Sstevel@tonic-gate#endif
18540Sstevel@tonic-gate
1855*10583SEdward.Gillett@Sun.COM	/*
1856*10583SEdward.Gillett@Sun.COM	 * This exit tail does not use the bsf instruction.
1857*10583SEdward.Gillett@Sun.COM	 */
1858*10583SEdward.Gillett@Sun.COM	.p2align 4
1859*10583SEdward.Gillett@Sun.COMLABEL(AMD_exit):
1860*10583SEdward.Gillett@Sun.COM	test	%dl, %dl
1861*10583SEdward.Gillett@Sun.COM	jz	LABEL(next_8_bytes)
1862*10583SEdward.Gillett@Sun.COM
1863*10583SEdward.Gillett@Sun.COM	test	$0x01, %dl
1864*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte0)
1865*10583SEdward.Gillett@Sun.COM
1866*10583SEdward.Gillett@Sun.COM	test	$0x02, %dl
1867*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte1)
1868*10583SEdward.Gillett@Sun.COM
1869*10583SEdward.Gillett@Sun.COM	test	$0x04, %dl
1870*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte2)
1871*10583SEdward.Gillett@Sun.COM
1872*10583SEdward.Gillett@Sun.COM	test	$0x08, %dl
1873*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte3)
1874*10583SEdward.Gillett@Sun.COM
1875*10583SEdward.Gillett@Sun.COM	test	$0x10, %dl
1876*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte4)
1877*10583SEdward.Gillett@Sun.COM
1878*10583SEdward.Gillett@Sun.COM	test	$0x20, %dl
1879*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte5)
1880*10583SEdward.Gillett@Sun.COM
1881*10583SEdward.Gillett@Sun.COM	test	$0x40, %dl
1882*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte6)
1883*10583SEdward.Gillett@Sun.COM
1884*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1885*10583SEdward.Gillett@Sun.COM	sub	$7, %r11
1886*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1887*10583SEdward.Gillett@Sun.COM#endif
1888*10583SEdward.Gillett@Sun.COM	movzx	7(%rsi), %ecx
1889*10583SEdward.Gillett@Sun.COM	movzx	7(%rdi), %eax
1890*10583SEdward.Gillett@Sun.COM
1891*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1892*10583SEdward.Gillett@Sun.COM	ret
18930Sstevel@tonic-gate
1894*10583SEdward.Gillett@Sun.COM	.p2align 4
1895*10583SEdward.Gillett@Sun.COMLABEL(Byte0):
1896*10583SEdward.Gillett@Sun.COM	/*
1897*10583SEdward.Gillett@Sun.COM	 * never need to handle byte 0 for strncmpy
1898*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1899*10583SEdward.Gillett@Sun.COM	sub	$0, %r11
1900*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1901*10583SEdward.Gillett@Sun.COM#endif
1902*10583SEdward.Gillett@Sun.COM	*/
1903*10583SEdward.Gillett@Sun.COM	movzx	(%rsi), %ecx
1904*10583SEdward.Gillett@Sun.COM	movzx	(%rdi), %eax
1905*10583SEdward.Gillett@Sun.COM
1906*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1907*10583SEdward.Gillett@Sun.COM	ret
1908*10583SEdward.Gillett@Sun.COM
1909*10583SEdward.Gillett@Sun.COM	.p2align 4
1910*10583SEdward.Gillett@Sun.COMLABEL(Byte1):
1911*10583SEdward.Gillett@Sun.COM
1912*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1913*10583SEdward.Gillett@Sun.COM	sub	$1, %r11
1914*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1915*10583SEdward.Gillett@Sun.COM#endif
1916*10583SEdward.Gillett@Sun.COM	movzx	1(%rsi), %ecx
1917*10583SEdward.Gillett@Sun.COM	movzx	1(%rdi), %eax
1918*10583SEdward.Gillett@Sun.COM
1919*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1920*10583SEdward.Gillett@Sun.COM	ret
1921*10583SEdward.Gillett@Sun.COM
1922*10583SEdward.Gillett@Sun.COM	.p2align 4
1923*10583SEdward.Gillett@Sun.COMLABEL(Byte2):
1924*10583SEdward.Gillett@Sun.COM
1925*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1926*10583SEdward.Gillett@Sun.COM	sub	$2, %r11
1927*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1928*10583SEdward.Gillett@Sun.COM#endif
1929*10583SEdward.Gillett@Sun.COM	movzx	2(%rsi), %ecx
1930*10583SEdward.Gillett@Sun.COM	movzx	2(%rdi), %eax
1931*10583SEdward.Gillett@Sun.COM
1932*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1933*10583SEdward.Gillett@Sun.COM	ret
1934*10583SEdward.Gillett@Sun.COM
1935*10583SEdward.Gillett@Sun.COM	.p2align 4
1936*10583SEdward.Gillett@Sun.COMLABEL(Byte3):
19370Sstevel@tonic-gate
19380Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1939*10583SEdward.Gillett@Sun.COM	sub	$3, %r11
1940*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
19410Sstevel@tonic-gate#endif
1942*10583SEdward.Gillett@Sun.COM	movzx	3(%rsi), %ecx
1943*10583SEdward.Gillett@Sun.COM	movzx	3(%rdi), %eax
1944*10583SEdward.Gillett@Sun.COM
1945*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1946*10583SEdward.Gillett@Sun.COM	ret
19470Sstevel@tonic-gate
1948*10583SEdward.Gillett@Sun.COM	.p2align 4
1949*10583SEdward.Gillett@Sun.COMLABEL(Byte4):
19500Sstevel@tonic-gate
1951*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1952*10583SEdward.Gillett@Sun.COM	sub	$4, %r11
1953*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1954*10583SEdward.Gillett@Sun.COM#endif
1955*10583SEdward.Gillett@Sun.COM	movzx	4(%rsi), %ecx
1956*10583SEdward.Gillett@Sun.COM	movzx	4(%rdi), %eax
19570Sstevel@tonic-gate
1958*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1959*10583SEdward.Gillett@Sun.COM	ret
19600Sstevel@tonic-gate
1961*10583SEdward.Gillett@Sun.COM	.p2align 4
1962*10583SEdward.Gillett@Sun.COMLABEL(Byte5):
19630Sstevel@tonic-gate
19640Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1965*10583SEdward.Gillett@Sun.COM	sub	$5, %r11
1966*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
19670Sstevel@tonic-gate#endif
1968*10583SEdward.Gillett@Sun.COM	movzx	5(%rsi), %ecx
1969*10583SEdward.Gillett@Sun.COM	movzx	5(%rdi), %eax
19700Sstevel@tonic-gate
1971*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1972*10583SEdward.Gillett@Sun.COM	ret
1973*10583SEdward.Gillett@Sun.COM
1974*10583SEdward.Gillett@Sun.COM	.p2align 4
1975*10583SEdward.Gillett@Sun.COMLABEL(Byte6):
19760Sstevel@tonic-gate
19770Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
1978*10583SEdward.Gillett@Sun.COM	sub	$6, %r11
1979*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
1980*10583SEdward.Gillett@Sun.COM#endif
1981*10583SEdward.Gillett@Sun.COM	movzx	6(%rsi), %ecx
1982*10583SEdward.Gillett@Sun.COM	movzx	6(%rdi), %eax
1983*10583SEdward.Gillett@Sun.COM
1984*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
1985*10583SEdward.Gillett@Sun.COM	ret
1986*10583SEdward.Gillett@Sun.COM
1987*10583SEdward.Gillett@Sun.COM	.p2align 4
1988*10583SEdward.Gillett@Sun.COMLABEL(next_8_bytes):
1989*10583SEdward.Gillett@Sun.COM	add	$8, %rdi
1990*10583SEdward.Gillett@Sun.COM	add	$8, %rsi
1991*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
1992*10583SEdward.Gillett@Sun.COM	sub	$8, %r11
1993*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
19940Sstevel@tonic-gate#endif
1995*10583SEdward.Gillett@Sun.COM	test	$0x01, %dh
1996*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte0)
1997*10583SEdward.Gillett@Sun.COM
1998*10583SEdward.Gillett@Sun.COM	test	$0x02, %dh
1999*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte1)
2000*10583SEdward.Gillett@Sun.COM
2001*10583SEdward.Gillett@Sun.COM	test	$0x04, %dh
2002*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte2)
2003*10583SEdward.Gillett@Sun.COM
2004*10583SEdward.Gillett@Sun.COM	test	$0x08, %dh
2005*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte3)
2006*10583SEdward.Gillett@Sun.COM
2007*10583SEdward.Gillett@Sun.COM	test	$0x10, %dh
2008*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte4)
2009*10583SEdward.Gillett@Sun.COM
2010*10583SEdward.Gillett@Sun.COM	test	$0x20, %dh
2011*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte5)
2012*10583SEdward.Gillett@Sun.COM
2013*10583SEdward.Gillett@Sun.COM	test	$0x40, %dh
2014*10583SEdward.Gillett@Sun.COM	jnz	LABEL(Byte6)
20150Sstevel@tonic-gate
20160Sstevel@tonic-gate#ifdef USE_AS_STRNCMP
2017*10583SEdward.Gillett@Sun.COM	sub	$7, %r11
2018*10583SEdward.Gillett@Sun.COM	jbe	LABEL(strcmp_exitz)
2019*10583SEdward.Gillett@Sun.COM#endif
2020*10583SEdward.Gillett@Sun.COM	movzx	7(%rsi), %ecx
2021*10583SEdward.Gillett@Sun.COM	movzx	7(%rdi), %eax
2022*10583SEdward.Gillett@Sun.COM
2023*10583SEdward.Gillett@Sun.COM	sub	%ecx, %eax
2024*10583SEdward.Gillett@Sun.COM	ret
2025*10583SEdward.Gillett@Sun.COM
2026*10583SEdward.Gillett@Sun.COM	.pushsection .rodata
2027*10583SEdward.Gillett@Sun.COM	.p2align 4
2028*10583SEdward.Gillett@Sun.COMLABEL(unaligned_table):
2029*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_0) - LABEL(unaligned_table)
2030*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_15) - LABEL(unaligned_table)
2031*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_14) - LABEL(unaligned_table)
2032*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_13) - LABEL(unaligned_table)
2033*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_12) - LABEL(unaligned_table)
2034*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_11) - LABEL(unaligned_table)
2035*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_10) - LABEL(unaligned_table)
2036*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_9) - LABEL(unaligned_table)
2037*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_8) - LABEL(unaligned_table)
2038*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_7) - LABEL(unaligned_table)
2039*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_6) - LABEL(unaligned_table)
2040*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_5) - LABEL(unaligned_table)
2041*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_4) - LABEL(unaligned_table)
2042*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_3) - LABEL(unaligned_table)
2043*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_2) - LABEL(unaligned_table)
2044*10583SEdward.Gillett@Sun.COM	.int	LABEL(ashr_1) - LABEL(unaligned_table)
2045*10583SEdward.Gillett@Sun.COM	.popsection
2046*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP
20470Sstevel@tonic-gate	SET_SIZE(strncmp)
20480Sstevel@tonic-gate#else
20490Sstevel@tonic-gate	SET_SIZE(strcmp)		/* (const char *, const char *) */
20500Sstevel@tonic-gate#endif
2051