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.
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.
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]
23 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
31 * Compare n bytes: s1>s2: >0 s1==s2: 0 s1<s2: <0
33 * Fast assembler language version of the following C-program for memcmp
34 * which represents the `standard' for the C-library.
37 * memcmp(const void *s1, const void *s2, size_t n)
39 * if (s1 != s2 && n != 0) {
40 * const char *ps1 = s1;
41 * const char *ps2 = s2;
43 * if (*ps1++ != *ps2++)
44 * return(ps1[-1] - ps2[-1]);
51 #include <sys/asm_linkage.h>
52 #include <sys/machasi.h>
56 ANSI_PRAGMA_WEAK
(memcmp
,function
)
59 cmp %o0
, %o1
! s1
== s2?
61 prefetch
[%o0
], #one_read
62 prefetch
[%o1
], #one_read
64 ! for small counts byte compare immediately
67 mov
%o2
, %o3
! o3
<= 48
69 ! Count
> 48. We will byte compare (8 + num of bytes to dbl align)
70 ! bytes. We assume that most miscompares will occur in the
1st 8 bytes
72 prefetch
[%o0
+ (1 * BLOCK_SIZE
)], #one_read
73 prefetch
[%o1
+ (1 * BLOCK_SIZE
)], #one_read
76 and %o0
, 7, %o4
! is s1 aligned on
a 8 byte bound
77 mov
8, %o3
! o2
> 48; o3
= 8
78 sub %o4
, 8, %o4
! o4
= -(num of bytes to dbl align
)
80 sub %o3
, %o4
, %o3
! o3
= 8 + (num of bytes to dbl align
)
82 1: ldub
[%o1
], %o5
! byte compare loop
93 ! Check to see if there are more bytes to compare
94 cmp %o2
, 0 ! is o2
> 0
95 bgu
%ncc
, .dwcmp ! we should already be dbl aligned
98 retl
! strings compare equal
102 retl
! strings aren
't equal
103 sub %o4, %o5, %o0 ! return(*s1 - *s2)
106 ! double word compare - using ldd and faligndata. Compares upto
107 ! 8 byte multiple count and does byte compare for the residual.
110 prefetch [%o0 + (2 * BLOCK_SIZE)], #one_read
111 prefetch [%o1 + (2 * BLOCK_SIZE)], #one_read
113 ! if fprs.fef == 0, set it. Checking it, reqires 2 instructions.
114 ! So set it anyway, without checking.
115 rd %fprs, %o3 ! o3 = fprs
116 wr %g0, 0x4, %fprs ! fprs.fef = 1
118 andn %o2, 7, %o4 ! o4 has 8 byte aligned cnt
120 alignaddr %o1, %g0, %g1
126 prefetch [%g1 + (3 * BLOCK_SIZE)], #one_read
127 prefetch [%o0 + (3 * BLOCK_SIZE)], #one_read
128 faligndata %d0, %d2, %d8
129 fcmpne32 %d6, %d8, %o5
130 fsrc1 %d6, %d6 ! 2 fsrc1's added since o5 cannot
131 fsrc1
%d8
, %d8
! be used for
3 cycles else we
132 fmovd
%d2
, %d0
! create
9 bubbles in the pipeline
134 sub %o1
, %o0
, %o1
! o1 gets the difference
143 sub %o1
, %o0
, %o1
! o1 gets the difference
145 5: ldub
[%o0
+ %o1
], %o5
! byte compare loop
154 and %o3
, 0x4, %o3
! fprs.du
= fprs.dl
= 0
155 wr
%o3
, %g0
, %fprs
! fprs
= o3
- restore fprs
157 sub %g0
, %g0
, %o0
! strings compare equal
160 and %o3
, 0x4, %o3
! fprs.du
= fprs.dl
= 0
161 wr
%o3
, %g0
, %fprs
! fprs
= o3
- restore fprs
163 sub %o4
, %o5
, %o0
! return
(*s1
- *s2
)