- pre3:
[davej-history.git] / arch / arm / lib / memzero.S
blobc0a8d1906214c7048f39fbe0172ec094724bfccc
1 /*
2  * linux/arch/arm/lib/memzero.S
3  *
4  * Copyright (C) 1995-2000 Russell King
5  */
6 #include <linux/linkage.h>
7 #include <asm/assembler.h>
9         .text
10         .align  5
11         .word   0
13  * Align the pointer in r0.  r3 contains the number of bytes that we are
14  * mis-aligned by, and r1 is the number of bytes.  If r1 < 4, then we
15  * don't bother; we use byte stores instead.
16  */
17 1:      subs    r1, r1, #4              @ 1 do we have enough
18         blt     5f                      @ 1 bytes to align with?
19         cmp     r3, #2                  @ 1
20         strltb  r2, [r0], #1            @ 1
21         strleb  r2, [r0], #1            @ 1
22         strb    r2, [r0], #1            @ 1
23         add     r1, r1, r3              @ 1 (r1 = r1 - (4 - r3))
25  * The pointer is now aligned and the length is adjusted.  Try doing the
26  * memzero again.
27  */
29 ENTRY(__memzero)
30         mov     r2, #0                  @ 1
31         ands    r3, r0, #3              @ 1 unaligned?
32         bne     1b                      @ 1
34  * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
35  */
36         cmp     r1, #16                 @ 1 we can skip this chunk if we
37         blt     4f                      @ 1 have < 16 bytes
39  * We need an extra register for this loop - save the return address and
40  * use the LR
41  */
42         str     lr, [sp, #-4]!          @ 1
43         mov     ip, r2                  @ 1
44         mov     lr, r2                  @ 1
46 3:      subs    r1, r1, #64             @ 1 write 32 bytes out per loop
47         stmgeia r0!, {r2, r3, ip, lr}   @ 4
48         stmgeia r0!, {r2, r3, ip, lr}   @ 4
49         stmgeia r0!, {r2, r3, ip, lr}   @ 4
50         stmgeia r0!, {r2, r3, ip, lr}   @ 4
51         bgt     3b                      @ 1
52         LOADREGS(eqfd, sp!, {pc})       @ 1/2 quick exit
54  * No need to correct the count; we're only testing bits from now on
55  */
56         tst     r1, #32                 @ 1
57         stmneia r0!, {r2, r3, ip, lr}   @ 4
58         stmneia r0!, {r2, r3, ip, lr}   @ 4
59         tst     r1, #16                 @ 1 16 bytes or more?
60         stmneia r0!, {r2, r3, ip, lr}   @ 4
61         ldr     lr, [sp], #4            @ 1
63 4:      tst     r1, #8                  @ 1 8 bytes or more?
64         stmneia r0!, {r2, r3}           @ 2
65         tst     r1, #4                  @ 1 4 bytes or more?
66         strne   r2, [r0], #4            @ 1
68  * When we get here, we've got less than 4 bytes to zero.  We
69  * may have an unaligned pointer as well.
70  */
71 5:      tst     r1, #2                  @ 1 2 bytes or more?
72         strneb  r2, [r0], #1            @ 1
73         strneb  r2, [r0], #1            @ 1
74         tst     r1, #1                  @ 1 a byte left over
75         strneb  r2, [r0], #1            @ 1
76         RETINSTR(mov,pc,lr)             @ 1