memcpy.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file COPYING in the main directory of this archive
  4. * for more details.
  5. */
  6. #include <linux/module.h>
  7. #include <linux/string.h>
  8. void *memcpy(void *to, const void *from, size_t n)
  9. {
  10. void *xto = to;
  11. size_t temp;
  12. if (!n)
  13. return xto;
  14. if ((long)to & 1) {
  15. char *cto = to;
  16. const char *cfrom = from;
  17. *cto++ = *cfrom++;
  18. to = cto;
  19. from = cfrom;
  20. n--;
  21. }
  22. #if defined(CONFIG_M68000)
  23. if ((long)from & 1) {
  24. char *cto = to;
  25. const char *cfrom = from;
  26. for (; n; n--)
  27. *cto++ = *cfrom++;
  28. return xto;
  29. }
  30. #endif
  31. if (n > 2 && (long)to & 2) {
  32. short *sto = to;
  33. const short *sfrom = from;
  34. *sto++ = *sfrom++;
  35. to = sto;
  36. from = sfrom;
  37. n -= 2;
  38. }
  39. temp = n >> 2;
  40. if (temp) {
  41. long *lto = to;
  42. const long *lfrom = from;
  43. #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
  44. for (; temp; temp--)
  45. *lto++ = *lfrom++;
  46. #else
  47. size_t temp1;
  48. asm volatile (
  49. " movel %2,%3\n"
  50. " andw #7,%3\n"
  51. " lsrl #3,%2\n"
  52. " negw %3\n"
  53. " jmp %%pc@(1f,%3:w:2)\n"
  54. "4: movel %0@+,%1@+\n"
  55. " movel %0@+,%1@+\n"
  56. " movel %0@+,%1@+\n"
  57. " movel %0@+,%1@+\n"
  58. " movel %0@+,%1@+\n"
  59. " movel %0@+,%1@+\n"
  60. " movel %0@+,%1@+\n"
  61. " movel %0@+,%1@+\n"
  62. "1: dbra %2,4b\n"
  63. " clrw %2\n"
  64. " subql #1,%2\n"
  65. " jpl 4b"
  66. : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
  67. : "0" (lfrom), "1" (lto), "2" (temp));
  68. #endif
  69. to = lto;
  70. from = lfrom;
  71. }
  72. if (n & 2) {
  73. short *sto = to;
  74. const short *sfrom = from;
  75. *sto++ = *sfrom++;
  76. to = sto;
  77. from = sfrom;
  78. }
  79. if (n & 1) {
  80. char *cto = to;
  81. const char *cfrom = from;
  82. *cto = *cfrom;
  83. }
  84. return xto;
  85. }
  86. EXPORT_SYMBOL(memcpy);