1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26	.file	"memcmp.s"
27
28/*
29 * memcmp(s1, s2, len)
30 *
31 * Compare n bytes:  s1>s2: >0  s1==s2: 0  s1<s2: <0
32 *
33 * Fast assembler language version of the following C-program for memcmp
34 * which represents the `standard' for the C-library.
35 *
36 *	int
37 *	memcmp(const void *s1, const void *s2, size_t n)
38 *	{
39 *		if (s1 != s2 && n != 0) {
40 *			const char *ps1 = s1;
41 *			const char *ps2 = s2;
42 *			do {
43 *				if (*ps1++ != *ps2++)
44 *					return(ps1[-1] - ps2[-1]);
45 *			} while (--n != 0);
46 *		}
47 *		return (0);
48 *	}
49 */
50
51#include <sys/asm_linkage.h>
52#include <sys/sun4asi.h>
53
54	ANSI_PRAGMA_WEAK(memcmp,function)
55
56	ENTRY(memcmp)
57	cmp	%o0, %o1		! s1 == s2?
58	be	%ncc, .cmpeq
59
60	! for small counts byte compare immediately
61	cmp	%o2, 48
62	bleu,a 	%ncc, .bytcmp
63	mov	%o2, %o3		! o3 <= 48
64
65	! Count > 48. We will byte compare (8 + num of bytes to dbl align)
66	! bytes. We assume that most miscompares will occur in the 1st 8 bytes
67
68.chkdbl:
69        and     %o0, 7, %o4             ! is s1 aligned on a 8 byte bound
70	mov	8, %o3			! o2 > 48;  o3 = 8
71        sub     %o4, 8, %o4		! o4 = -(num of bytes to dbl align)
72	ba	%ncc, .bytcmp
73        sub     %o3, %o4, %o3           ! o3 = 8 + (num of bytes to dbl align)
74
75
761:      ldub    [%o1], %o5        	! byte compare loop
77        inc     %o1
78        inc     %o0
79	dec	%o2
80        cmp     %o4, %o5
81	bne	%ncc, .noteq
82.bytcmp:
83	deccc   %o3
84	bgeu,a   %ncc, 1b
85        ldub    [%o0], %o4
86
87	! Check to see if there are more bytes to compare
88	cmp	%o2, 0			! is o2 > 0
89	bgu,a	%ncc, .blkchk		! we should already be dbl aligned
90	cmp     %o2, 320                ! if cnt < 256 + 64 -  no Block ld/st
91.cmpeq:
92        retl                             ! strings compare equal
93	sub	%g0, %g0, %o0
94
95.noteq:
96	retl				! strings aren't equal
97	sub	%o4, %o5, %o0		! return(*s1 - *s2)
98
99
100        ! Now src1 is Double word aligned
101.blkchk:
102        bgeu,a   %ncc, blkcmp                  ! do block cmp
103        andcc   %o0, 63, %o3            ! is src1 block aligned
104
105        ! double word compare - using ldd and faligndata. Compares upto
106        ! 8 byte multiple count and does byte compare for the residual.
107
108.dwcmp:
109
110        rd      %fprs, %o3              ! o3 = fprs
111
112        ! if fprs.fef == 0, set it. Checking it, reqires 2 instructions.
113        ! So set it anyway, without checking.
114        wr      %g0, 0x4, %fprs         ! fprs.fef = 1
115
116        andn    %o2, 7, %o4             ! o4 has 8 byte aligned cnt
117	sub     %o4, 8, %o4
118        alignaddr %o1, %g0, %g1
119        ldd     [%g1], %d0
1204:
121        add     %g1, 8, %g1
122        ldd     [%g1], %d2
123	ldd	[%o0], %d6
124        faligndata %d0, %d2, %d8
125	fcmpne32 %d6, %d8, %o5
126	fsrc1	%d6, %d6		! 2 fsrc1's added since o5 cannot
127	fsrc1	%d8, %d8		! be used for 3 cycles else we
128	fmovd	%d2, %d0		! create 9 bubbles in the pipeline
129	brnz,a,pn %o5, 6f
130	sub     %o1, %o0, %o1           ! o1 gets the difference
131        subcc   %o4, 8, %o4
132        add     %o0, 8, %o0
133        add     %o1, 8, %o1
134        bgu,pt	%ncc, 4b
135        sub     %o2, 8, %o2
136
137.residcmp:
138        ba      6f
139	sub     %o1, %o0, %o1           ! o1 gets the difference
140
1415:      ldub    [%o0 + %o1], %o5        ! byte compare loop
142        inc     %o0
143        cmp     %o4, %o5
144        bne     %ncc, .dnoteq
1456:
146        deccc   %o2
147        bgeu,a	%ncc, 5b
148        ldub    [%o0], %o4
149
150	and     %o3, 0x4, %o3           ! fprs.du = fprs.dl = 0
151	wr      %o3, %g0, %fprs         ! fprs = o3 - restore fprs
152	retl
153	sub	%g0, %g0, %o0		! strings compare equal
154
155.dnoteq:
156	and     %o3, 0x4, %o3           ! fprs.du = fprs.dl = 0
157	wr      %o3, %g0, %fprs         ! fprs = o3 - restore fprs
158	retl
159	sub	%o4, %o5, %o0		! return(*s1 - *s2)
160
161
162blkcmp:
163	save    %sp, -SA(MINFRAME), %sp
164        rd      %fprs, %l5              ! l5 = fprs
165
166        ! if fprs.fef == 0, set it. Checking it, reqires 2 instructions.
167        ! So set it anyway, without checking.
168        wr      %g0, 0x4, %fprs         ! fprs.fef = 1
169
170	bz,pn   %ncc, .blalign          ! now block aligned
171        sub     %i3, 64, %i3
172        neg     %i3                     ! bytes till block aligned
173
174        ! Compare %i3 bytes till dst is block (64 byte) aligned. use
175        ! double word compares.
176
177        alignaddr %i1, %g0, %g1
178        ldd     [%g1], %d0
1797:
180        add     %g1, 8, %g1
181        ldd     [%g1], %d2
182        ldd     [%i0], %d6
183        faligndata %d0, %d2, %d8
184        fcmpne32 %d6, %d8, %i5
185	fsrc1	%d6, %d6		! 2 fsrc1's added since i5 cannot
186	fsrc1	%d8, %d8		! be used for 3 cycles else we
187	fmovd	%d2, %d0		! create 9 bubbles in the pipeline
188        brnz,a,pn  %i5, .remcmp
189        sub     %i1, %i0, %i1           ! i1 gets the difference
190        subcc   %i3, 8, %i3
191        add     %i0, 8, %i0
192        add     %i1, 8, %i1
193        bgu,pt	%ncc, 7b
194        sub     %i2, 8, %i2
195
196.blalign:
197
198	! src1 is block aligned
199        membar  #StoreLoad
200        srl     %i1, 3, %l6             ! bits 3,4,5 are now least sig in  %l6
201        andcc   %l6, 7, %l6             ! mask everything except bits 1,2 3
202        andn    %i2, 63, %i3            ! calc number of blocks
203        alignaddr %i1, %g0, %g0         ! gen %gsr
204        andn    %i1, 0x3F, %l7          ! blk aligned address
205        sub     %i2, %i3, %l2
206        andn    %l2, 7, %i4             ! calc doubles left after blkcpy
207
208	be,a	%ncc, 1f	! branch taken if src2 is 64-byte aligned
209	ldda	[%l7]ASI_BLK_P, %d0
210
211	call	.+8		! get the address of this instruction in %o7
212	sll	%l6, 2, %l4
213	add	%o7, %l4, %o7
214	jmp	%o7 + 16	! jump to the starting ldd instruction
215	nop
216	ldd	[%l7+8], %d2
217	ldd	[%l7+16], %d4
218	ldd	[%l7+24], %d6
219	ldd	[%l7+32], %d8
220	ldd	[%l7+40], %d10
221	ldd	[%l7+48], %d12
222	ldd	[%l7+56], %d14
2231:
224        add     %l7, 64, %l7
225        ldda    [%l7]ASI_BLK_P, %d16
226        add     %l7, 64, %l7
227	ldda	[%i0]ASI_BLK_P, %d32
228	sub     %i3, 128, %i3
229
230        ! switch statement to get us to the right 8 byte blk within a
231        ! 64 byte block
232
233        cmp      %l6, 4
234        bgeu,a	hlf
235        cmp      %l6, 6
236        cmp      %l6, 2
237        bgeu,a	sqtr
238        nop
239        cmp      %l6, 1
240        be,a     seg1
241        nop
242        ba       seg0
243        nop
244sqtr:
245        be,a     seg2
246        nop
247
248        ba,a     seg3
249        nop
250
251hlf:
252        bgeu,a	fqtr
253        nop
254        cmp      %l6, 5
255        be,a     seg5
256        nop
257        ba       seg4
258        nop
259fqtr:
260        be,a     seg6
261        nop
262        ba       seg7
263        nop
264
265! The fsrc1 instructions are to make sure that the results of the fcmpne32
266! are used 3 cycles later - else spitfire adds 9 bubbles.
267
268#define	FCMPNE32_D32_D48			\
269	fcmpne32	%d48, %d32, %l0		;\
270	fcmpne32	%d50, %d34, %l1		;\
271	fcmpne32	%d52, %d36, %l2		;\
272	fcmpne32	%d54, %d38, %l3		;\
273	brnz,a		%l0, add		;\
274	mov		0, %l4			;\
275	fcmpne32	%d56, %d40, %l0		;\
276	brnz,a		%l1, add		;\
277	mov		8, %l4			;\
278	fcmpne32	%d58, %d42, %l1		;\
279	brnz,a		%l2, add		;\
280	mov		16, %l4			;\
281	fcmpne32	%d60, %d44, %l2		;\
282	brnz,a		%l3, add		;\
283	mov		24, %l4			;\
284	fcmpne32	%d62, %d46, %l3		;\
285	brnz,a		%l0, add		;\
286	mov		32, %l4			;\
287        fsrc1           %d48, %d48              ;\
288	brnz,a		%l1, add		;\
289	mov		40, %l4			;\
290        fsrc1           %d48, %d48              ;\
291	brnz,a		%l2, add		;\
292	mov		48, %l4			;\
293        fsrc1           %d48, %d48              ;\
294	brnz,a		%l3, add		;\
295	mov		56, %l4
296
297add:
298	add	%l4, %i0, %i0
299	add	%l4, %i1, %i1
300	ba	.remcmp
301	sub	%i1, %i0, %i1
302
303#define FALIGN_D0                       \
304        faligndata %d0, %d2, %d48       ;\
305        faligndata %d2, %d4, %d50       ;\
306        faligndata %d4, %d6, %d52       ;\
307        faligndata %d6, %d8, %d54       ;\
308        faligndata %d8, %d10, %d56      ;\
309        faligndata %d10, %d12, %d58     ;\
310        faligndata %d12, %d14, %d60     ;\
311        faligndata %d14, %d16, %d62
312
313#define FALIGN_D16                      \
314        faligndata %d16, %d18, %d48     ;\
315        faligndata %d18, %d20, %d50     ;\
316        faligndata %d20, %d22, %d52     ;\
317        faligndata %d22, %d24, %d54     ;\
318        faligndata %d24, %d26, %d56     ;\
319        faligndata %d26, %d28, %d58     ;\
320        faligndata %d28, %d30, %d60     ;\
321        faligndata %d30, %d0, %d62
322
323seg0:
324        FALIGN_D0
325        ldda    [%l7]ASI_BLK_P, %d0
326        add     %l7, 64, %l7
327	FCMPNE32_D32_D48
328        add     %i0, 64, %i0
329        add     %i1, 64, %i1
330        subcc   %i3, 64, %i3
331        bz,pn   %ncc, 1f
332        sub     %i2, 64, %i2
333        ldda    [%i0]ASI_BLK_P, %d32
334
335        FALIGN_D16
336        ldda    [%l7]ASI_BLK_P, %d16
337        add     %l7, 64, %l7
338	FCMPNE32_D32_D48
339        add     %i0, 64, %i0
340        add     %i1, 64, %i1
341        subcc   %i3, 64, %i3
342        bz,pn   %ncc, 0f
343        sub     %i2, 64, %i2
344
345        ba	%ncc, seg0
346	ldda	[%i0]ASI_BLK_P, %d32
347
3480:
349	ldda	[%i0]ASI_BLK_P, %d32
350	membar  #Sync
351	FALIGN_D0
352	FCMPNE32_D32_D48
353        add     %i0, 64, %i0
354        add     %i1, 64, %i1
355	ba	%ncc, blkd16
356        sub     %i2, 64, %i2
357
3581:
359	ldda	[%i0]ASI_BLK_P, %d32
360	membar  #Sync
361	FALIGN_D16
362	FCMPNE32_D32_D48
363        add     %i0, 64, %i0
364        add     %i1, 64, %i1
365	ba	%ncc, blkd0
366        sub     %i2, 64, %i2
367
368#define FALIGN_D2                       \
369        faligndata %d2, %d4, %d48       ;\
370        faligndata %d4, %d6, %d50       ;\
371        faligndata %d6, %d8, %d52       ;\
372        faligndata %d8, %d10, %d54      ;\
373        faligndata %d10, %d12, %d56     ;\
374        faligndata %d12, %d14, %d58     ;\
375        faligndata %d14, %d16, %d60     ;\
376        faligndata %d16, %d18, %d62
377
378#define FALIGN_D18                      \
379        faligndata %d18, %d20, %d48     ;\
380        faligndata %d20, %d22, %d50     ;\
381        faligndata %d22, %d24, %d52     ;\
382        faligndata %d24, %d26, %d54     ;\
383        faligndata %d26, %d28, %d56     ;\
384        faligndata %d28, %d30, %d58     ;\
385        faligndata %d30, %d0, %d60      ;\
386        faligndata %d0, %d2, %d62
387
388
389seg1:
390        FALIGN_D2
391        ldda    [%l7]ASI_BLK_P, %d0
392        add     %l7, 64, %l7
393	FCMPNE32_D32_D48
394        add     %i0, 64, %i0
395        add     %i1, 64, %i1
396        subcc   %i3, 64, %i3
397        bz,pn   %ncc, 1f
398        sub     %i2, 64, %i2
399        ldda    [%i0]ASI_BLK_P, %d32
400
401        FALIGN_D18
402        ldda    [%l7]ASI_BLK_P, %d16
403        add     %l7, 64, %l7
404	FCMPNE32_D32_D48
405        add     %i0, 64, %i0
406        add     %i1, 64, %i1
407        subcc   %i3, 64, %i3
408        bz,pn   %ncc, 0f
409        sub     %i2, 64, %i2
410
411        ba	%ncc, seg1
412	ldda	[%i0]ASI_BLK_P, %d32
413
4140:
415	ldda	[%i0]ASI_BLK_P, %d32
416	membar  #Sync
417	FALIGN_D2
418	FCMPNE32_D32_D48
419        add     %i0, 64, %i0
420        add     %i1, 64, %i1
421	ba	%ncc, blkd18
422        sub     %i2, 64, %i2
423
4241:
425	ldda	[%i0]ASI_BLK_P, %d32
426	membar  #Sync
427	FALIGN_D18
428	FCMPNE32_D32_D48
429        add     %i0, 64, %i0
430        add     %i1, 64, %i1
431	ba	%ncc, blkd2
432        sub     %i2, 64, %i2
433
434#define FALIGN_D4                       \
435        faligndata %d4, %d6, %d48       ;\
436        faligndata %d6, %d8, %d50       ;\
437        faligndata %d8, %d10, %d52      ;\
438        faligndata %d10, %d12, %d54     ;\
439        faligndata %d12, %d14, %d56     ;\
440        faligndata %d14, %d16, %d58     ;\
441        faligndata %d16, %d18, %d60     ;\
442        faligndata %d18, %d20, %d62
443
444#define FALIGN_D20                      \
445        faligndata %d20, %d22, %d48     ;\
446        faligndata %d22, %d24, %d50     ;\
447        faligndata %d24, %d26, %d52     ;\
448        faligndata %d26, %d28, %d54     ;\
449        faligndata %d28, %d30, %d56     ;\
450        faligndata %d30, %d0, %d58      ;\
451        faligndata %d0, %d2, %d60       ;\
452        faligndata %d2, %d4, %d62
453
454seg2:
455	FALIGN_D4
456        ldda    [%l7]ASI_BLK_P, %d0
457        add     %l7, 64, %l7
458	FCMPNE32_D32_D48
459        add     %i0, 64, %i0
460        add     %i1, 64, %i1
461        subcc   %i3, 64, %i3
462        bz,pn   %ncc, 1f
463        sub     %i2, 64, %i2
464        ldda    [%i0]ASI_BLK_P, %d32
465
466        FALIGN_D20
467        ldda    [%l7]ASI_BLK_P, %d16
468        add     %l7, 64, %l7
469	FCMPNE32_D32_D48
470        add     %i0, 64, %i0
471        add     %i1, 64, %i1
472        subcc   %i3, 64, %i3
473        bz,pn   %ncc, 0f
474        sub     %i2, 64, %i2
475
476        ba	%ncc, seg2
477	ldda	[%i0]ASI_BLK_P, %d32
478
4790:
480	ldda	[%i0]ASI_BLK_P, %d32
481	membar  #Sync
482	FALIGN_D4
483	FCMPNE32_D32_D48
484        add     %i0, 64, %i0
485        add     %i1, 64, %i1
486	ba	%ncc, blkd20
487        sub     %i2, 64, %i2
488
4891:
490	ldda	[%i0]ASI_BLK_P, %d32
491	membar  #Sync
492	FALIGN_D20
493	FCMPNE32_D32_D48
494        add     %i0, 64, %i0
495        add     %i1, 64, %i1
496	ba	%ncc, blkd4
497        sub     %i2, 64, %i2
498
499#define FALIGN_D6                       \
500        faligndata %d6, %d8, %d48       ;\
501        faligndata %d8, %d10, %d50      ;\
502        faligndata %d10, %d12, %d52     ;\
503        faligndata %d12, %d14, %d54     ;\
504        faligndata %d14, %d16, %d56     ;\
505        faligndata %d16, %d18, %d58     ;\
506        faligndata %d18, %d20, %d60     ;\
507        faligndata %d20, %d22, %d62
508
509#define FALIGN_D22                      \
510        faligndata %d22, %d24, %d48     ;\
511        faligndata %d24, %d26, %d50     ;\
512        faligndata %d26, %d28, %d52     ;\
513        faligndata %d28, %d30, %d54     ;\
514        faligndata %d30, %d0, %d56      ;\
515        faligndata %d0, %d2, %d58       ;\
516        faligndata %d2, %d4, %d60       ;\
517        faligndata %d4, %d6, %d62
518
519
520seg3:
521        FALIGN_D6
522        ldda    [%l7]ASI_BLK_P, %d0
523        add     %l7, 64, %l7
524	FCMPNE32_D32_D48
525        add     %i0, 64, %i0
526        add     %i1, 64, %i1
527        subcc   %i3, 64, %i3
528        bz,pn   %ncc, 1f
529        sub     %i2, 64, %i2
530        ldda    [%i0]ASI_BLK_P, %d32
531
532        FALIGN_D22
533        ldda    [%l7]ASI_BLK_P, %d16
534        add     %l7, 64, %l7
535	FCMPNE32_D32_D48
536        add     %i0, 64, %i0
537        add     %i1, 64, %i1
538        subcc   %i3, 64, %i3
539        bz,pn   %ncc, 0f
540        sub     %i2, 64, %i2
541
542        ba	%ncc, seg3
543	ldda	[%i0]ASI_BLK_P, %d32
544
545
5460:
547	ldda	[%i0]ASI_BLK_P, %d32
548	membar  #Sync
549	FALIGN_D6
550	FCMPNE32_D32_D48
551        add     %i0, 64, %i0
552        add     %i1, 64, %i1
553	ba	%ncc, blkd22
554        sub     %i2, 64, %i2
555
5561:
557	ldda	[%i0]ASI_BLK_P, %d32
558	membar  #Sync
559	FALIGN_D22
560	FCMPNE32_D32_D48
561        add     %i0, 64, %i0
562        add     %i1, 64, %i1
563	ba	%ncc, blkd6
564        sub     %i2, 64, %i2
565
566#define FALIGN_D8                       \
567        faligndata %d8, %d10, %d48      ;\
568        faligndata %d10, %d12, %d50     ;\
569        faligndata %d12, %d14, %d52     ;\
570        faligndata %d14, %d16, %d54     ;\
571        faligndata %d16, %d18, %d56     ;\
572        faligndata %d18, %d20, %d58     ;\
573        faligndata %d20, %d22, %d60     ;\
574        faligndata %d22, %d24, %d62
575
576#define FALIGN_D24                      \
577        faligndata %d24, %d26, %d48     ;\
578        faligndata %d26, %d28, %d50     ;\
579        faligndata %d28, %d30, %d52     ;\
580        faligndata %d30, %d0, %d54      ;\
581        faligndata %d0, %d2, %d56       ;\
582        faligndata %d2, %d4, %d58       ;\
583        faligndata %d4, %d6, %d60       ;\
584        faligndata %d6, %d8, %d62
585
586
587seg4:
588        FALIGN_D8
589        ldda    [%l7]ASI_BLK_P, %d0
590        add     %l7, 64, %l7
591	FCMPNE32_D32_D48
592        add     %i0, 64, %i0
593        add     %i1, 64, %i1
594        subcc   %i3, 64, %i3
595        bz,pn   %ncc, 1f
596        sub     %i2, 64, %i2
597        ldda    [%i0]ASI_BLK_P, %d32
598
599        FALIGN_D24
600        ldda    [%l7]ASI_BLK_P, %d16
601        add     %l7, 64, %l7
602	FCMPNE32_D32_D48
603        add     %i0, 64, %i0
604        add     %i1, 64, %i1
605        subcc   %i3, 64, %i3
606        bz,pn   %ncc, 0f
607        sub     %i2, 64, %i2
608
609        ba	%ncc, seg4
610	ldda	[%i0]ASI_BLK_P, %d32
611
612
6130:
614	ldda	[%i0]ASI_BLK_P, %d32
615	membar  #Sync
616	FALIGN_D8
617	FCMPNE32_D32_D48
618        add     %i0, 64, %i0
619        add     %i1, 64, %i1
620	ba	%ncc, blkd24
621        sub     %i2, 64, %i2
622
6231:
624	ldda	[%i0]ASI_BLK_P, %d32
625	membar  #Sync
626	FALIGN_D24
627	FCMPNE32_D32_D48
628        add     %i0, 64, %i0
629        add     %i1, 64, %i1
630	ba	%ncc, blkd8
631        sub     %i2, 64, %i2
632
633#define FALIGN_D10                      \
634        faligndata %d10, %d12, %d48     ;\
635        faligndata %d12, %d14, %d50     ;\
636        faligndata %d14, %d16, %d52     ;\
637        faligndata %d16, %d18, %d54     ;\
638        faligndata %d18, %d20, %d56     ;\
639        faligndata %d20, %d22, %d58     ;\
640        faligndata %d22, %d24, %d60     ;\
641        faligndata %d24, %d26, %d62
642
643#define FALIGN_D26                      \
644        faligndata %d26, %d28, %d48     ;\
645        faligndata %d28, %d30, %d50     ;\
646        faligndata %d30, %d0, %d52      ;\
647        faligndata %d0, %d2, %d54       ;\
648        faligndata %d2, %d4, %d56       ;\
649        faligndata %d4, %d6, %d58       ;\
650        faligndata %d6, %d8, %d60       ;\
651        faligndata %d8, %d10, %d62
652
653
654seg5:
655        FALIGN_D10
656        ldda    [%l7]ASI_BLK_P, %d0
657        add     %l7, 64, %l7
658	FCMPNE32_D32_D48
659        add     %i0, 64, %i0
660        add     %i1, 64, %i1
661        subcc   %i3, 64, %i3
662        bz,pn   %ncc, 1f
663        sub     %i2, 64, %i2
664        ldda    [%i0]ASI_BLK_P, %d32
665
666        FALIGN_D26
667        ldda    [%l7]ASI_BLK_P, %d16
668        add     %l7, 64, %l7
669	FCMPNE32_D32_D48
670        add     %i0, 64, %i0
671        add     %i1, 64, %i1
672        subcc   %i3, 64, %i3
673        bz,pn   %ncc, 0f
674        sub     %i2, 64, %i2
675
676        ba	%ncc, seg5
677	ldda	[%i0]ASI_BLK_P, %d32
678
679
6800:
681	ldda	[%i0]ASI_BLK_P, %d32
682	membar  #Sync
683	FALIGN_D10
684	FCMPNE32_D32_D48
685        add     %i0, 64, %i0
686        add     %i1, 64, %i1
687	ba	%ncc, blkd26
688        sub     %i2, 64, %i2
689
6901:
691	ldda	[%i0]ASI_BLK_P, %d32
692	membar  #Sync
693	FALIGN_D26
694	FCMPNE32_D32_D48
695        add     %i0, 64, %i0
696        add     %i1, 64, %i1
697	ba	%ncc, blkd10
698        sub     %i2, 64, %i2
699
700#define FALIGN_D12                      \
701        faligndata %d12, %d14, %d48     ;\
702        faligndata %d14, %d16, %d50     ;\
703        faligndata %d16, %d18, %d52     ;\
704        faligndata %d18, %d20, %d54     ;\
705        faligndata %d20, %d22, %d56     ;\
706        faligndata %d22, %d24, %d58     ;\
707        faligndata %d24, %d26, %d60     ;\
708        faligndata %d26, %d28, %d62
709
710#define FALIGN_D28                      \
711        faligndata %d28, %d30, %d48     ;\
712        faligndata %d30, %d0, %d50      ;\
713        faligndata %d0, %d2, %d52       ;\
714        faligndata %d2, %d4, %d54       ;\
715        faligndata %d4, %d6, %d56       ;\
716        faligndata %d6, %d8, %d58       ;\
717        faligndata %d8, %d10, %d60      ;\
718        faligndata %d10, %d12, %d62
719
720
721seg6:
722        FALIGN_D12
723        ldda    [%l7]ASI_BLK_P, %d0
724        add     %l7, 64, %l7
725	FCMPNE32_D32_D48
726        add     %i0, 64, %i0
727        add     %i1, 64, %i1
728        subcc   %i3, 64, %i3
729        bz,pn   %ncc, 1f
730        sub     %i2, 64, %i2
731        ldda    [%i0]ASI_BLK_P, %d32
732
733        FALIGN_D28
734        ldda    [%l7]ASI_BLK_P, %d16
735        add     %l7, 64, %l7
736	FCMPNE32_D32_D48
737        add     %i0, 64, %i0
738        add     %i1, 64, %i1
739        subcc   %i3, 64, %i3
740        bz,pn   %ncc, 0f
741        sub     %i2, 64, %i2
742
743        ba	%ncc, seg6
744	ldda	[%i0]ASI_BLK_P, %d32
745
746
7470:
748	ldda	[%i0]ASI_BLK_P, %d32
749	membar  #Sync
750	FALIGN_D12
751	FCMPNE32_D32_D48
752        add     %i0, 64, %i0
753        add     %i1, 64, %i1
754	ba	%ncc, blkd28
755        sub     %i2, 64, %i2
756
7571:
758	ldda	[%i0]ASI_BLK_P, %d32
759	membar  #Sync
760	FALIGN_D28
761	FCMPNE32_D32_D48
762        add     %i0, 64, %i0
763        add     %i1, 64, %i1
764	ba	%ncc, blkd12
765        sub     %i2, 64, %i2
766
767#define FALIGN_D14                      \
768        faligndata %d14, %d16, %d48     ;\
769        faligndata %d16, %d18, %d50     ;\
770        faligndata %d18, %d20, %d52     ;\
771        faligndata %d20, %d22, %d54     ;\
772        faligndata %d22, %d24, %d56     ;\
773        faligndata %d24, %d26, %d58     ;\
774        faligndata %d26, %d28, %d60     ;\
775        faligndata %d28, %d30, %d62
776
777#define FALIGN_D30                      \
778        faligndata %d30, %d0, %d48     ;\
779        faligndata %d0, %d2, %d50      ;\
780        faligndata %d2, %d4, %d52      ;\
781        faligndata %d4, %d6, %d54      ;\
782        faligndata %d6, %d8, %d56      ;\
783        faligndata %d8, %d10, %d58     ;\
784        faligndata %d10, %d12, %d60    ;\
785        faligndata %d12, %d14, %d62
786
787seg7:
788        FALIGN_D14
789        ldda    [%l7]ASI_BLK_P, %d0
790        add     %l7, 64, %l7
791	FCMPNE32_D32_D48
792        add     %i0, 64, %i0
793        add     %i1, 64, %i1
794        subcc   %i3, 64, %i3
795        bz,pn   %ncc, 1f
796        sub     %i2, 64, %i2
797        ldda    [%i0]ASI_BLK_P, %d32
798
799        FALIGN_D30
800        ldda    [%l7]ASI_BLK_P, %d16
801        add     %l7, 64, %l7
802	FCMPNE32_D32_D48
803        add     %i0, 64, %i0
804        add     %i1, 64, %i1
805        subcc   %i3, 64, %i3
806        bz,pn   %ncc, 0f
807        sub     %i2, 64, %i2
808
809        ba	%ncc, seg7
810	ldda	[%i0]ASI_BLK_P, %d32
811
8120:
813	ldda	[%i0]ASI_BLK_P, %d32
814	membar  #Sync
815	FALIGN_D14
816	FCMPNE32_D32_D48
817        add     %i0, 64, %i0
818        add     %i1, 64, %i1
819	ba	%ncc, blkd30
820        sub     %i2, 64, %i2
821
8221:
823	ldda	[%i0]ASI_BLK_P, %d32
824	membar  #Sync
825	FALIGN_D30
826	FCMPNE32_D32_D48
827        add     %i0, 64, %i0
828        add     %i1, 64, %i1
829	ba	%ncc, blkd14
830        sub     %i2, 64, %i2
831
832
833blkd0:
834        subcc   %i4, 8, %i4
835        blu,a,pn %ncc, .remcmp
836        sub     %i1, %i0, %i1           ! i1 gets the difference
837        faligndata %d0, %d2, %d48
838	ldd	[%i0], %d32
839	fcmpne32 %d32, %d48, %l1
840	fsrc1	%d32, %d32
841	fsrc1	%d32, %d32
842	fsrc1	%d32, %d32
843	brnz,a	 %l1, .remcmp
844        sub     %i1, %i0, %i1           ! i1 gets the difference
845        add     %i0, 8, %i0
846        add     %i1, 8, %i1
847	sub	%i2, 8, %i2
848
849blkd2:
850        subcc   %i4, 8, %i4
851        blu,a,pn %ncc, .remcmp
852        sub     %i1, %i0, %i1           ! i1 gets the difference
853        faligndata %d2, %d4, %d48
854	ldd	[%i0], %d32
855	fcmpne32 %d32, %d48, %l1
856	fsrc1	%d32, %d32
857	fsrc1	%d32, %d32
858	fsrc1	%d32, %d32
859	brnz,a	 %l1, .remcmp
860        sub     %i1, %i0, %i1           ! i1 gets the difference
861        add     %i0, 8, %i0
862        add     %i1, 8, %i1
863	sub	%i2, 8, %i2
864
865blkd4:
866        subcc   %i4, 8, %i4
867        blu,a,pn %ncc, .remcmp
868        sub     %i1, %i0, %i1           ! i1 gets the difference
869        faligndata %d4, %d6, %d48
870	ldd	[%i0], %d32
871	fcmpne32 %d32, %d48, %l1
872	fsrc1	%d32, %d32
873	fsrc1	%d32, %d32
874	fsrc1	%d32, %d32
875	brnz,a	 %l1, .remcmp
876        sub     %i1, %i0, %i1           ! i1 gets the difference
877        add     %i0, 8, %i0
878        add     %i1, 8, %i1
879	sub	%i2, 8, %i2
880
881blkd6:
882        subcc   %i4, 8, %i4
883        blu,a,pn %ncc, .remcmp
884        sub     %i1, %i0, %i1           ! i1 gets the difference
885        faligndata %d6, %d8, %d48
886	ldd	[%i0], %d32
887	fcmpne32 %d32, %d48, %l1
888	fsrc1	%d32, %d32
889	fsrc1	%d32, %d32
890	fsrc1	%d32, %d32
891	brnz,a	 %l1, .remcmp
892        sub     %i1, %i0, %i1           ! i1 gets the difference
893        add     %i0, 8, %i0
894        add     %i1, 8, %i1
895	sub	%i2, 8, %i2
896
897blkd8:
898        subcc   %i4, 8, %i4
899        blu,a,pn %ncc, .remcmp
900        sub     %i1, %i0, %i1           ! i1 gets the difference
901        faligndata %d8, %d10, %d48
902	ldd	[%i0], %d32
903	fcmpne32 %d32, %d48, %l1
904	fsrc1	%d32, %d32
905	fsrc1	%d32, %d32
906	fsrc1	%d32, %d32
907	brnz,a	 %l1, .remcmp
908        sub     %i1, %i0, %i1           ! i1 gets the difference
909        add     %i0, 8, %i0
910        add     %i1, 8, %i1
911	sub	%i2, 8, %i2
912
913blkd10:
914        subcc   %i4, 8, %i4
915        blu,a,pn %ncc, .remcmp
916        sub     %i1, %i0, %i1           ! i1 gets the difference
917        faligndata %d10, %d12, %d48
918	ldd	[%i0], %d32
919	fcmpne32 %d32, %d48, %l1
920	fsrc1	%d32, %d32
921	fsrc1	%d32, %d32
922	fsrc1	%d32, %d32
923	brnz,a	 %l1, .remcmp
924        sub     %i1, %i0, %i1           ! i1 gets the difference
925        add     %i0, 8, %i0
926        add     %i1, 8, %i1
927	sub	%i2, 8, %i2
928
929blkd12:
930        subcc   %i4, 8, %i4
931        blu,a,pn %ncc, .remcmp
932        sub     %i1, %i0, %i1           ! i1 gets the difference
933        faligndata %d12, %d14, %d48
934	ldd	[%i0], %d32
935	fcmpne32 %d32, %d48, %l1
936	fsrc1	%d32, %d32
937	fsrc1	%d32, %d32
938	fsrc1	%d32, %d32
939	brnz,a	 %l1, .remcmp
940        sub     %i1, %i0, %i1           ! i1 gets the difference
941        add     %i0, 8, %i0
942        add     %i1, 8, %i1
943	sub	%i2, 8, %i2
944
945blkd14:
946        subcc   %i4, 8, %i4
947        blu,a,pn %ncc, .remcmp
948        sub     %i1, %i0, %i1           ! i1 gets the difference
949        ba,pt 	%ncc, blkleft
950	fmovd   %d14, %d0
951
952blkd16:
953        subcc   %i4, 8, %i4
954        blu,a,pn %ncc, .remcmp
955        sub     %i1, %i0, %i1           ! i1 gets the difference
956        faligndata %d16, %d18, %d48
957	ldd	[%i0], %d32
958	fcmpne32 %d32, %d48, %l1
959	fsrc1	%d32, %d32
960	fsrc1	%d32, %d32
961	fsrc1	%d32, %d32
962	brnz,a	 %l1, .remcmp
963        sub     %i1, %i0, %i1           ! i1 gets the difference
964        add     %i0, 8, %i0
965        add     %i1, 8, %i1
966	sub	%i2, 8, %i2
967
968blkd18:
969        subcc   %i4, 8, %i4
970        blu,a,pn %ncc, .remcmp
971        sub     %i1, %i0, %i1           ! i1 gets the difference
972        faligndata %d18, %d20, %d48
973	ldd	[%i0], %d32
974	fcmpne32 %d32, %d48, %l1
975	fsrc1	%d32, %d32
976	fsrc1	%d32, %d32
977	fsrc1	%d32, %d32
978	brnz,a	 %l1, .remcmp
979        sub     %i1, %i0, %i1           ! i1 gets the difference
980        add     %i0, 8, %i0
981        add     %i1, 8, %i1
982	sub	%i2, 8, %i2
983
984blkd20:
985        subcc   %i4, 8, %i4
986        blu,a,pn %ncc, .remcmp
987        sub     %i1, %i0, %i1           ! i1 gets the difference
988        faligndata %d20, %d22, %d48
989	ldd	[%i0], %d32
990	fcmpne32 %d32, %d48, %l1
991	fsrc1	%d32, %d32
992	fsrc1	%d32, %d32
993	fsrc1	%d32, %d32
994	brnz,a	 %l1, .remcmp
995        sub     %i1, %i0, %i1           ! i1 gets the difference
996        add     %i0, 8, %i0
997        add     %i1, 8, %i1
998	sub	%i2, 8, %i2
999
1000blkd22:
1001        subcc   %i4, 8, %i4
1002        blu,a,pn %ncc, .remcmp
1003        sub     %i1, %i0, %i1           ! i1 gets the difference
1004        faligndata %d22, %d24, %d48
1005	ldd	[%i0], %d32
1006	fcmpne32 %d32, %d48, %l1
1007	fsrc1	%d32, %d32
1008	fsrc1	%d32, %d32
1009	fsrc1	%d32, %d32
1010	brnz,a	 %l1, .remcmp
1011        sub     %i1, %i0, %i1           ! i1 gets the difference
1012        add     %i0, 8, %i0
1013        add     %i1, 8, %i1
1014	sub	%i2, 8, %i2
1015
1016blkd24:
1017        subcc   %i4, 8, %i4
1018        blu,a,pn %ncc, .remcmp
1019        sub     %i1, %i0, %i1           ! i1 gets the difference
1020        faligndata %d24, %d26, %d48
1021	ldd	[%i0], %d32
1022	fcmpne32 %d32, %d48, %l1
1023	fsrc1	%d32, %d32
1024	fsrc1	%d32, %d32
1025	fsrc1	%d32, %d32
1026	brnz,a	 %l1, .remcmp
1027        sub     %i1, %i0, %i1           ! i1 gets the difference
1028        add     %i0, 8, %i0
1029        add     %i1, 8, %i1
1030	sub	%i2, 8, %i2
1031
1032blkd26:
1033        subcc   %i4, 8, %i4
1034        blu,a,pn %ncc, .remcmp
1035        sub     %i1, %i0, %i1           ! i1 gets the difference
1036        faligndata %d26, %d28, %d48
1037	ldd	[%i0], %d32
1038	fcmpne32 %d32, %d48, %l1
1039	fsrc1	%d32, %d32
1040	fsrc1	%d32, %d32
1041	fsrc1	%d32, %d32
1042	brnz,a	 %l1, .remcmp
1043        sub     %i1, %i0, %i1           ! i1 gets the difference
1044        add     %i0, 8, %i0
1045        add     %i1, 8, %i1
1046	sub	%i2, 8, %i2
1047
1048blkd28:
1049        subcc   %i4, 8, %i4
1050        blu,a,pn %ncc, .remcmp
1051        sub     %i1, %i0, %i1           ! i1 gets the difference
1052        faligndata %d28, %d30, %d48
1053	ldd	[%i0], %d32
1054	fcmpne32 %d32, %d48, %l1
1055	fsrc1	%d32, %d32
1056	fsrc1	%d32, %d32
1057	fsrc1	%d32, %d32
1058	brnz,a	 %l1, .remcmp
1059        sub     %i1, %i0, %i1           ! i1 gets the difference
1060        add     %i0, 8, %i0
1061        add     %i1, 8, %i1
1062	sub	%i2, 8, %i2
1063
1064blkd30:
1065        subcc   %i4, 8, %i4
1066        blu,a,pn %ncc, .remcmp
1067        sub     %i1, %i0, %i1           ! i1 gets the difference
1068        fmovd   %d30, %d0
1069
1070	! This loop handles doubles remaining that were not loaded(ldda`ed)
1071	! in the Block Compare loop
1072blkleft:
1073        ldd     [%l7], %d2
1074        add     %l7, 8, %l7
1075        faligndata %d0, %d2, %d8
1076	ldd     [%i0], %d32
1077        fcmpne32 %d32, %d8, %l1
1078	fsrc1	%d2, %d0
1079	fsrc1	%d2, %d0
1080	fsrc1	%d2, %d0
1081	brnz,a	%l1, .remcmp
1082	sub     %i1, %i0, %i1           ! i1 gets the difference
1083        add     %i0, 8, %i0
1084        add     %i1, 8, %i1
1085        subcc   %i4, 8, %i4
1086        bgeu,pt  %ncc, blkleft
1087        sub     %i2, 8, %i2
1088
1089	ba	%ncc, .remcmp
1090	sub     %i1, %i0, %i1           ! i1 gets the difference
1091
10926:      ldub    [%i0 + %i1], %i5        ! byte compare loop
1093        inc     %i0
1094        cmp     %i4, %i5
1095        bne     %ncc, .bnoteq
1096.remcmp:
1097        deccc   %i2
1098        bgeu,a   %ncc, 6b
1099        ldub    [%i0], %i4
1100
1101exit:
1102	and     %l5, 0x4, %l5           ! fprs.du = fprs.dl = 0
1103	wr      %l5, %g0, %fprs         ! fprs = l5 - restore fprs
1104	membar  #StoreLoad|#StoreStore
1105        ret
1106        restore %g0, %g0, %o0
1107
1108
1109.bnoteq:
1110	and     %l5, 0x4, %l5           ! fprs.du = fprs.dl = 0
1111	wr      %l5, %g0, %fprs         ! fprs = l5 - restore fprs
1112	membar  #StoreLoad|#StoreStore
1113	sub	%i4, %i5, %i0		! return(*s1 - *s2)
1114	ret				! strings aren't equal
1115	restore %i0, %g0, %o0
1116
1117
1118
1119	SET_SIZE(memcmp)
1120