string.S 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * Copyright (C) Paul Mackerras 1997.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. *
  9. * NOTE: this code runs in 32 bit mode and is packaged as ELF32.
  10. */
  11. #include "ppc_asm.h"
  12. .text
  13. .globl strcpy
  14. strcpy:
  15. addi r5,r3,-1
  16. addi r4,r4,-1
  17. 1: lbzu r0,1(r4)
  18. cmpwi 0,r0,0
  19. stbu r0,1(r5)
  20. bne 1b
  21. blr
  22. .globl strncpy
  23. strncpy:
  24. cmpwi 0,r5,0
  25. beqlr
  26. mtctr r5
  27. addi r6,r3,-1
  28. addi r4,r4,-1
  29. 1: lbzu r0,1(r4)
  30. cmpwi 0,r0,0
  31. stbu r0,1(r6)
  32. bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
  33. blr
  34. .globl strcat
  35. strcat:
  36. addi r5,r3,-1
  37. addi r4,r4,-1
  38. 1: lbzu r0,1(r5)
  39. cmpwi 0,r0,0
  40. bne 1b
  41. addi r5,r5,-1
  42. 1: lbzu r0,1(r4)
  43. cmpwi 0,r0,0
  44. stbu r0,1(r5)
  45. bne 1b
  46. blr
  47. .globl strchr
  48. strchr:
  49. addi r3,r3,-1
  50. 1: lbzu r0,1(r3)
  51. cmpw 0,r0,r4
  52. beqlr
  53. cmpwi 0,r0,0
  54. bne 1b
  55. li r3,0
  56. blr
  57. .globl strcmp
  58. strcmp:
  59. addi r5,r3,-1
  60. addi r4,r4,-1
  61. 1: lbzu r3,1(r5)
  62. cmpwi 1,r3,0
  63. lbzu r0,1(r4)
  64. subf. r3,r0,r3
  65. beqlr 1
  66. beq 1b
  67. blr
  68. .globl strncmp
  69. strncmp:
  70. mtctr r5
  71. addi r5,r3,-1
  72. addi r4,r4,-1
  73. 1: lbzu r3,1(r5)
  74. cmpwi 1,r3,0
  75. lbzu r0,1(r4)
  76. subf. r3,r0,r3
  77. beqlr 1
  78. bdnzt eq,1b
  79. blr
  80. .globl strlen
  81. strlen:
  82. addi r4,r3,-1
  83. 1: lbzu r0,1(r4)
  84. cmpwi 0,r0,0
  85. bne 1b
  86. subf r3,r3,r4
  87. blr
  88. .globl memset
  89. memset:
  90. rlwimi r4,r4,8,16,23
  91. rlwimi r4,r4,16,0,15
  92. addi r6,r3,-4
  93. cmplwi 0,r5,4
  94. blt 7f
  95. stwu r4,4(r6)
  96. beqlr
  97. andi. r0,r6,3
  98. add r5,r0,r5
  99. subf r6,r0,r6
  100. rlwinm r0,r5,32-2,2,31
  101. mtctr r0
  102. bdz 6f
  103. 1: stwu r4,4(r6)
  104. bdnz 1b
  105. 6: andi. r5,r5,3
  106. 7: cmpwi 0,r5,0
  107. beqlr
  108. mtctr r5
  109. addi r6,r6,3
  110. 8: stbu r4,1(r6)
  111. bdnz 8b
  112. blr
  113. .globl memmove
  114. memmove:
  115. cmplw 0,r3,r4
  116. bgt backwards_memcpy
  117. /* fall through */
  118. .globl memcpy
  119. memcpy:
  120. rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */
  121. addi r6,r3,-4
  122. addi r4,r4,-4
  123. beq 3f /* if less than 8 bytes to do */
  124. andi. r0,r6,3 /* get dest word aligned */
  125. mtctr r7
  126. bne 5f
  127. andi. r0,r4,3 /* check src word aligned too */
  128. bne 3f
  129. 1: lwz r7,4(r4)
  130. lwzu r8,8(r4)
  131. stw r7,4(r6)
  132. stwu r8,8(r6)
  133. bdnz 1b
  134. andi. r5,r5,7
  135. 2: cmplwi 0,r5,4
  136. blt 3f
  137. lwzu r0,4(r4)
  138. addi r5,r5,-4
  139. stwu r0,4(r6)
  140. 3: cmpwi 0,r5,0
  141. beqlr
  142. mtctr r5
  143. addi r4,r4,3
  144. addi r6,r6,3
  145. 4: lbzu r0,1(r4)
  146. stbu r0,1(r6)
  147. bdnz 4b
  148. blr
  149. 5: subfic r0,r0,4
  150. cmpw cr1,r0,r5
  151. add r7,r0,r4
  152. andi. r7,r7,3 /* will source be word-aligned too? */
  153. ble cr1,3b
  154. bne 3b /* do byte-by-byte if not */
  155. mtctr r0
  156. 6: lbz r7,4(r4)
  157. addi r4,r4,1
  158. stb r7,4(r6)
  159. addi r6,r6,1
  160. bdnz 6b
  161. subf r5,r0,r5
  162. rlwinm. r7,r5,32-3,3,31
  163. beq 2b
  164. mtctr r7
  165. b 1b
  166. .globl backwards_memcpy
  167. backwards_memcpy:
  168. rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */
  169. add r6,r3,r5
  170. add r4,r4,r5
  171. beq 3f
  172. andi. r0,r6,3
  173. mtctr r7
  174. bne 5f
  175. andi. r0,r4,3
  176. bne 3f
  177. 1: lwz r7,-4(r4)
  178. lwzu r8,-8(r4)
  179. stw r7,-4(r6)
  180. stwu r8,-8(r6)
  181. bdnz 1b
  182. andi. r5,r5,7
  183. 2: cmplwi 0,r5,4
  184. blt 3f
  185. lwzu r0,-4(r4)
  186. subi r5,r5,4
  187. stwu r0,-4(r6)
  188. 3: cmpwi 0,r5,0
  189. beqlr
  190. mtctr r5
  191. 4: lbzu r0,-1(r4)
  192. stbu r0,-1(r6)
  193. bdnz 4b
  194. blr
  195. 5: cmpw cr1,r0,r5
  196. subf r7,r0,r4
  197. andi. r7,r7,3
  198. ble cr1,3b
  199. bne 3b
  200. mtctr r0
  201. 6: lbzu r7,-1(r4)
  202. stbu r7,-1(r6)
  203. bdnz 6b
  204. subf r5,r0,r5
  205. rlwinm. r7,r5,32-3,3,31
  206. beq 2b
  207. mtctr r7
  208. b 1b
  209. .globl memchr
  210. memchr:
  211. cmpwi 0,r5,0
  212. blelr
  213. mtctr r5
  214. addi r3,r3,-1
  215. 1: lbzu r0,1(r3)
  216. cmpw r0,r4
  217. beqlr
  218. bdnz 1b
  219. li r3,0
  220. blr
  221. .globl memcmp
  222. memcmp:
  223. cmpwi 0,r5,0
  224. ble 2f
  225. mtctr r5
  226. addi r6,r3,-1
  227. addi r4,r4,-1
  228. 1: lbzu r3,1(r6)
  229. lbzu r0,1(r4)
  230. subf. r3,r0,r3
  231. bdnzt 2,1b
  232. blr
  233. 2: li r3,0
  234. blr
  235. /*
  236. * Flush the dcache and invalidate the icache for a range of addresses.
  237. *
  238. * flush_cache(addr, len)
  239. */
  240. .global flush_cache
  241. flush_cache:
  242. addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
  243. rlwinm. 4,4,27,5,31
  244. mtctr 4
  245. beqlr
  246. 1: dcbf 0,3
  247. icbi 0,3
  248. addi 3,3,0x20
  249. bdnz 1b
  250. sync
  251. isync
  252. blr