Embedded Artistry libc
C Standard Library Support for Bare-metal Systems
memcpy.c File Reference
#include <string.h>
Include dependency graph for memcpy.c:

Go to the source code of this file.

Macros

#define wsize   sizeof(word)
 
#define wmask   (wsize - 1)
 
#define TLOOP(s)   if (t) TLOOP1(s)
 
#define TLOOP1(s)   do { s; } while (--t)
 

Typedefs

typedef int word
 

Functions

void * memcpy (void *dst0, const void *src0, size_t length)
 

Macro Definition Documentation

◆ TLOOP

#define TLOOP (   s)    if (t) TLOOP1(s)

◆ TLOOP1

#define TLOOP1 (   s)    do { s; } while (--t)

◆ wmask

#define wmask   (wsize - 1)

Definition at line 42 of file memcpy.c.

◆ wsize

#define wsize   sizeof(word)

Definition at line 41 of file memcpy.c.

Typedef Documentation

◆ word

typedef int word

Definition at line 39 of file memcpy.c.

Function Documentation

◆ memcpy()

void* memcpy ( void *  dst0,
const void *  src0,
size_t  length 
)

Definition at line 49 of file memcpy.c.

50 {
51  char* dst = dst0;
52  const char* src = src0;
53  size_t t;
54 
55  if(length == 0 || dst == src)
56  {
57  { /* nothing to do */
58  goto done;
59  }
60  }
61 
62 /*
63  * Macros: loop-t-times; and loop-t-times, t>0
64  */
65 // clang-format off
66 #define TLOOP(s) if (t) TLOOP1(s)
67 #define TLOOP1(s) do { s; } while (--t)
68  // clang-format on
69 
70  if((uintptr_t)dst < (uintptr_t)src)
71  {
72  /*
73  * Copy forward.
74  */
75  t = (uintptr_t)src; /* only need low bits */
76  if((t | (uintptr_t)dst) & wmask)
77  {
78  /*
79  * Try to align operands. This cannot be done
80  * unless the low bits match.
81  */
82  if((t ^ (uintptr_t)dst) & wmask || length < wsize)
83  {
84  {
85  t = length;
86  }
87  }
88  else
89  {
90  {
91  t = wsize - (t & wmask);
92  }
93  }
94  length -= t;
95  TLOOP1(*dst++ = *src++);
96  }
97  /*
98  * Copy whole words, then mop up any trailing bytes.
99  */
100  t = length / wsize;
101  // Silence warning for alignment change by casting to void*
102  TLOOP(*(word*)(void*)dst = *(const word*)(const void*)src; src += wsize; dst += wsize);
103  t = length & wmask;
104  TLOOP(*dst++ = *src++);
105  }
106  else
107  {
108  /*
109  * Copy backwards. Otherwise essentially the same.
110  * Alignment works as before, except that it takes
111  * (t&wmask) bytes to align, not wsize-(t&wmask).
112  */
113  src += length;
114  dst += length;
115  t = (uintptr_t)src;
116  if((t | (uintptr_t)dst) & wmask)
117  {
118  if((t ^ (uintptr_t)dst) & wmask || length <= wsize)
119  {
120  {
121  t = length;
122  }
123  }
124  else
125  {
126  {
127  t &= wmask;
128  }
129  }
130  length -= t;
131  TLOOP1(*--dst = *--src);
132  }
133  t = length / wsize;
134  // Silence warning for alignment change by casting to void*
135  TLOOP(src -= wsize; dst -= wsize; *(word*)(void*)dst = *(const word*)(const void*)src);
136  t = length & wmask;
137  TLOOP(*--dst = *--src);
138  }
139 done:
140  return (dst0);
141 }
#define wsize
Definition: memcpy.c:41
#define TLOOP1(s)
#define wmask
Definition: memcpy.c:42
int word
Definition: memcpy.c:39
#define TLOOP(s)

References TLOOP, TLOOP1, wmask, and wsize.