/* Optimized 32-bit memset implementation for POWER6.
Copyright (C) 1997-2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <sysdep.h>
/* void * [r3] memset (void *s [r3], int c [r4], size_t n [r5]));
Returns 's'.
The memset is done in three sizes: byte (8 bits), word (32 bits),
cache line (1024 bits). There is a special case for setting cache lines
to 0, to take advantage of the dcbz instruction. */
.machine power6
EALIGN (memset, 7, 0)
CALL_MCOUNT
#define rTMP r0
#define rRTN r3 /* Initial value of 1st argument. */
#define rMEMP0 r3 /* Original value of 1st arg. */
#define rCHR r4 /* Char to set in each byte. */
#define rLEN r5 /* Length of region to set. */
#define rMEMP r6 /* Address at which we are storing. */
#define rALIGN r7 /* Number of bytes we are setting now (when aligning). */
#define rMEMP2 r8
#define rNEG64 r8 /* Constant -64 for clearing with dcbz. */
#define rMEMP3 r9 /* Alt mem pointer. */
L(_memset):
/* Take care of case for size <= 4. */
cmplwi cr1, rLEN, 4
andi. rALIGN, rMEMP0, 3
mr rMEMP, rMEMP0
ble- cr1, L(small)
/* Align to word boundary. */
cmplwi cr5, rLEN, 31
insrwi rCHR, rCHR, 8, 16 /* Replicate byte to halfword. */
beq+ L(aligned)
mtcrf 0x01, rMEMP0
subfic rALIGN, rALIGN, 4
add rMEMP, rMEMP, rALIGN
sub rLEN, rLEN, rALIGN
bf+ 31, L(g0)
stb rCHR, 0(rMEMP0)
bt 30, L(aligned)
L(g0):
sth rCHR, -2(rMEMP)
.align 4
/* Handle the case of size < 31. */
L(aligned):
mtcrf 0x01, rLEN
insrwi rCHR, rCHR, 16, 0 /* Replicate halfword to word. */
ble cr5, L(medium)
/* Align to 32-byte boundary. */
andi. rALIGN, rMEMP, 0x1C
subfic rALIGN, rALIGN