Rev 3427 | Rev 3728 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3427 | Rev 3727 | ||
|---|---|---|---|
| Line 72... | Line 72... | ||
| 72 | ((unsigned char *) (((unsigned long *) src) + i))[j]; |
72 | ((unsigned char *) (((unsigned long *) src) + i))[j]; |
| 73 | 73 | ||
| 74 | return (char *) dst; |
74 | return (char *) dst; |
| 75 | } |
75 | } |
| 76 | 76 | ||
| - | 77 | /** Copy memory block. */ |
|
| 77 | void *memcpy(void *dst, const void *src, size_t n) |
78 | void *memcpy(void *dst, const void *src, size_t n) |
| 78 | { |
79 | { |
| 79 | int i, j; |
80 | size_t i; |
| - | 81 | size_t mod, fill; |
|
| - | 82 | size_t word_size; |
|
| - | 83 | size_t n_words; |
|
| - | 84 | ||
| - | 85 | const unsigned long *srcw; |
|
| - | 86 | unsigned long *dstw; |
|
| - | 87 | const uint8_t *srcb; |
|
| - | 88 | uint8_t *dstb; |
|
| - | 89 | ||
| - | 90 | word_size = sizeof(unsigned long); |
|
| 80 | 91 | ||
| - | 92 | /* |
|
| - | 93 | * Are source and destination addresses congruent modulo word_size? |
|
| - | 94 | * If not, use unaligned_memcpy(). |
|
| - | 95 | */ |
|
| - | 96 | ||
| 81 | if (((long) dst & (sizeof(long) - 1)) || |
97 | if (((uintptr_t) dst & (word_size - 1)) != |
| 82 | ((long) src & (sizeof(long) - 1))) |
98 | ((uintptr_t) src & (word_size - 1))) |
| 83 | return unaligned_memcpy(dst, src, n); |
99 | return unaligned_memcpy(dst, src, n); |
| 84 | 100 | ||
| - | 101 | /* |
|
| 85 | for (i = 0; i < n / sizeof(unsigned long); i++) |
102 | * mod is the address modulo word size. fill is the length of the |
| - | 103 | * initial buffer segment before the first word boundary. |
|
| 86 | ((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
104 | * If the buffer is very short, use unaligned_memcpy(), too. |
| 87 | 105 | */ |
|
| - | 106 | ||
| 88 | for (j = 0; j < n % sizeof(unsigned long); j++) |
107 | mod = (uintptr_t) dst & (word_size - 1); |
| - | 108 | fill = word_size - mod; |
|
| - | 109 | if (fill > n) fill = n; |
|
| - | 110 | ||
| - | 111 | /* Copy the initial segment. */ |
|
| - | 112 | ||
| - | 113 | srcb = src; |
|
| - | 114 | dstb = dst; |
|
| - | 115 | ||
| - | 116 | i = fill; |
|
| - | 117 | while (i-- > 0) |
|
| - | 118 | *dstb++ = *srcb++; |
|
| - | 119 | ||
| - | 120 | /* Compute remaining length. */ |
|
| - | 121 | ||
| - | 122 | n -= fill; |
|
| - | 123 | if (n == 0) return dst; |
|
| - | 124 | ||
| - | 125 | /* Pointers to aligned segment. */ |
|
| - | 126 | ||
| 89 | ((unsigned char *) (((unsigned long *) dst) + i))[j] = |
127 | dstw = (unsigned long *) dstb; |
| 90 | ((unsigned char *) (((unsigned long *) src) + i))[j]; |
128 | srcw = (const unsigned long *) srcb; |
| - | 129 | ||
| - | 130 | n_words = n / word_size; /* Number of whole words to copy. */ |
|
| - | 131 | n -= n_words * word_size; /* Remaining bytes at the end. */ |
|
| - | 132 | ||
| - | 133 | /* "Fast" copy. */ |
|
| - | 134 | i = n_words; |
|
| - | 135 | while (i-- > 0) |
|
| - | 136 | *dstw++ = *srcw++; |
|
| - | 137 | ||
| 91 | 138 | /* |
|
| - | 139 | * Copy the rest. |
|
| - | 140 | */ |
|
| - | 141 | ||
| - | 142 | srcb = (const uint8_t *) srcw; |
|
| - | 143 | dstb = (uint8_t *) dstw; |
|
| - | 144 | ||
| - | 145 | i = n; |
|
| - | 146 | while (i-- > 0) |
|
| - | 147 | *dstb++ = *srcb++; |
|
| - | 148 | ||
| 92 | return (char *) dst; |
149 | return dst; |
| 93 | } |
150 | } |
| 94 | 151 | ||
| 95 | void *memmove(void *dst, const void *src, size_t n) |
152 | void *memmove(void *dst, const void *src, size_t n) |
| 96 | { |
153 | { |
| 97 | int i, j; |
154 | int i, j; |