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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
29 * char *memset(sp, c, n)
31 * Set an array of n chars starting at sp to the character c.
34 * Fast assembler language version of the following C-program for memset
35 * which represents the `standard' for the C-library.
38 * memset(void *sp1, int c, size_t n)
51 * For small 6 or fewer bytes stores, bytes will be stored.
53 * For less than 32 bytes stores, align the address on 4 byte boundary.
54 * Then store as many 4-byte chunks, followed by trailing bytes.
56 * For sizes greater than 32 bytes, align the address on 8 byte boundary.
58 * store as many 8-bytes chunks to block align the address
59 * store using ASI_BLK_INIT_ST_QUAD_LDD_P
61 * Store as many 8-byte chunks, followed by trialing bytes.
65 #include <sys/asm_linkage.h>
66 #include <sys/niagaraasi.h>
69 ANSI_PRAGMA_WEAK
(memset
,function
)
76 mov
%o0
, %o5
! copy sp1 before using it
77 cmp %o2
, 7 ! if small counts
, just write bytes
79 and %o1
, 0xff, %o1
! o1 is
(char
)c
82 or %o1
, %o3
, %o1
! now o1 has
2 bytes of c
87 or %o1
, %o3
, %o1
! now o1 has
4 bytes of c
90 or %o1
, %o3
, %o1
! now o1 has
8 bytes of c
93 andcc
%o5
, 7, %o3
! is sp1 aligned on
a 8 byte bound
94 bz
,pt
%ncc
, .blkalign ! already double aligned
95 sub %o3
, 8, %o3
! -(bytes till double aligned
)
96 add %o2
, %o3
, %o2
! update o2 with new count
98 ! Set
-(%o3
) bytes till sp1 double aligned
99 1: stb %o1
, [%o5
] ! there is at least
1 byte to set
100 inccc
%o3
! byte clearing loop
104 ! Now sp1 is double aligned
(sp1 is found in
%o5
)
106 mov ASI_BLK_INIT_ST_QUAD_LDD_P
, %asi
108 cmp %o2
, 0x40 ! check if there are
64 bytes to set
112 andcc
%o5
, 63, %o3
! is sp1 block aligned?
113 bz
,pt
%ncc
, .blkwr ! now block aligned
114 sub %o3
, 64, %o3
! o3 is
-(bytes till block aligned
)
115 add %o2
, %o3
, %o2
! o2 is the remainder
117 ! Store
-(%o3
) bytes till
dst is block
(64 byte
) aligned.
118 ! Use double word stores.
119 ! Recall that
dst is already double word aligned
126 ! Now sp1 is block aligned
128 and %o2
, 63, %o3
! calc bytes left after blk store.
129 andn
%o2
, 63, %o4
! calc size of blocks in bytes
131 cmp %o4
, 0x100 ! check if there are
256 bytes to set
135 stxa
%o1
, [%o5+
0x0]%asi
136 stxa
%o1
, [%o5+
0x40]%asi
137 stxa
%o1
, [%o5+
0x80]%asi
138 stxa
%o1
, [%o5+
0xc0]%asi
140 stxa
%o1
, [%o5+
0x8]%asi
141 stxa
%o1
, [%o5+
0x10]%asi
142 stxa
%o1
, [%o5+
0x18]%asi
143 stxa
%o1
, [%o5+
0x20]%asi
144 stxa
%o1
, [%o5+
0x28]%asi
145 stxa
%o1
, [%o5+
0x30]%asi
146 stxa
%o1
, [%o5+
0x38]%asi
148 stxa
%o1
, [%o5+
0x48]%asi
149 stxa
%o1
, [%o5+
0x50]%asi
150 stxa
%o1
, [%o5+
0x58]%asi
151 stxa
%o1
, [%o5+
0x60]%asi
152 stxa
%o1
, [%o5+
0x68]%asi
153 stxa
%o1
, [%o5+
0x70]%asi
154 stxa
%o1
, [%o5+
0x78]%asi
156 stxa
%o1
, [%o5+
0x88]%asi
157 stxa
%o1
, [%o5+
0x90]%asi
158 stxa
%o1
, [%o5+
0x98]%asi
159 stxa
%o1
, [%o5+
0xa0]%asi
160 stxa
%o1
, [%o5+
0xa8]%asi
161 stxa
%o1
, [%o5+
0xb0]%asi
162 stxa
%o1
, [%o5+
0xb8]%asi
164 stxa
%o1
, [%o5+
0xc8]%asi
165 stxa
%o1
, [%o5+
0xd0]%asi
166 stxa
%o1
, [%o5+
0xd8]%asi
167 stxa
%o1
, [%o5+
0xe0]%asi
168 stxa
%o1
, [%o5+
0xe8]%asi
169 stxa
%o1
, [%o5+
0xf0]%asi
170 stxa
%o1
, [%o5+
0xf8]%asi
178 cmp %o4
, 0x40 ! check if
64 bytes to set
182 stxa
%o1
, [%o5+
0x0]%asi
183 stxa
%o1
, [%o5+
0x8]%asi
184 stxa
%o1
, [%o5+
0x10]%asi
185 stxa
%o1
, [%o5+
0x18]%asi
186 stxa
%o1
, [%o5+
0x20]%asi
187 stxa
%o1
, [%o5+
0x28]%asi
188 stxa
%o1
, [%o5+
0x30]%asi
189 stxa
%o1
, [%o5+
0x38]%asi
196 ! Set the remaining doubles
198 mov ASI_PNF
, %asi
! restore
%asi to default
199 ! ASI_PRIMARY_NOFAULT value
200 subcc
%o3
, 8, %o3
! Can we store any doubles?
202 and %o2
, 7, %o2
! calc bytes left after doubles
205 stx %o1
, [%o5
] ! store the doubles
214 andcc
%o5
, 3, %o3
! is sp1 aligned on
a word boundary
216 andn
%o2
, 3, %o3
! create word sized count in
%o3
218 dec %o2
! decrement count
219 stb %o1
, [%o5
] ! clear
a byte
224 st %o1
, [%o5
] ! 4-byte writing loop
229 and %o2
, 3, %o2
! leftover count
, if any
232 ! Set the remaining bytes
, if any
244 retl
! %o0 was preserved