1 /* Optimized memset implementation for PowerPC64.
2 Copyright (C) 1997-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
21 /* void * [r3] memset (void *s [r3], int c [r4], size_t n [r5]));
24 The memset is done in three sizes: byte (8 bits), word (32 bits),
25 cache line (256 bits). There is a special case for setting cache lines
26 to 0, to take advantage of the dcbz instruction. */
29 # define MEMSET memset
32 ENTRY_TOCLESS (MEMSET, 5)
36 #define rRTN r3 /* Initial value of 1st argument. */
37 #define rMEMP0 r3 /* Original value of 1st arg. */
38 #define rCHR r4 /* Char to set in each byte. */
39 #define rLEN r5 /* Length of region to set. */
40 #define rMEMP r6 /* Address at which we are storing. */
41 #define rALIGN r7 /* Number of bytes we are setting now (when aligning). */
44 #define rNEG64 r8 /* Constant -64 for clearing with dcbz. */
45 #define rCLS r8 /* Cache line size obtained from static. */
46 #define rCLM r9 /* Cache line size mask to check for cache alignment. */
48 /* Take care of case for size <= 4. */
50 andi. rALIGN, rMEMP0, 7
54 /* Align to doubleword boundary. */
56 insrdi rCHR, rCHR, 8, 48 /* Replicate byte to halfword. */
59 subfic rALIGN, rALIGN, 8
60 cror 28,30,31 /* Detect odd word aligned. */
61 add rMEMP, rMEMP, rALIGN
62 sub rLEN, rLEN, rALIGN
63 insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */
65 /* Process the even word of doubleword. */
74 /* Process the odd word of doubleword. */
76 bf 28, L(g4x) /* If false, word aligned on odd word. */
83 /* Handle the case of size < 31. */
85 insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */
89 /* Align to 32-byte boundary. */
90 andi. rALIGN, rMEMP, 0x18
91 subfic rALIGN, rALIGN, 0x20
92 insrdi rCHR, rCHR, 32, 0 /* Replicate word to double word. */
95 add rMEMP, rMEMP, rALIGN
96 sub rLEN, rLEN, rALIGN
97 cmplwi cr1, rALIGN, 0x10
100 stdu rCHR, -8(rMEMP2)
101 L(a1): blt cr1, L(a2)
103 stdu rCHR, -16(rMEMP2)
106 /* Now aligned to a 32 byte boundary. */
109 clrrdi. rALIGN, rLEN, 5
111 beq cr1, L(zloopstart) /* Special case for clearing memory using dcbz. */
115 beq L(medium) /* We may not actually get to do a full line. */
116 clrldi. rLEN, rLEN, 59
117 add rMEMP, rMEMP, rALIGN
121 L(c3): dcbtst rNEG64, rMEMP
125 stdu rCHR, -32(rMEMP)
132 stdu rCHR, -32(rMEMP)
134 add rMEMP, rMEMP, rALIGN
138 /* Clear lines of memory in 128-byte chunks. */
140 /* If the remaining length is less the 32 bytes, don't bother getting
141 the cache line size. */
143 li rCLS,128 /* cache line size is 128 */
145 /* Now we know the cache line size, and it is not 32-bytes, but
146 we may not yet be aligned to the cache line. May have a partial
147 line to fill, so touch it 1st. */
152 blt cr1,L(handletail32)
162 /* Now we are aligned to the cache line and can use dcbz. */
165 blt cr1,L(handletail32)
171 /* We are here because the cache line size was set and was not 32-bytes
172 and the remainder (rLEN) is less than the actual cache line size.
173 So set up the preconditions for L(nondcbz) and go there. */
175 clrrwi. rALIGN, rLEN, 5
180 /* Memset of 8 bytes or less. */
203 /* Memset of 0-31 bytes. */
206 insrdi rCHR, rCHR, 32, 0 /* Replicate word to double word. */
209 add rMEMP, rMEMP, rLEN
211 bt- 31, L(medium_31t)
212 bt- 30, L(medium_30t)
214 bt- 29, L(medium_29t)
216 bge- cr1, L(medium_27t)
223 bf- 30, L(medium_30f)
226 bf- 29, L(medium_29f)
229 blt- cr1, L(medium_27f)
232 stdu rCHR, -16(rMEMP)
238 END_GEN_TB (MEMSET,TB_TOCLESS)
239 libc_hidden_builtin_def (memset)