rt_memcpy_iar.S 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. ;/*
  2. ; * Copyright (c) 2006-2020, RT-Thread Development Team
  3. ; *
  4. ; * SPDX-License-Identifier: Apache-2.0
  5. ; *
  6. ; * Change Logs:
  7. ; * Date Author Notes
  8. ; * 2020-12-23 Meco Man porting to RT-Thread
  9. ; */
  10. ;********************************************************************************************************
  11. ;
  12. ; Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
  13. ;
  14. ; SPDX-License-Identifier: APACHE-2.0
  15. ;
  16. ; This software is subject to an open source license and is distributed by
  17. ; Silicon Laboratories Inc. pursuant to the terms of the Apache License,
  18. ; Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
  19. ;
  20. ;********************************************************************************************************
  21. ;********************************************************************************************************
  22. ; PUBLIC FUNCTIONS
  23. ;********************************************************************************************************
  24. PUBLIC rt_memcpy
  25. ;********************************************************************************************************
  26. ; CODE GENERATION DIRECTIVES
  27. ;********************************************************************************************************
  28. RSEG CODE:CODE:NOROOT(2)
  29. ;********************************************************************************************************
  30. ; rt_memcpy_asm()
  31. ;
  32. ; Description : Copy data octets from one buffer to another buffer.
  33. ;
  34. ; Argument(s) : pdest Pointer to destination memory buffer.
  35. ;
  36. ; psrc Pointer to source memory buffer.
  37. ;
  38. ; size Number of data buffer octets to copy.
  39. ;
  40. ; Return(s) : pdest Pointer to destination memory buffer.
  41. ;
  42. ; Caller(s) : Application.
  43. ;
  44. ; Note(s) : (1) Null copies allowed (i.e. 0-octet size).
  45. ;
  46. ; (2) Memory buffers NOT checked for overlapping.
  47. ;
  48. ; (3) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN'
  49. ; address boundary.
  50. ;
  51. ; (4) ARM Cortex-M3 processors use a subset of the ARM Thumb-2 instruction set which does
  52. ; NOT support 16-bit conditional branch instructions but ONLY supports 8-bit conditional
  53. ; branch instructions.
  54. ;
  55. ; Therefore, branches exceeding 8-bit, signed, relative offsets :
  56. ;
  57. ; (a) CANNOT be implemented with conditional branches; but ...
  58. ; (b) MUST be implemented with non-conditional branches.
  59. ;********************************************************************************************************
  60. ; void rt_memcpy (void *pdest, ; ==> R0
  61. ; void *psrc, ; ==> R1
  62. ; rt_ubase_t size) ; ==> R2
  63. rt_memcpy:
  64. CMP R0, #0
  65. BNE rt_memcpy_1
  66. BX LR ; return if pdest == NULL
  67. rt_memcpy_1:
  68. CMP R1, #0
  69. BNE rt_memcpy_2
  70. BX LR ; return if psrc == NULL
  71. rt_memcpy_2:
  72. CMP R2, #0
  73. BNE rt_memcpy_3
  74. BX LR ; return if size == 0
  75. rt_memcpy_3:
  76. STMFD SP!, {R3-R12} ; save registers on stack
  77. PUSH {R0} ; save pdest
  78. chk_align_32: ; check if both dest & src 32-bit aligned
  79. AND R3, R0, #0x03
  80. AND R4, R1, #0x03
  81. CMP R3, R4
  82. BNE chk_align_16 ; not 32-bit aligned, check for 16-bit alignment
  83. RSB R3, R3, #0x04 ; compute 1-2-3 pre-copy bytes (to align to the next 32-bit boundary)
  84. AND R3, R3, #0x03
  85. pre_copy_1:
  86. CMP R3, #1 ; copy 1-2-3 bytes (to align to the next 32-bit boundary)
  87. BCC copy_32_1 ; start real 32-bit copy
  88. CMP R2, #1 ; check if any more data to copy
  89. BCS pre_copy_1_cont
  90. B rt_memcpy_end ; no more data to copy (see Note #4b)
  91. pre_copy_1_cont:
  92. LDRB R4, [R1], #1
  93. STRB R4, [R0], #1
  94. SUB R3, R3, #1
  95. SUB R2, R2, #1
  96. B pre_copy_1
  97. chk_align_16: ; check if both dest & src 16-bit aligned
  98. AND R3, R0, #0x01
  99. AND R4, R1, #0x01
  100. CMP R3, R4
  101. BEQ pre_copy_2
  102. B copy_08_1 ; not 16-bit aligned, start 8-bit copy (see Note #4b)
  103. pre_copy_2:
  104. CMP R3, #1 ; copy 1 byte (to align to the next 16-bit boundary)
  105. BCC copy_16_1 ; start real 16-bit copy
  106. LDRB R4, [R1], #1
  107. STRB R4, [R0], #1
  108. SUB R3, R3, #1
  109. SUB R2, R2, #1
  110. B pre_copy_2
  111. copy_32_1:
  112. CMP R2, #(04*10*09) ; Copy 9 chunks of 10 32-bit words (360 octets per loop)
  113. BCC copy_32_2
  114. LDMIA R1!, {R3-R12}
  115. STMIA R0!, {R3-R12}
  116. LDMIA R1!, {R3-R12}
  117. STMIA R0!, {R3-R12}
  118. LDMIA R1!, {R3-R12}
  119. STMIA R0!, {R3-R12}
  120. LDMIA R1!, {R3-R12}
  121. STMIA R0!, {R3-R12}
  122. LDMIA R1!, {R3-R12}
  123. STMIA R0!, {R3-R12}
  124. LDMIA R1!, {R3-R12}
  125. STMIA R0!, {R3-R12}
  126. LDMIA R1!, {R3-R12}
  127. STMIA R0!, {R3-R12}
  128. LDMIA R1!, {R3-R12}
  129. STMIA R0!, {R3-R12}
  130. LDMIA R1!, {R3-R12}
  131. STMIA R0!, {R3-R12}
  132. SUB R2, R2, #(04*10*09)
  133. B copy_32_1
  134. copy_32_2:
  135. CMP R2, #(04*10*01) ; Copy chunks of 10 32-bit words (40 octets per loop)
  136. BCC copy_32_3
  137. LDMIA R1!, {R3-R12}
  138. STMIA R0!, {R3-R12}
  139. SUB R2, R2, #(04*10*01)
  140. B copy_32_2
  141. copy_32_3:
  142. CMP R2, #(04*01*01) ; Copy remaining 32-bit words
  143. BCC copy_16_1
  144. LDR R3, [R1], #4
  145. STR R3, [R0], #4
  146. SUB R2, R2, #(04*01*01)
  147. B copy_32_3
  148. copy_16_1:
  149. CMP R2, #(02*01*16) ; Copy chunks of 16 16-bit words (32 bytes per loop)
  150. BCC copy_16_2
  151. LDRH R3, [R1], #2
  152. STRH R3, [R0], #2
  153. LDRH R3, [R1], #2
  154. STRH R3, [R0], #2
  155. LDRH R3, [R1], #2
  156. STRH R3, [R0], #2
  157. LDRH R3, [R1], #2
  158. STRH R3, [R0], #2
  159. LDRH R3, [R1], #2
  160. STRH R3, [R0], #2
  161. LDRH R3, [R1], #2
  162. STRH R3, [R0], #2
  163. LDRH R3, [R1], #2
  164. STRH R3, [R0], #2
  165. LDRH R3, [R1], #2
  166. STRH R3, [R0], #2
  167. LDRH R3, [R1], #2
  168. STRH R3, [R0], #2
  169. LDRH R3, [R1], #2
  170. STRH R3, [R0], #2
  171. LDRH R3, [R1], #2
  172. STRH R3, [R0], #2
  173. LDRH R3, [R1], #2
  174. STRH R3, [R0], #2
  175. LDRH R3, [R1], #2
  176. STRH R3, [R0], #2
  177. LDRH R3, [R1], #2
  178. STRH R3, [R0], #2
  179. LDRH R3, [R1], #2
  180. STRH R3, [R0], #2
  181. LDRH R3, [R1], #2
  182. STRH R3, [R0], #2
  183. SUB R2, R2, #(02*01*16)
  184. B copy_16_1
  185. copy_16_2:
  186. CMP R2, #(02*01*01) ; Copy remaining 16-bit words
  187. BCC copy_08_1
  188. LDRH R3, [R1], #2
  189. STRH R3, [R0], #2
  190. SUB R2, R2, #(02*01*01)
  191. B copy_16_2
  192. copy_08_1:
  193. CMP R2, #(01*01*16) ; Copy chunks of 16 8-bit words (16 bytes per loop)
  194. BCC copy_08_2
  195. LDRB R3, [R1], #1
  196. STRB R3, [R0], #1
  197. LDRB R3, [R1], #1
  198. STRB R3, [R0], #1
  199. LDRB R3, [R1], #1
  200. STRB R3, [R0], #1
  201. LDRB R3, [R1], #1
  202. STRB R3, [R0], #1
  203. LDRB R3, [R1], #1
  204. STRB R3, [R0], #1
  205. LDRB R3, [R1], #1
  206. STRB R3, [R0], #1
  207. LDRB R3, [R1], #1
  208. STRB R3, [R0], #1
  209. LDRB R3, [R1], #1
  210. STRB R3, [R0], #1
  211. LDRB R3, [R1], #1
  212. STRB R3, [R0], #1
  213. LDRB R3, [R1], #1
  214. STRB R3, [R0], #1
  215. LDRB R3, [R1], #1
  216. STRB R3, [R0], #1
  217. LDRB R3, [R1], #1
  218. STRB R3, [R0], #1
  219. LDRB R3, [R1], #1
  220. STRB R3, [R0], #1
  221. LDRB R3, [R1], #1
  222. STRB R3, [R0], #1
  223. LDRB R3, [R1], #1
  224. STRB R3, [R0], #1
  225. LDRB R3, [R1], #1
  226. STRB R3, [R0], #1
  227. SUB R2, R2, #(01*01*16)
  228. B copy_08_1
  229. copy_08_2:
  230. CMP R2, #(01*01*01) ; Copy remaining 8-bit words
  231. BCC rt_memcpy_end
  232. LDRB R3, [R1], #1
  233. STRB R3, [R0], #1
  234. SUB R2, R2, #(01*01*01)
  235. B copy_08_2
  236. rt_memcpy_end:
  237. POP {R0} ; pop pdest
  238. LDMFD SP!, {R3-R12} ; restore registers from stack
  239. BX LR ; return
  240. END