coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
memset.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 /* From glibc-2.14, sysdeps/i386/memset.c */
4 
5 #include <string.h>
6 #include <stdint.h>
7 #include <stdbool.h>
8 #include <asan.h>
9 
10 typedef uint32_t op_t;
11 
12 void *memset(void *dstpp, int c, size_t len)
13 {
14  int d0;
15  unsigned long int dstp = (unsigned long int) dstpp;
16 
17 #if (ENV_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
21 
22  /* This explicit register allocation improves code very much indeed. */
23  register op_t x asm("ax");
24 
25  x = (unsigned char) c;
26 
27  /* Clear the direction flag, so filling will move forward. */
28  asm volatile("cld");
29 
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);
35 
36  /* Adjust LEN for the bytes handled in the first loop. */
37  len -= (-dstp) % sizeof(op_t);
38 
39  /*
40  * There are at least some bytes to set. No need to test for
41  * LEN == 0 in this alignment loop.
42  */
43 
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");
51 
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);
60  }
61 
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");
69 
70  return dstpp;
71 }
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
uint32_t op_t
Definition: memset.c:10
void check_memory_region(unsigned long addr, size_t size, bool write, unsigned long ret_ip)
Definition: asan.c:264
#define _RET_IP_
Definition: asan.h:20
int x
Definition: edid.c:994
unsigned int uint32_t
Definition: stdint.h:14
#define c(value, pmcreg, dst_bits)