memcpy.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * Copyright (C) 2002 Mark Debbage (Mark.Debbage@superh.com)
  3. *
  4. * May be copied or modified under the terms of the GNU General Public
  5. * License. See linux/COPYING for more information.
  6. *
  7. */
  8. #include <linux/types.h>
  9. #include <asm/string.h>
  10. // This is a simplistic optimization of memcpy to increase the
  11. // granularity of access beyond one byte using aligned
  12. // loads and stores. This is not an optimal implementation
  13. // for SH-5 (especially with regard to prefetching and the cache),
  14. // and a better version should be provided later ...
  15. void *memcpy(void *dest, const void *src, size_t count)
  16. {
  17. char *d = (char *) dest, *s = (char *) src;
  18. if (count >= 32) {
  19. int i = 8 - (((unsigned long) d) & 0x7);
  20. if (i != 8)
  21. while (i-- && count--) {
  22. *d++ = *s++;
  23. }
  24. if (((((unsigned long) d) & 0x7) == 0) &&
  25. ((((unsigned long) s) & 0x7) == 0)) {
  26. while (count >= 32) {
  27. unsigned long long t1, t2, t3, t4;
  28. t1 = *(unsigned long long *) (s);
  29. t2 = *(unsigned long long *) (s + 8);
  30. t3 = *(unsigned long long *) (s + 16);
  31. t4 = *(unsigned long long *) (s + 24);
  32. *(unsigned long long *) (d) = t1;
  33. *(unsigned long long *) (d + 8) = t2;
  34. *(unsigned long long *) (d + 16) = t3;
  35. *(unsigned long long *) (d + 24) = t4;
  36. d += 32;
  37. s += 32;
  38. count -= 32;
  39. }
  40. while (count >= 8) {
  41. *(unsigned long long *) d =
  42. *(unsigned long long *) s;
  43. d += 8;
  44. s += 8;
  45. count -= 8;
  46. }
  47. }
  48. if (((((unsigned long) d) & 0x3) == 0) &&
  49. ((((unsigned long) s) & 0x3) == 0)) {
  50. while (count >= 4) {
  51. *(unsigned long *) d = *(unsigned long *) s;
  52. d += 4;
  53. s += 4;
  54. count -= 4;
  55. }
  56. }
  57. if (((((unsigned long) d) & 0x1) == 0) &&
  58. ((((unsigned long) s) & 0x1) == 0)) {
  59. while (count >= 2) {
  60. *(unsigned short *) d = *(unsigned short *) s;
  61. d += 2;
  62. s += 2;
  63. count -= 2;
  64. }
  65. }
  66. }
  67. while (count--) {
  68. *d++ = *s++;
  69. }
  70. return d;
  71. }