source: trunk/libs/newlib/src/newlib/libc/string/memset.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.0 KB
Line 
1/*
2FUNCTION
3        <<memset>>---set an area of memory
4
5INDEX
6        memset
7
8SYNOPSIS
9        #include <string.h>
10        void *memset(void *<[dst]>, int <[c]>, size_t <[length]>);
11
12DESCRIPTION
13        This function converts the argument <[c]> into an unsigned
14        char and fills the first <[length]> characters of the array
15        pointed to by <[dst]> to the value.
16
17RETURNS
18        <<memset>> returns the value of <[dst]>.
19
20PORTABILITY
21<<memset>> is ANSI C.
22
23    <<memset>> requires no supporting OS subroutines.
24
25QUICKREF
26        memset ansi pure
27*/
28
29#include <string.h>
30#include "local.h"
31
32#define LBLOCKSIZE (sizeof(long))
33#define UNALIGNED(X)   ((long)X & (LBLOCKSIZE - 1))
34#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
35
36void *
37__inhibit_loop_to_libcall
38memset (void *m,
39        int c,
40        size_t n)
41{
42  char *s = (char *) m;
43
44#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
45  unsigned int i;
46  unsigned long buffer;
47  unsigned long *aligned_addr;
48  unsigned int d = c & 0xff;    /* To avoid sign extension, copy C to an
49                                   unsigned variable.  */
50
51  while (UNALIGNED (s))
52    {
53      if (n--)
54        *s++ = (char) c;
55      else
56        return m;
57    }
58
59  if (!TOO_SMALL (n))
60    {
61      /* If we get this far, we know that n is large and s is word-aligned. */
62      aligned_addr = (unsigned long *) s;
63
64      /* Store D into each char sized location in BUFFER so that
65         we can set large blocks quickly.  */
66      buffer = (d << 8) | d;
67      buffer |= (buffer << 16);
68      for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
69        buffer = (buffer << i) | buffer;
70
71      /* Unroll the loop.  */
72      while (n >= LBLOCKSIZE*4)
73        {
74          *aligned_addr++ = buffer;
75          *aligned_addr++ = buffer;
76          *aligned_addr++ = buffer;
77          *aligned_addr++ = buffer;
78          n -= 4*LBLOCKSIZE;
79        }
80
81      while (n >= LBLOCKSIZE)
82        {
83          *aligned_addr++ = buffer;
84          n -= LBLOCKSIZE;
85        }
86      /* Pick up the remainder with a bytewise loop.  */
87      s = (char*)aligned_addr;
88    }
89
90#endif /* not PREFER_SIZE_OVER_SPEED */
91
92  while (n--)
93    *s++ = (char) c;
94
95  return m;
96}
Note: See TracBrowser for help on using the repository browser.