1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /* From glibc-2.14, sysdeps/i386/memset.c */
10 typedef uint32_t op_t
;
12 void *memset(void *dstpp
, int c
, size_t len
)
15 unsigned long int dstp
= (unsigned long int)dstpp
;
17 #if (ENV_SEPARATE_ROMSTAGE && CONFIG(ASAN_IN_ROMSTAGE)) || \
18 (ENV_RAMSTAGE && CONFIG(ASAN_IN_RAMSTAGE))
19 check_memory_region((unsigned long)dstpp
, len
, true, _RET_IP_
);
22 /* This explicit register allocation improves code very much indeed. */
23 register op_t x
asm("ax");
27 /* Clear the direction flag, so filling will move forward. */
30 /* This threshold value is optimal. */
32 /* Fill X with four copies of the char we want to fill with. */
36 /* Adjust LEN for the bytes handled in the first loop. */
37 len
-= (-dstp
) % sizeof(op_t
);
40 * There are at least some bytes to set. No need to test for
41 * LEN == 0 in this alignment loop.
44 /* Fill bytes until DSTP is aligned on a longword boundary. */
47 "stosb" /* %0, %2, %3 */ :
48 "=D" (dstp
), "=c" (d0
) :
49 "0" (dstp
), "1" ((-dstp
) % sizeof(op_t
)), "a" (x
) :
55 "stosl" /* %0, %2, %3 */ :
56 "=D" (dstp
), "=c" (d0
) :
57 "0" (dstp
), "1" (len
/ sizeof(op_t
)), "a" (x
) :
62 /* Write the last few bytes. */
65 "stosb" /* %0, %2, %3 */ :
66 "=D" (dstp
), "=c" (d0
) :
67 "0" (dstp
), "1" (len
), "a" (x
) :