* Copy a block of memory, handling overlap. * This is the routine that actually implements * (the portable versions of) bcopy, memcpy, and memmove. */
| 69 | * (the portable versions of) bcopy, memcpy, and memmove. |
| 70 | */ |
| 71 | void * |
| 72 | memcpy(void *dst0, const void *src0, size_t length) |
| 73 | { |
| 74 | char *dst; |
| 75 | const char *src; |
| 76 | size_t t; |
| 77 | |
| 78 | dst = dst0; |
| 79 | src = src0; |
| 80 | |
| 81 | if (length == 0 || dst == src) { /* nothing to do */ |
| 82 | goto done; |
| 83 | } |
| 84 | |
| 85 | /* |
| 86 | * Macros: loop-t-times; and loop-t-times, t>0 |
| 87 | */ |
| 88 | #define TLOOP(s) if (t) TLOOP1(s) |
| 89 | #define TLOOP1(s) do { s; } while (--t) |
| 90 | |
| 91 | if ((unsigned long)dst < (unsigned long)src) { |
| 92 | /* |
| 93 | * Copy forward. |
| 94 | */ |
| 95 | t = (size_t)src; /* only need low bits */ |
| 96 | |
| 97 | if ((t | (uintptr_t)dst) & wmask) { |
| 98 | /* |
| 99 | * Try to align operands. This cannot be done |
| 100 | * unless the low bits match. |
| 101 | */ |
| 102 | if ((t ^ (uintptr_t)dst) & wmask || length < wsize) { |
| 103 | t = length; |
| 104 | } else { |
| 105 | t = wsize - (t & wmask); |
| 106 | } |
| 107 | |
| 108 | length -= t; |
| 109 | TLOOP1(*dst++ = *src++); |
| 110 | } |
| 111 | /* |
| 112 | * Copy whole words, then mop up any trailing bytes. |
| 113 | */ |
| 114 | t = length / wsize; |
| 115 | TLOOP(*(word *)dst = *(const word *)src; src += wsize; |
| 116 | dst += wsize); |
| 117 | t = length & wmask; |
| 118 | TLOOP(*dst++ = *src++); |
| 119 | } else { |
| 120 | /* |
| 121 | * Copy backwards. Otherwise essentially the same. |
| 122 | * Alignment works as before, except that it takes |
| 123 | * (t&wmask) bytes to align, not wsize-(t&wmask). |
| 124 | */ |
| 125 | src += length; |
| 126 | dst += length; |
| 127 | t = (uintptr_t)src; |
| 128 |
no outgoing calls