string.S 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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 strcmp
  48. strcmp:
  49. addi r5,r3,-1
  50. addi r4,r4,-1
  51. 1: lbzu r3,1(r5)
  52. cmpwi 1,r3,0
  53. lbzu r0,1(r4)
  54. subf. r3,r0,r3
  55. beqlr 1
  56. beq 1b
  57. blr
  58. .globl strlen
  59. strlen:
  60. addi r4,r3,-1
  61. 1: lbzu r0,1(r4)
  62. cmpwi 0,r0,0
  63. bne 1b
  64. subf r3,r3,r4
  65. blr
  66. .globl memset
  67. memset:
  68. rlwimi r4,r4,8,16,23
  69. rlwimi r4,r4,16,0,15
  70. addi r6,r3,-4
  71. cmplwi 0,r5,4
  72. blt 7f
  73. stwu r4,4(r6)
  74. beqlr
  75. andi. r0,r6,3
  76. add r5,r0,r5
  77. subf r6,r0,r6
  78. rlwinm r0,r5,32-2,2,31
  79. mtctr r0
  80. bdz 6f
  81. 1: stwu r4,4(r6)
  82. bdnz 1b
  83. 6: andi. r5,r5,3
  84. 7: cmpwi 0,r5,0
  85. beqlr
  86. mtctr r5
  87. addi r6,r6,3
  88. 8: stbu r4,1(r6)
  89. bdnz 8b
  90. blr
  91. .globl memmove
  92. memmove:
  93. cmplw 0,r3,r4
  94. bgt backwards_memcpy
  95. /* fall through */
  96. .globl memcpy
  97. memcpy:
  98. rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */
  99. addi r6,r3,-4
  100. addi r4,r4,-4
  101. beq 3f /* if less than 8 bytes to do */
  102. andi. r0,r6,3 /* get dest word aligned */
  103. mtctr r7
  104. bne 5f
  105. andi. r0,r4,3 /* check src word aligned too */
  106. bne 3f
  107. 1: lwz r7,4(r4)
  108. lwzu r8,8(r4)
  109. stw r7,4(r6)
  110. stwu r8,8(r6)
  111. bdnz 1b
  112. andi. r5,r5,7
  113. 2: cmplwi 0,r5,4
  114. blt 3f
  115. lwzu r0,4(r4)
  116. addi r5,r5,-4
  117. stwu r0,4(r6)
  118. 3: cmpwi 0,r5,0
  119. beqlr
  120. mtctr r5
  121. addi r4,r4,3
  122. addi r6,r6,3
  123. 4: lbzu r0,1(r4)
  124. stbu r0,1(r6)
  125. bdnz 4b
  126. blr
  127. 5: subfic r0,r0,4
  128. cmpw cr1,r0,r5
  129. add r7,r0,r4
  130. andi. r7,r7,3 /* will source be word-aligned too? */
  131. ble cr1,3b
  132. bne 3b /* do byte-by-byte if not */
  133. mtctr r0
  134. 6: lbz r7,4(r4)
  135. addi r4,r4,1
  136. stb r7,4(r6)
  137. addi r6,r6,1
  138. bdnz 6b
  139. subf r5,r0,r5
  140. rlwinm. r7,r5,32-3,3,31
  141. beq 2b
  142. mtctr r7
  143. b 1b
  144. .globl backwards_memcpy
  145. backwards_memcpy:
  146. rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */
  147. add r6,r3,r5
  148. add r4,r4,r5
  149. beq 3f
  150. andi. r0,r6,3
  151. mtctr r7
  152. bne 5f
  153. andi. r0,r4,3
  154. bne 3f
  155. 1: lwz r7,-4(r4)
  156. lwzu r8,-8(r4)
  157. stw r7,-4(r6)
  158. stwu r8,-8(r6)
  159. bdnz 1b
  160. andi. r5,r5,7
  161. 2: cmplwi 0,r5,4
  162. blt 3f
  163. lwzu r0,-4(r4)
  164. subi r5,r5,4
  165. stwu r0,-4(r6)
  166. 3: cmpwi 0,r5,0
  167. beqlr
  168. mtctr r5
  169. 4: lbzu r0,-1(r4)
  170. stbu r0,-1(r6)
  171. bdnz 4b
  172. blr
  173. 5: cmpw cr1,r0,r5
  174. subf r7,r0,r4
  175. andi. r7,r7,3
  176. ble cr1,3b
  177. bne 3b
  178. mtctr r0
  179. 6: lbzu r7,-1(r4)
  180. stbu r7,-1(r6)
  181. bdnz 6b
  182. subf r5,r0,r5
  183. rlwinm. r7,r5,32-3,3,31
  184. beq 2b
  185. mtctr r7
  186. b 1b
  187. .globl memcmp
  188. memcmp:
  189. cmpwi 0,r5,0
  190. blelr
  191. mtctr r5
  192. addi r6,r3,-1
  193. addi r4,r4,-1
  194. 1: lbzu r3,1(r6)
  195. lbzu r0,1(r4)
  196. subf. r3,r0,r3
  197. bdnzt 2,1b
  198. blr
  199. /*
  200. * Flush the dcache and invalidate the icache for a range of addresses.
  201. *
  202. * flush_cache(addr, len)
  203. */
  204. .global flush_cache
  205. flush_cache:
  206. addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
  207. rlwinm. 4,4,27,5,31
  208. mtctr 4
  209. beqlr
  210. 1: dcbf 0,3
  211. icbi 0,3
  212. addi 3,3,0x20
  213. bdnz 1b
  214. sync
  215. isync
  216. blr