bcopy.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*-
  2. * SPDX-License-Identifier: BSD-3-Clause
  3. * Copyright (c) 1990 The Regents of the University of California.
  4. *
  5. * All rights reserved.
  6. *
  7. * This code is derived from software contributed to Berkeley by
  8. * Chris Torek.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * 3. Neither the name of the University nor the names of its contributors
  19. * may be used to endorse or promote products derived from this software
  20. * without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32. * SUCH DAMAGE.
  33. */
  34. #if defined(LIBC_SCCS) && !defined(lint)
  35. #if 0
  36. static char *sccsid = "from: @(#)bcopy.c 5.11 (Berkeley) 6/21/91";
  37. #endif
  38. #if 0
  39. static char *rcsid = "$NetBSD: bcopy.c,v 1.2 1997/04/16 22:09:41 thorpej Exp $";
  40. #endif
  41. #endif /* LIBC_SCCS and not lint */
  42. #include <sys/cdefs.h>
  43. __FBSDID("$FreeBSD$");
  44. #include <sys/param.h>
  45. #ifdef _KERNEL
  46. #include <sys/systm.h>
  47. #else
  48. #include <string.h>
  49. #endif
  50. #undef memcpy
  51. #undef memmove
  52. #undef bcopy
  53. /*
  54. * sizeof(word) MUST BE A POWER OF TWO
  55. * SO THAT wmask BELOW IS ALL ONES
  56. */
  57. typedef long word; /* "word" used for optimal copy speed */
  58. #define wsize sizeof(word)
  59. #define wmask (wsize - 1)
  60. /*
  61. * Copy a block of memory, handling overlap.
  62. * This is the routine that actually implements
  63. * (the portable versions of) bcopy, memcpy, and memmove.
  64. */
  65. void *
  66. memcpy(void *dst0, const void *src0, size_t length)
  67. {
  68. char *dst;
  69. const char *src;
  70. size_t t;
  71. dst = dst0;
  72. src = src0;
  73. if (length == 0 || dst == src) { /* nothing to do */
  74. goto done;
  75. }
  76. /*
  77. * Macros: loop-t-times; and loop-t-times, t>0
  78. */
  79. #define TLOOP(s) if (t) TLOOP1(s)
  80. #define TLOOP1(s) do { s; } while (--t)
  81. if ((unsigned long)dst < (unsigned long)src) {
  82. /*
  83. * Copy forward.
  84. */
  85. t = (size_t)src; /* only need low bits */
  86. if ((t | (uintptr_t)dst) & wmask) {
  87. /*
  88. * Try to align operands. This cannot be done
  89. * unless the low bits match.
  90. */
  91. if ((t ^ (uintptr_t)dst) & wmask || length < wsize) {
  92. t = length;
  93. } else {
  94. t = wsize - (t & wmask);
  95. }
  96. length -= t;
  97. TLOOP1(*dst++ = *src++);
  98. }
  99. /*
  100. * Copy whole words, then mop up any trailing bytes.
  101. */
  102. t = length / wsize;
  103. TLOOP(*(word *)dst = *(const word *)src; src += wsize;
  104. dst += wsize);
  105. t = length & wmask;
  106. TLOOP(*dst++ = *src++);
  107. } else {
  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. if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) {
  118. t = length;
  119. } else {
  120. t &= wmask;
  121. }
  122. length -= t;
  123. TLOOP1(*--dst = *--src);
  124. }
  125. t = length / wsize;
  126. TLOOP(src -= wsize; dst -= wsize;
  127. *(word *)dst = *(const word *)src);
  128. t = length & wmask;
  129. TLOOP(*--dst = *--src);
  130. }
  131. done:
  132. return (dst0);
  133. }
  134. __strong_reference(memcpy, memmove);
  135. void
  136. (bcopy)(const void *src0, void *dst0, size_t length)
  137. {
  138. memcpy(dst0, src0, length);
  139. }