diff options
Diffstat (limited to 'newlib/libc/string/memset.c')
-rw-r--r-- | newlib/libc/string/memset.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/newlib/libc/string/memset.c b/newlib/libc/string/memset.c index 55d2ce180..ac3590ea4 100644 --- a/newlib/libc/string/memset.c +++ b/newlib/libc/string/memset.c @@ -7,7 +7,7 @@ INDEX ANSI_SYNOPSIS #include <string.h> - void *memset(void *<[dst]>, int <[c]>, size_t <[length]>); + void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>); TRAD_SYNOPSIS #include <string.h> @@ -22,7 +22,7 @@ DESCRIPTION pointed to by <[dst]> to the value. RETURNS - <<memset>> returns the value of <[dst]>. + <<memset>> returns the value of <[m]>. PORTABILITY <<memset>> is ANSI C. @@ -39,42 +39,48 @@ QUICKREF #define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1)) #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE) -_PTR +_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; -#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) + while (n-- != 0) + { + *s++ = (char) c; + } + + return m; +#else + char *s = (char *) m; int i; unsigned long buffer; unsigned long *aligned_addr; unsigned int d = c & 0xff; /* To avoid sign extension, copy C to an unsigned variable. */ - while (UNALIGNED (s)) + if (!TOO_SMALL (n) && !UNALIGNED (m)) { - if (n--) - *s++ = (char) c; - else - return m; - } - - if (!TOO_SMALL (n)) - { - /* If we get this far, we know that n is large and s is word-aligned. */ - aligned_addr = (unsigned long *) s; + /* If we get this far, we know that n is large and m is word-aligned. */ + aligned_addr = (unsigned long*)m; /* Store D into each char sized location in BUFFER so that we can set large blocks quickly. */ - buffer = (d << 8) | d; - buffer |= (buffer << 16); - for (i = 32; i < LBLOCKSIZE * 8; i <<= 1) - buffer = (buffer << i) | buffer; + if (LBLOCKSIZE == 4) + { + buffer = (d << 8) | d; + buffer |= (buffer << 16); + } + else + { + buffer = 0; + for (i = 0; i < LBLOCKSIZE; i++) + buffer = (buffer << 8) | d; + } - /* Unroll the loop. */ while (n >= LBLOCKSIZE*4) { *aligned_addr++ = buffer; @@ -93,10 +99,11 @@ _DEFUN (memset, (m, c, n), s = (char*)aligned_addr; } -#endif /* not PREFER_SIZE_OVER_SPEED */ - while (n--) - *s++ = (char) c; + { + *s++ = (char)d; + } return m; +#endif /* not PREFER_SIZE_OVER_SPEED */ } |