/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* memcmp(s1, s2, len)
*
* Compare n bytes: s1>s2: >0 s1==s2: 0 s1<s2: <0
*
* Fast assembler language version of the following C-program for memcmp
* which represents the `standard' for the C-library.
*
* int
* memcmp(const void *s1, const void *s2, size_t n)
* {
* if (s1 != s2 && n != 0) {
* const char *ps1 = s1;
* const char *ps2 = s2;
* do {
* if (*ps1++ != *ps2++)
* return(ps1[-1] - ps2[-1]);
* } while (--n != 0);
* }
* return (0);
* }
*/
#include <sys/asm_linkage.h>
.chkdbl:
.bytcmp:
.cmpeq:
.noteq:
sub %o4, %o5, %o0 ! return(*s1 - *s2)
! double word compare - using ldd and faligndata. Compares upto
! 8 byte multiple count and does byte compare for the residual.
.dwcmp:
prefetch [%o0 + (2 * BLOCK_SIZE)], #one_read
prefetch [%o1 + (2 * BLOCK_SIZE)], #one_read
! if fprs.fef == 0, set it. Checking it, reqires 2 instructions.
! So set it anyway, without checking.
rd %fprs, %o3 ! o3 = fprs
wr %g0, 0x4, %fprs ! fprs.fef = 1
andn %o2, 7, %o4 ! o4 has 8 byte aligned cnt
sub %o4, 8, %o4
alignaddr %o1, %g0, %g1
ldd [%g1], %d0
4:
add %g1, 8, %g1
ldd [%g1], %d2
ldd [%o0], %d6
prefetch [%g1 + (3 * BLOCK_SIZE)], #one_read
prefetch [%o0 + (3 * BLOCK_SIZE)], #one_read
faligndata %d0, %d2, %d8
fcmpne32 %d6, %d8, %o5
.residcmp:
ba 6f
6:
.dnoteq: