original comment: +Wilson03172004,marked due to this pci host does not support MWI
[linux-2.4.git] / arch / arm / lib / uaccess.S
1 /*
2  *  linux/arch/arm/lib/uaccess.S
3  *
4  *  Copyright (C) 1995, 1996,1997,1998 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  *  Routines to block copy data to/from user memory
11  *   These are highly optimised both for the 4k page size
12  *   and for various alignments.
13  */
14 #include <linux/linkage.h>
15 #include <asm/assembler.h>
16 #include <asm/errno.h>
17
18                 .text
19
20 #define PAGE_SHIFT 12
21
22 /* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n)
23  * Purpose  : copy a block to user memory from kernel memory
24  * Params   : to   - user memory
25  *          : from - kernel memory
26  *          : n    - number of bytes to copy
27  * Returns  : Number of bytes NOT copied.
28  */
29
30 .c2u_dest_not_aligned:
31                 rsb     ip, ip, #4
32                 cmp     ip, #2
33                 ldrb    r3, [r1], #1
34 USER(           strbt   r3, [r0], #1)                   @ May fault
35                 ldrgeb  r3, [r1], #1
36 USER(           strgebt r3, [r0], #1)                   @ May fault
37                 ldrgtb  r3, [r1], #1
38 USER(           strgtbt r3, [r0], #1)                   @ May fault
39                 sub     r2, r2, ip
40                 b       .c2u_dest_aligned
41
42 ENTRY(__arch_copy_to_user)
43                 stmfd   sp!, {r2, r4 - r7, lr}
44                 cmp     r2, #4
45                 blt     .c2u_not_enough
46                 ands    ip, r0, #3
47                 bne     .c2u_dest_not_aligned
48 .c2u_dest_aligned:
49
50                 ands    ip, r1, #3
51                 bne     .c2u_src_not_aligned
52 /*
53  * Seeing as there has to be at least 8 bytes to copy, we can
54  * copy one word, and force a user-mode page fault...
55  */
56
57 .c2u_0fupi:     subs    r2, r2, #4
58                 addmi   ip, r2, #4
59                 bmi     .c2u_0nowords
60                 ldr     r3, [r1], #4
61 USER(           strt    r3, [r0], #4)                   @ May fault
62                 mov     ip, r0, lsl #32 - PAGE_SHIFT    @ On each page, use a ld/st??t instruction
63                 rsb     ip, ip, #0
64                 movs    ip, ip, lsr #32 - PAGE_SHIFT
65                 beq     .c2u_0fupi
66 /*
67  * ip = max no. of bytes to copy before needing another "strt" insn
68  */
69                 cmp     r2, ip
70                 movlt   ip, r2
71                 sub     r2, r2, ip
72                 subs    ip, ip, #32
73                 blt     .c2u_0rem8lp
74
75 .c2u_0cpy8lp:   ldmia   r1!, {r3 - r6}
76                 stmia   r0!, {r3 - r6}                  @ Shouldnt fault
77                 ldmia   r1!, {r3 - r6}
78                 stmia   r0!, {r3 - r6}                  @ Shouldnt fault
79                 subs    ip, ip, #32
80                 bpl     .c2u_0cpy8lp
81 .c2u_0rem8lp:   cmn     ip, #16
82                 ldmgeia r1!, {r3 - r6}
83                 stmgeia r0!, {r3 - r6}                  @ Shouldnt fault
84                 tst     ip, #8
85                 ldmneia r1!, {r3 - r4}
86                 stmneia r0!, {r3 - r4}                  @ Shouldnt fault
87                 tst     ip, #4
88                 ldrne   r3, [r1], #4
89                 strnet  r3, [r0], #4                    @ Shouldnt fault
90                 ands    ip, ip, #3
91                 beq     .c2u_0fupi
92 .c2u_0nowords:  teq     ip, #0
93                 beq     .c2u_finished
94 .c2u_nowords:   cmp     ip, #2
95                 ldrb    r3, [r1], #1
96 USER(           strbt   r3, [r0], #1)                   @ May fault
97                 ldrgeb  r3, [r1], #1
98 USER(           strgebt r3, [r0], #1)                   @ May fault
99                 ldrgtb  r3, [r1], #1
100 USER(           strgtbt r3, [r0], #1)                   @ May fault
101                 b       .c2u_finished
102
103 .c2u_not_enough:
104                 movs    ip, r2
105                 bne     .c2u_nowords
106 .c2u_finished:  mov     r0, #0
107                 LOADREGS(fd,sp!,{r2, r4 - r7, pc})
108
109 .c2u_src_not_aligned:
110                 bic     r1, r1, #3
111                 ldr     r7, [r1], #4
112                 cmp     ip, #2
113                 bgt     .c2u_3fupi
114                 beq     .c2u_2fupi
115 .c2u_1fupi:     subs    r2, r2, #4
116                 addmi   ip, r2, #4
117                 bmi     .c2u_1nowords
118                 mov     r3, r7, lsr #8
119                 ldr     r7, [r1], #4
120                 orr     r3, r3, r7, lsl #24
121 USER(           strt    r3, [r0], #4)                   @ May fault
122                 mov     ip, r0, lsl #32 - PAGE_SHIFT
123                 rsb     ip, ip, #0
124                 movs    ip, ip, lsr #32 - PAGE_SHIFT
125                 beq     .c2u_1fupi
126                 cmp     r2, ip
127                 movlt   ip, r2
128                 sub     r2, r2, ip
129                 subs    ip, ip, #16
130                 blt     .c2u_1rem8lp
131
132 .c2u_1cpy8lp:   mov     r3, r7, lsr #8
133                 ldmia   r1!, {r4 - r7}
134                 orr     r3, r3, r4, lsl #24
135                 mov     r4, r4, lsr #8
136                 orr     r4, r4, r5, lsl #24
137                 mov     r5, r5, lsr #8
138                 orr     r5, r5, r6, lsl #24
139                 mov     r6, r6, lsr #8
140                 orr     r6, r6, r7, lsl #24
141                 stmia   r0!, {r3 - r6}                  @ Shouldnt fault
142                 subs    ip, ip, #16
143                 bpl     .c2u_1cpy8lp
144 .c2u_1rem8lp:   tst     ip, #8
145                 movne   r3, r7, lsr #8
146                 ldmneia r1!, {r4, r7}
147                 orrne   r3, r3, r4, lsl #24
148                 movne   r4, r4, lsr #8
149                 orrne   r4, r4, r7, lsl #24
150                 stmneia r0!, {r3 - r4}                  @ Shouldnt fault
151                 tst     ip, #4
152                 movne   r3, r7, lsr #8
153                 ldrne   r7, [r1], #4
154                 orrne   r3, r3, r7, lsl #24
155                 strnet  r3, [r0], #4                    @ Shouldnt fault
156                 ands    ip, ip, #3
157                 beq     .c2u_1fupi
158 .c2u_1nowords:  mov     r3, r7, lsr #8
159                 teq     ip, #0
160                 beq     .c2u_finished
161                 cmp     ip, #2
162 USER(           strbt   r3, [r0], #1)                   @ May fault
163                 movge   r3, r3, lsr #8
164 USER(           strgebt r3, [r0], #1)                   @ May fault
165                 movgt   r3, r3, lsr #8
166 USER(           strgtbt r3, [r0], #1)                   @ May fault
167                 b       .c2u_finished
168
169 .c2u_2fupi:     subs    r2, r2, #4
170                 addmi   ip, r2, #4
171                 bmi     .c2u_2nowords
172                 mov     r3, r7, lsr #16
173                 ldr     r7, [r1], #4
174                 orr     r3, r3, r7, lsl #16
175 USER(           strt    r3, [r0], #4)                   @ May fault
176                 mov     ip, r0, lsl #32 - PAGE_SHIFT
177                 rsb     ip, ip, #0
178                 movs    ip, ip, lsr #32 - PAGE_SHIFT
179                 beq     .c2u_2fupi
180                 cmp     r2, ip
181                 movlt   ip, r2
182                 sub     r2, r2, ip
183                 subs    ip, ip, #16
184                 blt     .c2u_2rem8lp
185
186 .c2u_2cpy8lp:   mov     r3, r7, lsr #16
187                 ldmia   r1!, {r4 - r7}
188                 orr     r3, r3, r4, lsl #16
189                 mov     r4, r4, lsr #16
190                 orr     r4, r4, r5, lsl #16
191                 mov     r5, r5, lsr #16
192                 orr     r5, r5, r6, lsl #16
193                 mov     r6, r6, lsr #16
194                 orr     r6, r6, r7, lsl #16
195                 stmia   r0!, {r3 - r6}                  @ Shouldnt fault
196                 subs    ip, ip, #16
197                 bpl     .c2u_2cpy8lp
198 .c2u_2rem8lp:   tst     ip, #8
199                 movne   r3, r7, lsr #16
200                 ldmneia r1!, {r4, r7}
201                 orrne   r3, r3, r4, lsl #16
202                 movne   r4, r4, lsr #16
203                 orrne   r4, r4, r7, lsl #16
204                 stmneia r0!, {r3 - r4}                  @ Shouldnt fault
205                 tst     ip, #4
206                 movne   r3, r7, lsr #16
207                 ldrne   r7, [r1], #4
208                 orrne   r3, r3, r7, lsl #16
209                 strnet  r3, [r0], #4                    @ Shouldnt fault
210                 ands    ip, ip, #3
211                 beq     .c2u_2fupi
212 .c2u_2nowords:  mov     r3, r7, lsr #16
213                 teq     ip, #0
214                 beq     .c2u_finished
215                 cmp     ip, #2
216 USER(           strbt   r3, [r0], #1)                   @ May fault
217                 movge   r3, r3, lsr #8
218 USER(           strgebt r3, [r0], #1)                   @ May fault
219                 ldrgtb  r3, [r1], #0
220 USER(           strgtbt r3, [r0], #1)                   @ May fault
221                 b       .c2u_finished
222
223 .c2u_3fupi:     subs    r2, r2, #4
224                 addmi   ip, r2, #4
225                 bmi     .c2u_3nowords
226                 mov     r3, r7, lsr #24
227                 ldr     r7, [r1], #4
228                 orr     r3, r3, r7, lsl #8
229 USER(           strt    r3, [r0], #4)                   @ May fault
230                 mov     ip, r0, lsl #32 - PAGE_SHIFT
231                 rsb     ip, ip, #0
232                 movs    ip, ip, lsr #32 - PAGE_SHIFT
233                 beq     .c2u_3fupi
234                 cmp     r2, ip
235                 movlt   ip, r2
236                 sub     r2, r2, ip
237                 subs    ip, ip, #16
238                 blt     .c2u_3rem8lp
239
240 .c2u_3cpy8lp:   mov     r3, r7, lsr #24
241                 ldmia   r1!, {r4 - r7}
242                 orr     r3, r3, r4, lsl #8
243                 mov     r4, r4, lsr #24
244                 orr     r4, r4, r5, lsl #8
245                 mov     r5, r5, lsr #24
246                 orr     r5, r5, r6, lsl #8
247                 mov     r6, r6, lsr #24
248                 orr     r6, r6, r7, lsl #8
249                 stmia   r0!, {r3 - r6}                  @ Shouldnt fault
250                 subs    ip, ip, #16
251                 bpl     .c2u_3cpy8lp
252 .c2u_3rem8lp:   tst     ip, #8
253                 movne   r3, r7, lsr #24
254                 ldmneia r1!, {r4, r7}
255                 orrne   r3, r3, r4, lsl #8
256                 movne   r4, r4, lsr #24
257                 orrne   r4, r4, r7, lsl #8
258                 stmneia r0!, {r3 - r4}                  @ Shouldnt fault
259                 tst     ip, #4
260                 movne   r3, r7, lsr #24
261                 ldrne   r7, [r1], #4
262                 orrne   r3, r3, r7, lsl #8
263                 strnet  r3, [r0], #4                    @ Shouldnt fault
264                 ands    ip, ip, #3
265                 beq     .c2u_3fupi
266 .c2u_3nowords:  mov     r3, r7, lsr #24
267                 teq     ip, #0
268                 beq     .c2u_finished
269                 cmp     ip, #2
270 USER(           strbt   r3, [r0], #1)                   @ May fault
271                 ldrge   r3, [r1], #0
272 USER(           strgebt r3, [r0], #1)                   @ May fault
273                 movgt   r3, r3, lsr #8
274 USER(           strgtbt r3, [r0], #1)                   @ May fault
275                 b       .c2u_finished
276
277                 .section .fixup,"ax"
278                 .align  0
279 9001:           LOADREGS(fd,sp!, {r0, r4 - r7, pc})
280                 .previous
281
282 /* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n);
283  * Purpose  : copy a block from user memory to kernel memory
284  * Params   : to   - kernel memory
285  *          : from - user memory
286  *          : n    - number of bytes to copy
287  * Returns  : Number of bytes NOT copied.
288  */
289 .cfu_dest_not_aligned:
290                 rsb     ip, ip, #4
291                 cmp     ip, #2
292 USER(           ldrbt   r3, [r1], #1)                   @ May fault
293                 strb    r3, [r0], #1
294 USER(           ldrgebt r3, [r1], #1)                   @ May fault
295                 strgeb  r3, [r0], #1
296 USER(           ldrgtbt r3, [r1], #1)                   @ May fault
297                 strgtb  r3, [r0], #1
298                 sub     r2, r2, ip
299                 b       .cfu_dest_aligned
300
301 ENTRY(__arch_copy_from_user)
302                 stmfd   sp!, {r0, r2, r4 - r7, lr}
303                 cmp     r2, #4
304                 blt     .cfu_not_enough
305                 ands    ip, r0, #3
306                 bne     .cfu_dest_not_aligned
307 .cfu_dest_aligned:
308                 ands    ip, r1, #3
309                 bne     .cfu_src_not_aligned
310 /*
311  * Seeing as there has to be at least 8 bytes to copy, we can
312  * copy one word, and force a user-mode page fault...
313  */
314
315 .cfu_0fupi:     subs    r2, r2, #4
316                 addmi   ip, r2, #4
317                 bmi     .cfu_0nowords
318 USER(           ldrt    r3, [r1], #4)
319                 str     r3, [r0], #4
320                 mov     ip, r1, lsl #32 - PAGE_SHIFT    @ On each page, use a ld/st??t instruction
321                 rsb     ip, ip, #0
322                 movs    ip, ip, lsr #32 - PAGE_SHIFT
323                 beq     .cfu_0fupi
324 /*
325  * ip = max no. of bytes to copy before needing another "strt" insn
326  */
327                 cmp     r2, ip
328                 movlt   ip, r2
329                 sub     r2, r2, ip
330                 subs    ip, ip, #32
331                 blt     .cfu_0rem8lp
332
333 .cfu_0cpy8lp:   ldmia   r1!, {r3 - r6}                  @ Shouldnt fault
334                 stmia   r0!, {r3 - r6}
335                 ldmia   r1!, {r3 - r6}                  @ Shouldnt fault
336                 stmia   r0!, {r3 - r6}
337                 subs    ip, ip, #32
338                 bpl     .cfu_0cpy8lp
339 .cfu_0rem8lp:   cmn     ip, #16
340                 ldmgeia r1!, {r3 - r6}                  @ Shouldnt fault
341                 stmgeia r0!, {r3 - r6}
342                 tst     ip, #8
343                 ldmneia r1!, {r3 - r4}                  @ Shouldnt fault
344                 stmneia r0!, {r3 - r4}
345                 tst     ip, #4
346                 ldrnet  r3, [r1], #4                    @ Shouldnt fault
347                 strne   r3, [r0], #4
348                 ands    ip, ip, #3
349                 beq     .cfu_0fupi
350 .cfu_0nowords:  teq     ip, #0
351                 beq     .cfu_finished
352 .cfu_nowords:   cmp     ip, #2
353 USER(           ldrbt   r3, [r1], #1)                   @ May fault
354                 strb    r3, [r0], #1
355 USER(           ldrgebt r3, [r1], #1)                   @ May fault
356                 strgeb  r3, [r0], #1
357 USER(           ldrgtbt r3, [r1], #1)                   @ May fault
358                 strgtb  r3, [r0], #1
359                 b       .cfu_finished
360
361 .cfu_not_enough:
362                 movs    ip, r2
363                 bne     .cfu_nowords
364 .cfu_finished:  mov     r0, #0
365                 add     sp, sp, #8
366                 LOADREGS(fd,sp!,{r4 - r7, pc})
367
368 .cfu_src_not_aligned:
369                 bic     r1, r1, #3
370 USER(           ldrt    r7, [r1], #4)                   @ May fault
371                 cmp     ip, #2
372                 bgt     .cfu_3fupi
373                 beq     .cfu_2fupi
374 .cfu_1fupi:     subs    r2, r2, #4
375                 addmi   ip, r2, #4
376                 bmi     .cfu_1nowords
377                 mov     r3, r7, lsr #8
378 USER(           ldrt    r7, [r1], #4)                   @ May fault
379                 orr     r3, r3, r7, lsl #24
380                 str     r3, [r0], #4
381                 mov     ip, r1, lsl #32 - PAGE_SHIFT
382                 rsb     ip, ip, #0
383                 movs    ip, ip, lsr #32 - PAGE_SHIFT
384                 beq     .cfu_1fupi
385                 cmp     r2, ip
386                 movlt   ip, r2
387                 sub     r2, r2, ip
388                 subs    ip, ip, #16
389                 blt     .cfu_1rem8lp
390
391 .cfu_1cpy8lp:   mov     r3, r7, lsr #8
392                 ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
393                 orr     r3, r3, r4, lsl #24
394                 mov     r4, r4, lsr #8
395                 orr     r4, r4, r5, lsl #24
396                 mov     r5, r5, lsr #8
397                 orr     r5, r5, r6, lsl #24
398                 mov     r6, r6, lsr #8
399                 orr     r6, r6, r7, lsl #24
400                 stmia   r0!, {r3 - r6}
401                 subs    ip, ip, #16
402                 bpl     .cfu_1cpy8lp
403 .cfu_1rem8lp:   tst     ip, #8
404                 movne   r3, r7, lsr #8
405                 ldmneia r1!, {r4, r7}                   @ Shouldnt fault
406                 orrne   r3, r3, r4, lsl #24
407                 movne   r4, r4, lsr #8
408                 orrne   r4, r4, r7, lsl #24
409                 stmneia r0!, {r3 - r4}
410                 tst     ip, #4
411                 movne   r3, r7, lsr #8
412 USER(           ldrnet  r7, [r1], #4)                   @ May fault
413                 orrne   r3, r3, r7, lsl #24
414                 strne   r3, [r0], #4
415                 ands    ip, ip, #3
416                 beq     .cfu_1fupi
417 .cfu_1nowords:  mov     r3, r7, lsr #8
418                 teq     ip, #0
419                 beq     .cfu_finished
420                 cmp     ip, #2
421                 strb    r3, [r0], #1
422                 movge   r3, r3, lsr #8
423                 strgeb  r3, [r0], #1
424                 movgt   r3, r3, lsr #8
425                 strgtb  r3, [r0], #1
426                 b       .cfu_finished
427
428 .cfu_2fupi:     subs    r2, r2, #4
429                 addmi   ip, r2, #4
430                 bmi     .cfu_2nowords
431                 mov     r3, r7, lsr #16
432 USER(           ldrt    r7, [r1], #4)                   @ May fault
433                 orr     r3, r3, r7, lsl #16
434                 str     r3, [r0], #4
435                 mov     ip, r1, lsl #32 - PAGE_SHIFT
436                 rsb     ip, ip, #0
437                 movs    ip, ip, lsr #32 - PAGE_SHIFT
438                 beq     .cfu_2fupi
439                 cmp     r2, ip
440                 movlt   ip, r2
441                 sub     r2, r2, ip
442                 subs    ip, ip, #16
443                 blt     .cfu_2rem8lp
444
445 .cfu_2cpy8lp:   mov     r3, r7, lsr #16
446                 ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
447                 orr     r3, r3, r4, lsl #16
448                 mov     r4, r4, lsr #16
449                 orr     r4, r4, r5, lsl #16
450                 mov     r5, r5, lsr #16
451                 orr     r5, r5, r6, lsl #16
452                 mov     r6, r6, lsr #16
453                 orr     r6, r6, r7, lsl #16
454                 stmia   r0!, {r3 - r6}
455                 subs    ip, ip, #16
456                 bpl     .cfu_2cpy8lp
457 .cfu_2rem8lp:   tst     ip, #8
458                 movne   r3, r7, lsr #16
459                 ldmneia r1!, {r4, r7}                   @ Shouldnt fault
460                 orrne   r3, r3, r4, lsl #16
461                 movne   r4, r4, lsr #16
462                 orrne   r4, r4, r7, lsl #16
463                 stmneia r0!, {r3 - r4}
464                 tst     ip, #4
465                 movne   r3, r7, lsr #16
466 USER(           ldrnet  r7, [r1], #4)                   @ May fault
467                 orrne   r3, r3, r7, lsl #16
468                 strne   r3, [r0], #4
469                 ands    ip, ip, #3
470                 beq     .cfu_2fupi
471 .cfu_2nowords:  mov     r3, r7, lsr #16
472                 teq     ip, #0
473                 beq     .cfu_finished
474                 cmp     ip, #2
475                 strb    r3, [r0], #1
476                 movge   r3, r3, lsr #8
477                 strgeb  r3, [r0], #1
478 USER(           ldrgtbt r3, [r1], #0)                   @ May fault
479                 strgtb  r3, [r0], #1
480                 b       .cfu_finished
481
482 .cfu_3fupi:     subs    r2, r2, #4
483                 addmi   ip, r2, #4
484                 bmi     .cfu_3nowords
485                 mov     r3, r7, lsr #24
486 USER(           ldrt    r7, [r1], #4)                   @ May fault
487                 orr     r3, r3, r7, lsl #8
488                 str     r3, [r0], #4
489                 mov     ip, r1, lsl #32 - PAGE_SHIFT
490                 rsb     ip, ip, #0
491                 movs    ip, ip, lsr #32 - PAGE_SHIFT
492                 beq     .cfu_3fupi
493                 cmp     r2, ip
494                 movlt   ip, r2
495                 sub     r2, r2, ip
496                 subs    ip, ip, #16
497                 blt     .cfu_3rem8lp
498
499 .cfu_3cpy8lp:   mov     r3, r7, lsr #24
500                 ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
501                 orr     r3, r3, r4, lsl #8
502                 mov     r4, r4, lsr #24
503                 orr     r4, r4, r5, lsl #8
504                 mov     r5, r5, lsr #24
505                 orr     r5, r5, r6, lsl #8
506                 mov     r6, r6, lsr #24
507                 orr     r6, r6, r7, lsl #8
508                 stmia   r0!, {r3 - r6}
509                 subs    ip, ip, #16
510                 bpl     .cfu_3cpy8lp
511 .cfu_3rem8lp:   tst     ip, #8
512                 movne   r3, r7, lsr #24
513                 ldmneia r1!, {r4, r7}                   @ Shouldnt fault
514                 orrne   r3, r3, r4, lsl #8
515                 movne   r4, r4, lsr #24
516                 orrne   r4, r4, r7, lsl #8
517                 stmneia r0!, {r3 - r4}
518                 tst     ip, #4
519                 movne   r3, r7, lsr #24
520 USER(           ldrnet  r7, [r1], #4)                   @ May fault
521                 orrne   r3, r3, r7, lsl #8
522                 strne   r3, [r0], #4
523                 ands    ip, ip, #3
524                 beq     .cfu_3fupi
525 .cfu_3nowords:  mov     r3, r7, lsr #24
526                 teq     ip, #0
527                 beq     .cfu_finished
528                 cmp     ip, #2
529                 strb    r3, [r0], #1
530 USER(           ldrget  r3, [r1], #0)                   @ May fault
531                 strgeb  r3, [r0], #1
532                 movgt   r3, r3, lsr #8
533                 strgtb  r3, [r0], #1
534                 b       .cfu_finished
535
536                 .section .fixup,"ax"
537                 .align  0
538                 /*
539                  * We took an exception.  r0 contains a pointer to
540                  * the byte not copied.
541                  */
542 9001:           ldr     r2, [sp], #4                    @ void *to
543                 sub     r2, r0, r2                      @ bytes copied
544                 ldr     r1, [sp], #4                    @ unsigned long count
545                 subs    r4, r1, r2                      @ bytes left to copy
546                 movne   r1, r4
547                 blne    SYMBOL_NAME(__memzero)
548                 mov     r0, r4
549                 LOADREGS(fd,sp!, {r4 - r7, pc})
550                 .previous
551
552 /* Prototype: int __arch_clear_user(void *addr, size_t sz)
553  * Purpose  : clear some user memory
554  * Params   : addr - user memory address to clear
555  *          : sz   - number of bytes to clear
556  * Returns  : number of bytes NOT cleared
557  */
558 ENTRY(__arch_clear_user)
559                 stmfd   sp!, {r1, lr}
560                 mov     r2, #0
561                 cmp     r1, #4
562                 blt     2f
563                 ands    ip, r0, #3
564                 beq     1f
565                 cmp     ip, #2
566 USER(           strbt   r2, [r0], #1)
567 USER(           strlebt r2, [r0], #1)
568 USER(           strltbt r2, [r0], #1)
569                 rsb     ip, ip, #4
570                 sub     r1, r1, ip              @  7  6  5  4  3  2  1
571 1:              subs    r1, r1, #8              @ -1 -2 -3 -4 -5 -6 -7
572 USER(           strplt  r2, [r0], #4)
573 USER(           strplt  r2, [r0], #4)
574                 bpl     1b
575                 adds    r1, r1, #4              @  3  2  1  0 -1 -2 -3
576 USER(           strplt  r2, [r0], #4)
577 2:              tst     r1, #2                  @ 1x 1x 0x 0x 1x 1x 0x
578 USER(           strnebt r2, [r0], #1)
579 USER(           strnebt r2, [r0], #1)
580                 tst     r1, #1                  @ x1 x0 x1 x0 x1 x0 x1
581 USER(           strnebt r2, [r0], #1)
582                 mov     r0, #0
583                 LOADREGS(fd,sp!, {r1, pc})
584
585                 .section .fixup,"ax"
586                 .align  0
587 9001:           LOADREGS(fd,sp!, {r0, pc})
588                 .previous
589