/* FUNCTION <>---set an area of memory INDEX memset ANSI_SYNOPSIS #include void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>); TRAD_SYNOPSIS #include void *memset(<[dst]>, <[c]>, <[length]>) void *<[dst]>; int <[c]>; size_t <[length]>; DESCRIPTION This function converts the argument <[c]> into an unsigned char and fills the first <[length]> characters of the array pointed to by <[dst]> to the value. RETURNS <> returns the value of <[m]>. PORTABILITY <> is ANSI C. <> requires no supporting OS subroutines. QUICKREF memset ansi pure */ #include #include "_ansi.h" #define LBLOCKSIZE (sizeof(long)) #define ROCKBOX_UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1)) #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE) _PTR _DEFUN (memset, (m, c, n), _PTR m _AND int c _AND size_t n) { #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) char *s = (char *) m; while (n-- != 0) { *s++ = (char) c; } return m; #else char *s = (char *) m; unsigned int i; unsigned long buffer; unsigned long *aligned_addr; if (!TOO_SMALL (n) && !ROCKBOX_UNALIGNED (m)) { /* If we get this far, we know that n is large and m is word-aligned. */ aligned_addr = (unsigned long*)m; /* Store C into each char sized location in BUFFER so that we can set large blocks quickly. */ c &= 0xff; if (LBLOCKSIZE == 4) { buffer = (c << 8) | c; buffer |= (buffer << 16); } else { buffer = 0; for (i = 0; i < LBLOCKSIZE; i++) buffer = (buffer << 8) | c; } while (n >= LBLOCKSIZE*4) { *aligned_addr++ = buffer; *aligned_addr++ = buffer; *aligned_addr++ = buffer; *aligned_addr++ = buffer; n -= 4*LBLOCKSIZE; } while (n >= LBLOCKSIZE) { *aligned_addr++ = buffer; n -= LBLOCKSIZE; } /* Pick up the remainder with a bytewise loop. */ s = (char*)aligned_addr; } while (n--) { *s++ = (char)c; } return m; #endif /* not PREFER_SIZE_OVER_SPEED */ }