1 /* Optimized 32-bit memset implementation for POWER6.
2 Copyright (C) 1997,99, 2000,02,03,06,2007 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, write to the Free
17 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
24 /* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
27 The memset is done in three sizes: byte (8 bits), word (32 bits),
28 cache line (1024 bits). There is a special case for setting cache lines
29 to 0, to take advantage of the dcbz instruction. */
32 EALIGN (BP_SYM (memset), 7, 0)
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 rMEMP3 r9 /* Alt mem pointer. */
47 /* Take care of case for size <= 4. */
49 andi. rALIGN, rMEMP0, 3
52 /* Align to word boundary. */
54 rlwimi rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword. */
57 subfic rALIGN, rALIGN, 4
58 add rMEMP, rMEMP, rALIGN
59 sub rLEN, rLEN, rALIGN
67 /* Handle the case of size < 31. */
70 rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */
72 /* Align to 32-byte boundary. */
73 andi. rALIGN, rMEMP, 0x1C
74 subfic rALIGN, rALIGN, 0x20
77 add rMEMP, rMEMP, rALIGN
78 sub rLEN, rLEN, rALIGN
79 cmplwi cr1, rALIGN, 0x10
89 stwu rCHR, -16(rMEMP2)
90 L(a2): bf 29, L(caligned)
94 /* Now aligned to a 32 byte boundary. */
97 clrrwi. rALIGN, rLEN, 5
99 beq cr1, L(zloopstart) /* Special case for clearing memory using dcbz. */
101 beq L(medium) /* We may not actually get to do a full line. */
103 /* Storing a non-zero "c" value. We are aligned at a sector (32-byte)
104 boundary may not be at cache line (128-byte) boundary. */
106 /* memset in 32-byte chunks until we get to a cache line boundary.
107 If rLEN is less then the distance to the next cache-line boundary use
108 cacheAligned1 code to finish the tail. */
112 blt cr1,L(cacheAligned1)
114 beq L(nzCacheAligned)
123 andi. rTMP,rMEMP3,127
127 beq L(nzCacheAligned)
140 beq L(nzCacheAligned)
142 /* At this point we can overrun the store queue (pipe reject) so it is
143 time to slow things down. The store queue can merge two adjacent
144 stores into a single L1/L2 op, but the L2 is clocked at 1/2 the CPU.
145 So we add "group ending nops" to guarantee that we dispatch only two
146 stores every other cycle. */
165 blt cr1,L(cacheAligned1)
168 /* Now we are aligned to the cache line and can use dcbtst. */
173 blt cr1,L(cacheAligned1)
174 blt cr6,L(nzCacheAligned128)
176 L(nzCacheAligned128):
197 /* At this point we can overrun the store queue (pipe reject) so it is
198 time to slow things down. The store queue can merge two adjacent
199 stores into a single L1/L2 op, but the L2 is clocked at 1/2 the CPU.
200 So we add "group ending nops" to guarantee that we dispatch only one
233 blt cr6,L(cacheAligned1)
237 b L(nzCacheAligned256)
239 L(nzCacheAligned256):
243 /* When we are not in libc we should use only GPRs to avoid the FPU lock
280 /* We are in libc and this is a long memset so we can use FPRs and can afford
281 occasional FPU locked interrupts. */
301 bge cr1,L(nzCacheAligned256)
306 /* Storing a zero "c" value. We are aligned at a sector (32-byte)
307 boundary but may not be at cache line (128-byte) boundary. If the
308 remaining length spans a full cache line we can use the Data cache
309 block zero instruction. */
311 /* memset in 32-byte chunks until we get to a cache line boundary.
312 If rLEN is less then the distance to the next cache-line boundary use
313 cacheAligned1 code to finish the tail. */
318 blt cr1,L(cacheAligned1)
329 andi. rTMP,rMEMP3,127
348 /* At this point we can overrun the store queue (pipe reject) so it is
349 time to slow things down. The store queue can merge two adjacent
350 stores into a single L1/L2 op, but the L2 is clocked at 1/2 the CPU.
351 So we add "group ending nops" to guarantee that we dispatch only two
352 stores every other cycle. */
372 blt cr1,L(cacheAligned1)
373 blt cr6,L(cacheAligned128)
376 /* Now we are aligned to the cache line and can use dcbz. */
381 blt cr1,L(cacheAligned1)
385 blt cr6,L(cacheAligned128)
386 bgt cr5,L(cacheAligned512)
393 blt cr1,L(cacheAligned1)
394 blt cr6,L(cacheAligned128)
397 /* A simple loop for the longer (>640 bytes) lengths. This form limits
398 the branch miss-predicted to exactly 1 at loop exit.*/
401 blt cr1,L(cacheAligned1)
414 bge cr6,L(cacheAligned256)
415 blt cr1,L(cacheAligned1)
424 blt cr1,L(handletail32)
438 blt cr1,L(handletail32)
452 blt cr1,L(handletail32)
453 /* At this point we can overrun the store queue (pipe reject) so it is
454 time to slow things down. The store queue can merge two adjacent
455 stores into a single L1/L2 op, but the L2 is clocked at 1/2 the CPU.
456 So we add "group ending nops" to guarantee that we dispatch only two
457 stores every other cycle. */
479 /* We are here because the length or remainder (rLEN) is less than the
480 cache line/sector size and does not justify aggressive loop unrolling.
481 So set up the preconditions for L(medium) and go there. */
490 /* Memset of 4 bytes or less. */
503 /* Memset of 0-31 bytes. */
508 add rMEMP, rMEMP, rLEN
510 bt- 31, L(medium_31t)
511 bt- 30, L(medium_30t)
515 bge cr1, L(medium_27t)
523 bf- 30, L(medium_30f)
526 bf- 29, L(medium_29f)
529 blt cr1, L(medium_27f)
534 stwu rCHR, -16(rMEMP)
541 END (BP_SYM (memset))
542 libc_hidden_builtin_def (memset)