Linux-2.6.12-rc2
[deliverable/linux.git] / arch / ppc64 / lib / string.S
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
18 1: 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
30 1: 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
39 1: lbzu r0,1(r5)
40 cmpwi 0,r0,0
41 bne 1b
42 addi r5,r5,-1
43 1: 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
52 1: 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
62 1: 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
83 1: bf 30,2f
84 sth r4,0(r6)
85 addi r6,r6,2
86 2: bf 29,3f
87 stw r4,0(r6)
88 addi r6,r6,4
89 3: srdi. r0,r5,6
90 clrldi r5,r5,58
91 mtctr r0
92 beq 5f
93 4: 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
103 5: 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
113 6: bf 30,7f
114 std r4,0(r6)
115 std r4,8(r6)
116 addi r6,r6,16
117 7: bf 31,8f
118 std r4,0(r6)
119 addi r6,r6,8
120 8: cmpwi r5,0
121 mtcrf 1,r5
122 beqlr+
123 bf 29,9f
124 stw r4,0(r6)
125 addi r6,r6,4
126 9: bf 30,10f
127 sth r4,0(r6)
128 addi r6,r6,2
129 10: 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
146 1: 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
152 2: cmplwi 0,r5,4
153 blt 3f
154 lwzu r0,-4(r4)
155 subi r5,r5,4
156 stwu r0,-4(r6)
157 3: cmpwi 0,r5,0
158 beqlr
159 mtctr r5
160 4: lbzu r0,-1(r4)
161 stbu r0,-1(r6)
162 bdnz 4b
163 blr
164 5: mtctr r0
165 6: 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
180 1: lbzu r3,1(r6)
181 lbzu r0,1(r4)
182 subf. r3,r0,r3
183 bdnzt 2,1b
184 blr
185 2: 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
193 1: lbzu r0,1(r3)
194 cmpw 0,r0,r4
195 bdnzf 2,1b
196 beqlr
197 2: 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 */
207 11: 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
217 1: stwu r5,4(r6)
218 bdnz 1b
219 /* clear byte sized chunks */
220 7: cmpwi 0,r4,0
221 beqlr
222 mtctr r4
223 addi r6,r6,3
224 8: stbu r5,1(r6)
225 bdnz 8b
226 blr
227 90: mr r3,r4
228 blr
229 91: mfctr r3
230 slwi r3,r3,2
231 add r3,r3,r4
232 blr
233 92: 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
250 1: 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
255 2: addi r6,r6,1
256 3: subf r3,r3,r6
257 blr
258 99: 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 */
270 1: 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
280 99: li r3,0 /* bad address, return 0 */
281 blr
282
283 .section __ex_table,"a"
284 .align 3
285 .llong 1b,99b
This page took 0.039569 seconds and 5 git commands to generate.