memmove.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright (C) 2004-2007 Atmel Corporation
  3. *
  4. * This file is subject to the terms and conditions of the GNU Lesser General
  5. * Public License. See the file "COPYING.LIB" in the main directory of this
  6. * archive for more details.
  7. */
  8. #define dst r12
  9. #define src r11
  10. #define len r10
  11. .text
  12. .global memmove
  13. .type memmove, @function
  14. memmove:
  15. cp.w src, dst
  16. brge __GI_memcpy
  17. add dst, len
  18. add src, len
  19. pref src[-1]
  20. /*
  21. * The rest is basically the same as in memcpy.S except that
  22. * the direction is reversed.
  23. */
  24. cp.w len, 32
  25. brge .Lmore_than_31
  26. sub len, 1
  27. retlt r12
  28. 1: ld.ub r8, --src
  29. st.b --dst, r8
  30. sub len, 1
  31. brge 1b
  32. retal r12
  33. .Lmore_than_31:
  34. pushm r0-r7, lr
  35. /* Check alignment */
  36. mov r8, src
  37. andl r8, 31, COH
  38. brne .Lunaligned_src
  39. mov r8, r12
  40. andl r8, 3, COH
  41. brne .Lunaligned_dst
  42. .Laligned_copy:
  43. sub len, 32
  44. brlt .Lless_than_32
  45. 1: /* Copy 32 bytes at a time */
  46. sub src, 32
  47. ldm src, r0-r7
  48. sub dst, 32
  49. sub len, 32
  50. stm dst, r0-r7
  51. brge 1b
  52. .Lless_than_32:
  53. /* Copy 16 more bytes if possible */
  54. sub len, -16
  55. brlt .Lless_than_16
  56. sub src, 16
  57. ldm src, r0-r3
  58. sub dst, 16
  59. sub len, 16
  60. stm dst, r0-r3
  61. .Lless_than_16:
  62. /* Do the remaining as byte copies */
  63. sub len, -16
  64. breq 2f
  65. 1: ld.ub r0, --src
  66. st.b --dst, r0
  67. sub len, 1
  68. brne 1b
  69. 2: popm r0-r7, pc
  70. .Lunaligned_src:
  71. /* Make src cacheline-aligned. r8 = (src & 31) */
  72. sub len, r8
  73. 1: ld.ub r0, --src
  74. st.b --dst, r0
  75. sub r8, 1
  76. brne 1b
  77. /* If dst is word-aligned, we're ready to go */
  78. pref src[-4]
  79. mov r8, 3
  80. tst dst, r8
  81. breq .Laligned_copy
  82. .Lunaligned_dst:
  83. /* src is aligned, but dst is not. Expect bad performance */
  84. sub len, 4
  85. brlt 2f
  86. 1: ld.w r0, --src
  87. st.w --dst, r0
  88. sub len, 4
  89. brge 1b
  90. 2: neg len
  91. add pc, pc, len << 2
  92. .rept 3
  93. ld.ub r0, --src
  94. st.b --dst, r0
  95. .endr
  96. popm r0-r7, pc
  97. .size memmove, . - memmove
  98. libc_hidden_def(memmove)