string.S 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * String handling functions for PowerPC.
  3. *
  4. * Copyright (C) 1996 Paul Mackerras.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <asm/processor.h>
  12. #include <asm/errno.h>
  13. #include <asm/ppc_asm.h>
  14. _GLOBAL(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. _GLOBAL(strncpy)
  23. cmpwi 0,r5,0
  24. beqlr
  25. mtctr r5
  26. addi r6,r3,-1
  27. addi r4,r4,-1
  28. 1: lbzu r0,1(r4)
  29. cmpwi 0,r0,0
  30. stbu r0,1(r6)
  31. bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
  32. blr
  33. _GLOBAL(strcat)
  34. addi r5,r3,-1
  35. addi r4,r4,-1
  36. 1: lbzu r0,1(r5)
  37. cmpwi 0,r0,0
  38. bne 1b
  39. addi r5,r5,-1
  40. 1: lbzu r0,1(r4)
  41. cmpwi 0,r0,0
  42. stbu r0,1(r5)
  43. bne 1b
  44. blr
  45. _GLOBAL(strcmp)
  46. addi r5,r3,-1
  47. addi r4,r4,-1
  48. 1: lbzu r3,1(r5)
  49. cmpwi 1,r3,0
  50. lbzu r0,1(r4)
  51. subf. r3,r0,r3
  52. beqlr 1
  53. beq 1b
  54. blr
  55. _GLOBAL(strlen)
  56. addi r4,r3,-1
  57. 1: lbzu r0,1(r4)
  58. cmpwi 0,r0,0
  59. bne 1b
  60. subf r3,r3,r4
  61. blr
  62. _GLOBAL(memset)
  63. neg r0,r3
  64. rlwimi r4,r4,8,16,23
  65. andi. r0,r0,7 /* # bytes to be 8-byte aligned */
  66. rlwimi r4,r4,16,0,15
  67. cmplw cr1,r5,r0 /* do we get that far? */
  68. rldimi r4,r4,32,0
  69. mtcrf 1,r0
  70. mr r6,r3
  71. blt cr1,8f
  72. beq+ 3f /* if already 8-byte aligned */
  73. subf r5,r0,r5
  74. bf 31,1f
  75. stb r4,0(r6)
  76. addi r6,r6,1
  77. 1: bf 30,2f
  78. sth r4,0(r6)
  79. addi r6,r6,2
  80. 2: bf 29,3f
  81. stw r4,0(r6)
  82. addi r6,r6,4
  83. 3: srdi. r0,r5,6
  84. clrldi r5,r5,58
  85. mtctr r0
  86. beq 5f
  87. 4: std r4,0(r6)
  88. std r4,8(r6)
  89. std r4,16(r6)
  90. std r4,24(r6)
  91. std r4,32(r6)
  92. std r4,40(r6)
  93. std r4,48(r6)
  94. std r4,56(r6)
  95. addi r6,r6,64
  96. bdnz 4b
  97. 5: srwi. r0,r5,3
  98. clrlwi r5,r5,29
  99. mtcrf 1,r0
  100. beq 8f
  101. bf 29,6f
  102. std r4,0(r6)
  103. std r4,8(r6)
  104. std r4,16(r6)
  105. std r4,24(r6)
  106. addi r6,r6,32
  107. 6: bf 30,7f
  108. std r4,0(r6)
  109. std r4,8(r6)
  110. addi r6,r6,16
  111. 7: bf 31,8f
  112. std r4,0(r6)
  113. addi r6,r6,8
  114. 8: cmpwi r5,0
  115. mtcrf 1,r5
  116. beqlr+
  117. bf 29,9f
  118. stw r4,0(r6)
  119. addi r6,r6,4
  120. 9: bf 30,10f
  121. sth r4,0(r6)
  122. addi r6,r6,2
  123. 10: bflr 31
  124. stb r4,0(r6)
  125. blr
  126. _GLOBAL(memmove)
  127. cmplw 0,r3,r4
  128. bgt .backwards_memcpy
  129. b .memcpy
  130. _GLOBAL(backwards_memcpy)
  131. rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
  132. add r6,r3,r5
  133. add r4,r4,r5
  134. beq 2f
  135. andi. r0,r6,3
  136. mtctr r7
  137. bne 5f
  138. 1: lwz r7,-4(r4)
  139. lwzu r8,-8(r4)
  140. stw r7,-4(r6)
  141. stwu r8,-8(r6)
  142. bdnz 1b
  143. andi. r5,r5,7
  144. 2: cmplwi 0,r5,4
  145. blt 3f
  146. lwzu r0,-4(r4)
  147. subi r5,r5,4
  148. stwu r0,-4(r6)
  149. 3: cmpwi 0,r5,0
  150. beqlr
  151. mtctr r5
  152. 4: lbzu r0,-1(r4)
  153. stbu r0,-1(r6)
  154. bdnz 4b
  155. blr
  156. 5: mtctr r0
  157. 6: lbzu r7,-1(r4)
  158. stbu r7,-1(r6)
  159. bdnz 6b
  160. subf r5,r0,r5
  161. rlwinm. r7,r5,32-3,3,31
  162. beq 2b
  163. mtctr r7
  164. b 1b
  165. _GLOBAL(memcmp)
  166. cmpwi 0,r5,0
  167. ble- 2f
  168. mtctr r5
  169. addi r6,r3,-1
  170. addi r4,r4,-1
  171. 1: lbzu r3,1(r6)
  172. lbzu r0,1(r4)
  173. subf. r3,r0,r3
  174. bdnzt 2,1b
  175. blr
  176. 2: li r3,0
  177. blr
  178. _GLOBAL(memchr)
  179. cmpwi 0,r5,0
  180. ble- 2f
  181. mtctr r5
  182. addi r3,r3,-1
  183. 1: lbzu r0,1(r3)
  184. cmpw 0,r0,r4
  185. bdnzf 2,1b
  186. beqlr
  187. 2: li r3,0
  188. blr
  189. _GLOBAL(__clear_user)
  190. addi r6,r3,-4
  191. li r3,0
  192. li r5,0
  193. cmplwi 0,r4,4
  194. blt 7f
  195. /* clear a single word */
  196. 11: stwu r5,4(r6)
  197. beqlr
  198. /* clear word sized chunks */
  199. andi. r0,r6,3
  200. add r4,r0,r4
  201. subf r6,r0,r6
  202. srwi r0,r4,2
  203. andi. r4,r4,3
  204. mtctr r0
  205. bdz 7f
  206. 1: stwu r5,4(r6)
  207. bdnz 1b
  208. /* clear byte sized chunks */
  209. 7: cmpwi 0,r4,0
  210. beqlr
  211. mtctr r4
  212. addi r6,r6,3
  213. 8: stbu r5,1(r6)
  214. bdnz 8b
  215. blr
  216. 90: mr r3,r4
  217. blr
  218. 91: mfctr r3
  219. slwi r3,r3,2
  220. add r3,r3,r4
  221. blr
  222. 92: mfctr r3
  223. blr
  224. .section __ex_table,"a"
  225. .align 3
  226. .llong 11b,90b
  227. .llong 1b,91b
  228. .llong 8b,92b
  229. .text
  230. /* r3 = dst, r4 = src, r5 = count */
  231. _GLOBAL(__strncpy_from_user)
  232. addi r6,r3,-1
  233. addi r4,r4,-1
  234. cmpwi 0,r5,0
  235. beq 2f
  236. mtctr r5
  237. 1: lbzu r0,1(r4)
  238. cmpwi 0,r0,0
  239. stbu r0,1(r6)
  240. bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
  241. beq 3f
  242. 2: addi r6,r6,1
  243. 3: subf r3,r3,r6
  244. blr
  245. 99: li r3,-EFAULT
  246. blr
  247. .section __ex_table,"a"
  248. .align 3
  249. .llong 1b,99b
  250. .text
  251. /* r3 = str, r4 = len (> 0) */
  252. _GLOBAL(__strnlen_user)
  253. addi r7,r3,-1
  254. mtctr r4 /* ctr = len */
  255. 1: lbzu r0,1(r7) /* get next byte */
  256. cmpwi 0,r0,0
  257. bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
  258. addi r7,r7,1
  259. subf r3,r3,r7 /* number of bytes we have looked at */
  260. beqlr /* return if we found a 0 byte */
  261. cmpw 0,r3,r4 /* did we look at all len bytes? */
  262. blt 99f /* if not, must have hit top */
  263. addi r3,r4,1 /* return len + 1 to indicate no null found */
  264. blr
  265. 99: li r3,0 /* bad address, return 0 */
  266. blr
  267. .section __ex_table,"a"
  268. .align 3
  269. .llong 1b,99b