PageRenderTime 46ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/mm-utils/memcpy.c

http://github.com/matteobertozzi/carthage
C | 184 lines | 127 code | 20 blank | 37 comment | 15 complexity | 1660b181adea898f53918b7c9b2cbdd7 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /* [ memcpy.c ] - Memory Copy
  2. * -----------------------------------------------------------------------------
  3. * Copyright (c) 2010, Matteo Bertozzi
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * * Neither the name of the author nor the
  14. * names of its contributors may be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL MATTEO BERTOZZI BE LIABLE FOR ANY
  21. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. * -----------------------------------------------------------------------------
  28. */
  29. #include <stdint.h>
  30. #include <stddef.h>
  31. #define __memcpy_forward(dst, src, n) \
  32. do { \
  33. const unsigned long *isrc = (const unsigned long *)src; \
  34. unsigned long *idst = (unsigned long *)dst; \
  35. const unsigned char *csrc; \
  36. unsigned char *cdst; \
  37. \
  38. /* Fast copy while l >= sizeof(unsigned long) */ \
  39. for (; n >= sizeof(unsigned long); n -= sizeof(unsigned long)) \
  40. *idst++ = *isrc++; \
  41. \
  42. /* Copy the rest of the buffer */ \
  43. csrc = (const unsigned char *)isrc; \
  44. cdst = (unsigned char *)idst; \
  45. while (n--) \
  46. *cdst++ = *csrc++; \
  47. } while (0)
  48. #define __memcpy_forward_sized(type, dst, src, n) \
  49. do { \
  50. const type *isrc = (const type *)src; \
  51. type *idst = (type *)dest; \
  52. \
  53. for (; n >= sizeof(type); n -= sizeof(type)) \
  54. *idst++ = *isrc++; \
  55. } while (0)
  56. #define __memcpy_backward(dst, src, n) \
  57. do { \
  58. const unsigned long *isrc = (const unsigned long *)(src + n); \
  59. unsigned long *idst = (unsigned long *)(dst + n); \
  60. const unsigned char *csrc; \
  61. unsigned char *cdst; \
  62. \
  63. /* Fast copy while n >= sizeof(unsigned long) */ \
  64. for (; n >= sizeof(unsigned long); n -= sizeof(unsigned long)) \
  65. *idst-- = *isrc--; \
  66. \
  67. /* Copy the rest of the buffer */ \
  68. csrc = (const unsigned char *)isrc; \
  69. cdst = (unsigned char *)idst; \
  70. while (n--) \
  71. *cdst-- = *csrc--; \
  72. } while (0)
  73. #define __memcpy_backward_sized(type, dst, src, n) \
  74. do { \
  75. const type *isrc = (const type *)(src + n); \
  76. type *idst = (type *)(dst + n); \
  77. \
  78. for (; n > sizeof(type); n -= sizeof(type)) \
  79. *idst-- = *isrc--; \
  80. } while (0)
  81. /*
  82. * Mem-Copy Forward
  83. */
  84. void *memcpy (void *dest, const void *src, size_t n) {
  85. __memcpy_forward(dest, src, n);
  86. return(dest);
  87. }
  88. void *memcpy8 (void *dest, const void *src, size_t n) {
  89. __memcpy_forward_sized(uint8_t, dest, src, n);
  90. return(dest);
  91. }
  92. void *memcpy16 (void *dest, const void *src, size_t n) {
  93. __memcpy_forward_sized(uint16_t, dest, src, n);
  94. return(dest);
  95. }
  96. void *memcpy32 (void *dest, const void *src, size_t n) {
  97. __memcpy_forward_sized(uint32_t, dest, src, n);
  98. return(dest);
  99. }
  100. void *memcpy64 (void *dest, const void *src, size_t n) {
  101. __memcpy_forward_sized(uint64_t, dest, src, n);
  102. return(dest);
  103. }
  104. /*
  105. * Mem-Copy backward
  106. */
  107. void *membcpy (void *dest, const void *src, size_t n) {
  108. __memcpy_backward(dest, src, n);
  109. return(dest);
  110. }
  111. void *membcpy8 (void *dest, const void *src, size_t n) {
  112. __memcpy_backward_sized(uint8_t, dest, src, n);
  113. return(dest);
  114. }
  115. void *membcpy16 (void *dest, const void *src, size_t n) {
  116. __memcpy_backward_sized(uint16_t, dest, src, n);
  117. return(dest);
  118. }
  119. void *membcpy32 (void *dest, const void *src, size_t n) {
  120. __memcpy_backward_sized(uint32_t, dest, src, n);
  121. return(dest);
  122. }
  123. void *membcpy64 (void *dest, const void *src, size_t n) {
  124. __memcpy_backward_sized(uint64_t, dest, src, n);
  125. return(dest);
  126. }
  127. /*
  128. * Mem-Move
  129. */
  130. void *memmove (void *dest, const void *src, size_t n) {
  131. if (dest < src)
  132. __memcpy_forward(dest, src, n);
  133. else
  134. __memcpy_backward(dest, src, n);
  135. return(dest);
  136. }
  137. void *memmove8 (void *dest, const void *src, size_t n) {
  138. if (dest < src)
  139. __memcpy_forward_sized(uint8_t, dest, src, n);
  140. else
  141. __memcpy_backward_sized(uint8_t, dest, src, n);
  142. return(dest);
  143. }
  144. void *memmove16 (void *dest, const void *src, size_t n) {
  145. if (dest < src)
  146. __memcpy_forward_sized(uint16_t, dest, src, n);
  147. else
  148. __memcpy_backward_sized(uint16_t, dest, src, n);
  149. return(dest);
  150. }
  151. void *memmove32 (void *dest, const void *src, size_t n) {
  152. if (dest < src)
  153. __memcpy_forward_sized(uint32_t, dest, src, n);
  154. else
  155. __memcpy_backward_sized(uint32_t, dest, src, n);
  156. return(dest);
  157. }
  158. void *memmove64 (void *dest, const void *src, size_t n) {
  159. if (dest < src)
  160. __memcpy_forward_sized(uint64_t, dest, src, n);
  161. else
  162. __memcpy_forward_sized(uint64_t, dest, src, n);
  163. return(dest);
  164. }