]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/ppc64/lib/string.S
Linux-2.6.12-rc2
[net-next-2.6.git] / arch / ppc64 / lib / string.S
CommitLineData
1da177e4
LT
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
15_GLOBAL(strcpy)
16 addi r5,r3,-1
17 addi r4,r4,-1
181: lbzu r0,1(r4)
19 cmpwi 0,r0,0
20 stbu r0,1(r5)
21 bne 1b
22 blr
23
24_GLOBAL(strncpy)
25 cmpwi 0,r5,0
26 beqlr
27 mtctr r5
28 addi r6,r3,-1
29 addi r4,r4,-1
301: lbzu r0,1(r4)
31 cmpwi 0,r0,0
32 stbu r0,1(r6)
33 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
34 blr
35
36_GLOBAL(strcat)
37 addi r5,r3,-1
38 addi r4,r4,-1
391: lbzu r0,1(r5)
40 cmpwi 0,r0,0
41 bne 1b
42 addi r5,r5,-1
431: lbzu r0,1(r4)
44 cmpwi 0,r0,0
45 stbu r0,1(r5)
46 bne 1b
47 blr
48
49_GLOBAL(strcmp)
50 addi r5,r3,-1
51 addi r4,r4,-1
521: lbzu r3,1(r5)
53 cmpwi 1,r3,0
54 lbzu r0,1(r4)
55 subf. r3,r0,r3
56 beqlr 1
57 beq 1b
58 blr
59
60_GLOBAL(strlen)
61 addi r4,r3,-1
621: lbzu r0,1(r4)
63 cmpwi 0,r0,0
64 bne 1b
65 subf r3,r3,r4
66 blr
67
68_GLOBAL(memset)
69 neg r0,r3
70 rlwimi r4,r4,8,16,23
71 andi. r0,r0,7 /* # bytes to be 8-byte aligned */
72 rlwimi r4,r4,16,0,15
73 cmplw cr1,r5,r0 /* do we get that far? */
74 rldimi r4,r4,32,0
75 mtcrf 1,r0
76 mr r6,r3
77 blt cr1,8f
78 beq+ 3f /* if already 8-byte aligned */
79 subf r5,r0,r5
80 bf 31,1f
81 stb r4,0(r6)
82 addi r6,r6,1
831: bf 30,2f
84 sth r4,0(r6)
85 addi r6,r6,2
862: bf 29,3f
87 stw r4,0(r6)
88 addi r6,r6,4
893: srdi. r0,r5,6
90 clrldi r5,r5,58
91 mtctr r0
92 beq 5f
934: std r4,0(r6)
94 std r4,8(r6)
95 std r4,16(r6)
96 std r4,24(r6)
97 std r4,32(r6)
98 std r4,40(r6)
99 std r4,48(r6)
100 std r4,56(r6)
101 addi r6,r6,64
102 bdnz 4b
1035: srwi. r0,r5,3
104 clrlwi r5,r5,29
105 mtcrf 1,r0
106 beq 8f
107 bf 29,6f
108 std r4,0(r6)
109 std r4,8(r6)
110 std r4,16(r6)
111 std r4,24(r6)
112 addi r6,r6,32
1136: bf 30,7f
114 std r4,0(r6)
115 std r4,8(r6)
116 addi r6,r6,16
1177: bf 31,8f
118 std r4,0(r6)
119 addi r6,r6,8
1208: cmpwi r5,0
121 mtcrf 1,r5
122 beqlr+
123 bf 29,9f
124 stw r4,0(r6)
125 addi r6,r6,4
1269: bf 30,10f
127 sth r4,0(r6)
128 addi r6,r6,2
12910: bflr 31
130 stb r4,0(r6)
131 blr
132
133_GLOBAL(memmove)
134 cmplw 0,r3,r4
135 bgt .backwards_memcpy
136 b .memcpy
137
138_GLOBAL(backwards_memcpy)
139 rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
140 add r6,r3,r5
141 add r4,r4,r5
142 beq 2f
143 andi. r0,r6,3
144 mtctr r7
145 bne 5f
1461: lwz r7,-4(r4)
147 lwzu r8,-8(r4)
148 stw r7,-4(r6)
149 stwu r8,-8(r6)
150 bdnz 1b
151 andi. r5,r5,7
1522: cmplwi 0,r5,4
153 blt 3f
154 lwzu r0,-4(r4)
155 subi r5,r5,4
156 stwu r0,-4(r6)
1573: cmpwi 0,r5,0
158 beqlr
159 mtctr r5
1604: lbzu r0,-1(r4)
161 stbu r0,-1(r6)
162 bdnz 4b
163 blr
1645: mtctr r0
1656: lbzu r7,-1(r4)
166 stbu r7,-1(r6)
167 bdnz 6b
168 subf r5,r0,r5
169 rlwinm. r7,r5,32-3,3,31
170 beq 2b
171 mtctr r7
172 b 1b
173
174_GLOBAL(memcmp)
175 cmpwi 0,r5,0
176 ble- 2f
177 mtctr r5
178 addi r6,r3,-1
179 addi r4,r4,-1
1801: lbzu r3,1(r6)
181 lbzu r0,1(r4)
182 subf. r3,r0,r3
183 bdnzt 2,1b
184 blr
1852: li r3,0
186 blr
187
188_GLOBAL(memchr)
189 cmpwi 0,r5,0
190 ble- 2f
191 mtctr r5
192 addi r3,r3,-1
1931: lbzu r0,1(r3)
194 cmpw 0,r0,r4
195 bdnzf 2,1b
196 beqlr
1972: li r3,0
198 blr
199
200_GLOBAL(__clear_user)
201 addi r6,r3,-4
202 li r3,0
203 li r5,0
204 cmplwi 0,r4,4
205 blt 7f
206 /* clear a single word */
20711: stwu r5,4(r6)
208 beqlr
209 /* clear word sized chunks */
210 andi. r0,r6,3
211 add r4,r0,r4
212 subf r6,r0,r6
213 srwi r0,r4,2
214 andi. r4,r4,3
215 mtctr r0
216 bdz 7f
2171: stwu r5,4(r6)
218 bdnz 1b
219 /* clear byte sized chunks */
2207: cmpwi 0,r4,0
221 beqlr
222 mtctr r4
223 addi r6,r6,3
2248: stbu r5,1(r6)
225 bdnz 8b
226 blr
22790: mr r3,r4
228 blr
22991: mfctr r3
230 slwi r3,r3,2
231 add r3,r3,r4
232 blr
23392: mfctr r3
234 blr
235
236 .section __ex_table,"a"
237 .align 3
238 .llong 11b,90b
239 .llong 1b,91b
240 .llong 8b,92b
241 .text
242
243/* r3 = dst, r4 = src, r5 = count */
244_GLOBAL(__strncpy_from_user)
245 addi r6,r3,-1
246 addi r4,r4,-1
247 cmpwi 0,r5,0
248 beq 2f
249 mtctr r5
2501: lbzu r0,1(r4)
251 cmpwi 0,r0,0
252 stbu r0,1(r6)
253 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
254 beq 3f
2552: addi r6,r6,1
2563: subf r3,r3,r6
257 blr
25899: li r3,-EFAULT
259 blr
260
261 .section __ex_table,"a"
262 .align 3
263 .llong 1b,99b
264 .text
265
266/* r3 = str, r4 = len (> 0) */
267_GLOBAL(__strnlen_user)
268 addi r7,r3,-1
269 mtctr r4 /* ctr = len */
2701: lbzu r0,1(r7) /* get next byte */
271 cmpwi 0,r0,0
272 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
273 addi r7,r7,1
274 subf r3,r3,r7 /* number of bytes we have looked at */
275 beqlr /* return if we found a 0 byte */
276 cmpw 0,r3,r4 /* did we look at all len bytes? */
277 blt 99f /* if not, must have hit top */
278 addi r3,r4,1 /* return len + 1 to indicate no null found */
279 blr
28099: li r3,0 /* bad address, return 0 */
281 blr
282
283 .section __ex_table,"a"
284 .align 3
285 .llong 1b,99b