mb/asus/p8z77-m: Drop GPIO by I/O
[coreboot2.git] / src / arch / x86 / memset.c
blob142dda33d8f676066550cfe9705f261eb97258ae
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /* From glibc-2.14, sysdeps/i386/memset.c */
5 #include <string.h>
6 #include <stdint.h>
7 #include <stdbool.h>
8 #include <asan.h>
10 typedef uint32_t op_t;
12 void *memset(void *dstpp, int c, size_t len)
14 int d0;
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_);
20 #endif
22 /* This explicit register allocation improves code very much indeed. */
23 register op_t x asm("ax");
25 x = (unsigned char)c;
27 /* Clear the direction flag, so filling will move forward. */
28 asm volatile("cld");
30 /* This threshold value is optimal. */
31 if (len >= 12) {
32 /* Fill X with four copies of the char we want to fill with. */
33 x |= (x << 8);
34 x |= (x << 16);
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. */
45 asm volatile(
46 "rep\n"
47 "stosb" /* %0, %2, %3 */ :
48 "=D" (dstp), "=c" (d0) :
49 "0" (dstp), "1" ((-dstp) % sizeof(op_t)), "a" (x) :
50 "memory");
52 /* Fill longwords. */
53 asm volatile(
54 "rep\n"
55 "stosl" /* %0, %2, %3 */ :
56 "=D" (dstp), "=c" (d0) :
57 "0" (dstp), "1" (len / sizeof(op_t)), "a" (x) :
58 "memory");
59 len %= sizeof(op_t);
62 /* Write the last few bytes. */
63 asm volatile(
64 "rep\n"
65 "stosb" /* %0, %2, %3 */ :
66 "=D" (dstp), "=c" (d0) :
67 "0" (dstp), "1" (len), "a" (x) :
68 "memory");
70 return dstpp;