1 | /* |
---|

2 | * C library memcpy routine |
---|

3 | * |
---|

4 | * This routine has code to optimize performance on the CPU32+ |
---|

5 | * and another version for other 68k machines. |
---|

6 | * |
---|

7 | * It could be optimized more for machines with MOVE16 instructions. |
---|

8 | * |
---|

9 | * The routine is placed in this source directory to ensure that it |
---|

10 | * is picked up by all applications. |
---|

11 | * |
---|

12 | * W. Eric Norum |
---|

13 | * Saskatchewan Accelerator Laboratory |
---|

14 | * University of Saskatchewan |
---|

15 | * Saskatoon, Saskatchewan, CANADA |
---|

16 | * eric@skatter.usask.ca |
---|

17 | */ |
---|

18 | |
---|

19 | #include <string.h> |
---|

20 | #include <rtems/score/m68k.h> |
---|

21 | |
---|

22 | #if defined(__mcpu32__) |
---|

23 | #define COPYSETUP(n) n-- |
---|

24 | #define COPY(to,from,n,size) \ |
---|

25 | asm volatile ("1:\n" \ |
---|

26 | "\tmove." size " (%0)+,(%1)+\n" \ |
---|

27 | "\tdbf %2,1b\n" \ |
---|

28 | "\tsub.l #0x10000,%2\n" \ |
---|

29 | "\tbpl.b 1b\n" : \ |
---|

30 | "=a" (from), "=a" (to), "=d" (n) :\ |
---|

31 | "0" (from), "1" (to), "2" (n) : \ |
---|

32 | "cc", "memory") |
---|

33 | #else |
---|

34 | #define COPYSETUP(n) |
---|

35 | #define COPY(to,from,n,size) \ |
---|

36 | asm volatile ("1:\n" \ |
---|

37 | "\tmove." size " (%0)+,(%1)+\n" \ |
---|

38 | "\tsubq.l #1,%2\n\tbne.b 1b\n" : \ |
---|

39 | "=a" (from), "=a" (to), "=d" (n) :\ |
---|

40 | "0" (from), "1" (to), "2" (n) : \ |
---|

41 | "cc", "memory") |
---|

42 | #endif |
---|

43 | |
---|

44 | void * |
---|

45 | memcpy(void *s1, const void *s2, size_t n) |
---|

46 | { |
---|

47 | char *p1 = s1; |
---|

48 | const char *p2 = s2; |
---|

49 | |
---|

50 | if (n) { |
---|

51 | if (n < 16) { |
---|

52 | COPYSETUP (n); |
---|

53 | COPY (p1, p2, n, "b"); |
---|

54 | } |
---|

55 | else { |
---|

56 | int nbyte; |
---|

57 | int nl; |
---|

58 | nbyte = (int)p1 & 0x3; |
---|

59 | if (nbyte) { |
---|

60 | nbyte = 4 - nbyte; |
---|

61 | n -= nbyte; |
---|

62 | COPYSETUP (nbyte); |
---|

63 | COPY (p1, p2, nbyte, "b"); |
---|

64 | } |
---|

65 | #if (M68K_HAS_MISALIGNED == 0) |
---|

66 | /* |
---|

67 | * Take care of machines that can't |
---|

68 | * handle misaligned references. |
---|

69 | */ |
---|

70 | if ((int)p2 & 0x1) { |
---|

71 | COPYSETUP (n); |
---|

72 | COPY (p1, p2, n, "b"); |
---|

73 | return s1; |
---|

74 | } |
---|

75 | #endif |
---|

76 | nl = (unsigned int)n >> 2; |
---|

77 | COPYSETUP (nl); |
---|

78 | COPY (p1, p2, nl, "l"); |
---|

79 | nbyte = (int)n & 0x3; |
---|

80 | if (nbyte) { |
---|

81 | COPYSETUP (nbyte); |
---|

82 | COPY (p1, p2, nbyte, "b"); |
---|

83 | } |
---|

84 | } |
---|

85 | } |
---|

86 | return s1; |
---|

87 | } |
---|